首页 文章

将数据(递增地)加载到Amazon Redshift,S3与DynamoDB和Insert中

提问于
浏览
25

我有一个网络应用程序,需要发送其使用情况的报告,我想使用Amazon RedShift作为数据仓库,我应该如何收集数据?

每次,用户与我的应用程序交互,我想报告..所以我什么时候应该将文件写入S3?多少钱?我的意思是: - 如果不立即发送信息,那么我可能会因连接丢失而失去它,或者我的系统中的一些错误被收集并准备好发送到S3 ... - 如果我在每次用户交互时都将文件写入S3,我最终会得到数百个文件(每个文件都有最少的数据),需要在复制到RedShift后进行管理,排序,删除..这似乎不太像一个好的解决方案

我错过了什么?我应该使用DynamoDB,我应该使用简单的插入到Redshift中吗?
如果我确实需要将数据写入DynamoDB,我应该在复制后删除保留表 . 最佳做法是什么?

在任何情况下,哪些是避免RedShift中数据重复的最佳实践?

感谢帮助!

5 回答

  • 2

    虽然这里已经有一个公认的答案,但AWS推出了一项名为Kinesis Firehose的新服务,它根据用户定义的时间间隔处理聚合,临时上传到s3,上传(SAVE)到红移,重试和错误处理,吞吐量管理等 . ..

    这可能是最简单,最可靠的方法 .

  • 2

    在将它们摄入Amazon Redshift之前,首选 aggregate 事件日志 .

    好处是:

    • 您将更好地使用Redshift的 parallel 性质;对于S3中的一组较大文件(或来自大型DynamoDB表),COPY将比单个INSERT或小文件的COPY快 much .

    • 在将数据加载到Redshift之前,您可以 pre-sort 您的数据(特别是如果排序基于事件时间) . 这也可以提高您的负载性能并减少对表的需求 .

    您可以在聚合并将其加载到Redshift之前在多个位置累积您的事件:

    • Local file to S3 - 最常见的方法是在客户端/服务器上聚合日志,每x MB或y分钟将它们上传到S3 . 有许多日志追加器支持此功能,您无需在代码中进行任何修改(例如,FluentDLog4J) . 这可以仅使用容器配置来完成 . 缺点是您可能会丢失一些日志,并且可以在上载之前删除这些本地日志文件 .

    • DynamoDB - 正如@Swami所描述的,DynamoDB是积累事件的一种非常好的方法 .

    • Amazon Kinesis - 最近发布的服务也是以各种快速可靠的方式将您的活动从各种客户端和服务器流式传输到中心位置的好方法 . 事件按插入顺序排列,这样可以在以后预先排序到Redshift时轻松加载它 . 事件存储在Kinesis中24小时,您可以安排从kinesis读取并每小时加载到Redshift,以获得更好的性能 .

    请注意,所有这些服务(S3,SQS,DynamoDB和Kinesis)允许您从最终用户/设备进行 push the events directly ,而无需通过中间Web服务器 . 这可以显着提高服务的高可用性(如何处理增加的负载或服务器故障)和系统成本(您只需支付使用的费用,而不需要仅为日志使用未充分利用的服务器) .

    例如,请参阅如何在此处获取移动设备的临时安全令牌:http://aws.amazon.com/articles/4611615499399490

    允许与这些服务直接交互的另一组重要工具是各种SDK . 例如Java.NETJavaScriptiOSAndroid .

    关于 de-duplication 要求;在上面的大多数选项中,您可以在聚合阶段执行此操作,例如,当您从Kinesis流中读取时,您可以检查事件中是否没有重复,但在放入之前分析大量事件缓冲区进入数据存储区 .

    但是,您也可以在Redshift中进行此检查 . 一个好的做法是将数据 COPY 数据转换为临时表,然后SELECT INTO一个组织良好的排序表 .

    您可以实现的另一个最佳实践是每日(或每周)表分区 . 即使您想要一个大的长事件表,但大多数查询都在一天(例如最后一天)运行,您可以创建一组具有类似结构的表(events_01012014,events_01022014,events_01032014 ...) . 然后你可以 SELECT INTO ... WHERE date = ... 到每个表 . 如果要查询多天的数据,可以使用UNION_ALL .

  • 44

    只是在这里有点自私,并准确描述了事件分析平台Snowplow的作用 . 他们使用这种非常独特的方式从客户端收集事件日志并将其聚合在一起S3 .

    他们使用Cloudfront进行此操作 . 您可以做的是,在其中一个S3存储桶中托管一个像素,并将该存储桶放在CloudFront分配后面作为原点 . 为同一个CloudFront启用日志到S3存储桶 .

    每当您在客户端上调用该像素时,您都可以将日志作为网址参数发送(类似于Google Analytics) . 然后可以使用“复制”丰富这些日志并将其添加到Redshift数据库 .

    这解决了日志聚合的目的 . 此设置将为您处理所有这些 .

    您还可以查看Piwik这是一个开源分析服务,看看您是否可以根据需要对其进行修改 .

  • 6

    要考虑的一个选项是在DynamoDB中创建时间序列表,您可以在DynamoDB中每天或每周创建一个表来编写每个用户交互 . 在时间段结束时(天,小时或周),您可以将日志复制到Redshift .

    有关更多详细信息,请在DynamoDB时间序列表中查看此模式:http://docs.aws.amazon.com/amazondynamodb/latest/developerguide/GuidelinesForTables.html#GuidelinesForTables.TimeSeriesDataAccessPatterns

    和这个博客:

    http://aws.typepad.com/aws/2012/09/optimizing-provisioned-throughput-in-amazon-dynamodb.html

    对于Redshift DynamoDB副本:http://docs.aws.amazon.com/amazondynamodb/latest/developerguide/RedshiftforDynamoDB.html

    希望这可以帮助 .

  • 1

    您可以将数据写入本地磁盘上的CSV文件,然后运行Python / boto / psycopg2脚本以将数据加载到Amazon Redshift .

    在我的CSV_Loader_For_Redshift中,我这样做:

    • 使用boto Python模块和分段上传将数据压缩并加载到S3 .
    conn = boto.connect_s3(AWS_ACCESS_KEY_ID,AWS_SECRET_ACCESS_KEY)
    bucket = conn.get_bucket(bucket_name)
    k = Key(bucket)
    k.key = s3_key_name
    k.set_contents_from_file(file_handle, cb=progress, num_cb=20, 
    reduced_redundancy=use_rr )
    
    • 使用psycopg2 COPY命令将数据附加到Redshift表 .
    sql="""
    copy %s from '%s' 
    CREDENTIALS 'aws_access_key_id=%s;aws_secret_access_key=%s' 
    DELIMITER '%s' 
    FORMAT CSV %s 
    %s 
    %s 
    %s;""" % (opt.to_table, fn, AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY,opt.delim,quote,gzip, timeformat, ignoreheader)
    

相关问题