将数据(增量)加载到Amazon Redshift,S3 vs DynamoDB vs Insert

25
我有一个Web应用程序需要发送其使用情况的报告,我想将Amazon RedShift用作数据仓库,该如何收集数据?
每次用户与我的应用程序交互时,我都想要进行报告。那么我应该在何时将文件写入S3?应该写多少个文件? 我的意思是: - 如果不立即发送信息,则可能会因为连接中断或收集并准备好发送到S3时系统中出现某些错误而失去它。 - 如果我在每个用户交互时都将文件写入S3,我最终将拥有数百个文件(每个文件的数据很少),需要管理、排序、复制到RedShift后删除...这似乎不是一个好的解决方案。
我错过了什么?我应该改用DynamoDB吗?我应该使用简单的向Redshift插入语句!? 如果确实需要将数据写入DynamoDB,那么应该在复制后删除保留表格..哪些是最佳实践?
无论哪种情况,如何避免在RedShift中发生数据重复?感谢您的帮助!

http://stackoverflow.com/questions/38300416/how-to-load-files-from-zip-files-present-in-s3-to-redshift-using-copy-command - AWSDeveloper
5个回答

44

在将事件日志导入Amazon Redshift之前,最好进行聚合

好处是:

  • 您将更好地利用Redshift的并行性; 在S3中的一组较大文件上执行COPY(或从大型DynamoDB表中)将比单个小文件的INSERT或COPY快得多

  • 您可以在加载到Redshift之前预排序数据(特别是如果基于事件时间进行排序)。这也会提高您的加载性能,并减少对表的VACUUM的需求。

您可以在将事件加载到Redshift之前在多个位置累积它们并进行聚合:

  • 本地文件到S3 - 最常见的方法是在客户端/服务器上汇总日志,并每隔x MB或y分钟将其上传到S3。有许多支持此功能的日志附加程序,您不需要对代码进行任何修改(例如FluentDLog4J)。这只需进行容器配置即可完成。缺点是您有丢失一些日志的风险,而这些本地日志文件可能会在上传之前被删除。

  • DynamoDB - 如@Swami所述,DynamoDB是累积事件的非常好的方法。

  • Amazon Kinesis - 最近发布的服务也是从各个客户端和服务器流式传输事件到中央位置的快速可靠的好方法。事件按插入顺序排列,这使得稍后将其预先排序到Redshift中变得容易。事件在Kinesis中存储24小时,您可以计划每小时从kinesis读取并加载到Redshift中以获得更好的性能。

  • 请注意,所有这些服务(S3、SQS、DynamoDB和Kinesis)都允许您直接从最终用户/设备推送事件,无需通过中间Web服务器。这可以显着提高您的服务高可用性(如何处理负载增加或服务器故障)和系统成本(您只支付所使用的部分,无需为日志而拥有未利用的服务器)。

    例如,您可以在此处了解有关移动设备的临时安全令牌的详细信息:http://aws.amazon.com/articles/4611615499399490

    另一个与这些服务直接交互的重要工具集是各种SDK。例如,Java.NETJavaScriptiOSAndroid

    关于去重的要求;在上述大多数选项中,您可以在聚合阶段执行此操作。例如,在从Kinesis流读取时,您可以检查事件是否有重复,并在将其放入数据存储之前分析大型事件缓冲区。

    不过,您也可以在Redshift中进行此项检查。一种好的做法是将数据复制到临时表中,然后SELECT INTO一个组织良好且排序良好的表中。

    另一个最佳实践是每日(或每周)对表进行分区。即使您想要一个大型的长事件表,但大多数查询仅在单个日期(例如最后一天)运行,您也可以创建一组具有类似结构的表(events_01012014、events_01022014、events_01032014...)。 然后,您可以针对每个表使用SELECT INTO ... WHERE date = ...。当您想要从多个日期查询数据时,可以使用UNION_ALL


    谢谢你,Guy。你的回答非常详细,我想我会利用 S3 来解决我的数据聚合问题。但有一件事我不太确定是否理解正确,为什么你说我不需要经过中间 Web 服务器? - Ofer Velich
    您可以直接上传对象至 S3。请参考此处:http://docs.aws.amazon.com/AmazonS3/latest/dev/PresignedUrlUploadObject.html - Guy
    1
    Kinesis 连接器库及相关属性文件:https://github.com/awslabs/amazon-kinesis-connectors/blob/master/src/main/samples/redshiftbasic/RedshiftBasicSample.properties - Guy
    1
    是否可以使用AWS Lambda来复制数据从S3 -> Redshift,而不是使用Java连接器库?我没有看到任何关于使用Lambda将数据从S3复制到Redshift的文档。 - Kevin Meredith
    我在Redshift中是否仍需要创建分区表?Redshift应该能够更好地处理大型表,对吗? - DBS
    显示剩余7条评论

    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 希望这能帮到您。

    2
    你可以将数据写入本地磁盘上的CSV文件,然后运行Python / boto / psycopg2脚本将数据加载到Amazon Redshift中。
    在我的 CSV_Loader_For_Redshift中,我就是这样做的:
    1. Compress and load data to S3 using boto Python module and multipart upload.

      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 )
      
    2. Use psycopg2 COPY command to append data to Redshift table.

      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)
      

    2
    尽管这里已经有一个被接受的答案,但AWS推出了一个名为Kinesis Firehose的新服务,它根据用户定义的间隔处理聚合、暂时上传到s3和上传(保存)到redshift、重试和错误处理、吞吐量管理等等...... 这可能是最简单和最可靠的方法。

    1

    我这里有点自私,想详细描述一下事件分析平台Snowplow的功能。他们使用了一种独特的方式从客户端收集事件日志并在S3上进行聚合。

    他们使用Cloudfront来实现这一点。您可以在其中一个S3存储桶中托管像素,并将该存储桶放置在CloudFront分发后面作为源。为同一CloudFront启用对S3存储桶的日志记录。

    每当您在客户端调用该像素时,可以将日志作为URL参数发送。这些日志可以使用Copy添加到Redshift数据库中进行增强处理。

    这解决了日志聚合的目的。这个设置会为您处理所有这些问题。

    您还可以查看Piwik,这是一个开源的分析服务,并查看是否可以根据您的需求进行修改。


    网页内容由stack overflow 提供, 点击上面的
    可以查看英文原文,
    原文链接