【问题标题】:Amazon redshift: bulk insert vs COPYing from s3Amazon redshift:从 s3 批量插入与复制
【发布时间】:2014-10-16 17:57:21
【问题描述】:

我有一个用于某些分析应用程序的 redshift 集群。我有想要添加到clicks 表的传入数据。假设我每秒要存储约 10 次新的“点击”。如果可能的话,我希望我的数据尽快在 redshift 中可用。

据我了解,由于是列式存储,插入性能不好,所以必须分批插入。我的工作流程是将点击存储在 redis 中,每分钟,我将大约 600 次点击从 redis 插入到 redshift。

我有两种方法可以在 redshift 中插入一批点击:

我已经做了一些测试(这是在一个已经有 200 万行的 clicks 表上完成的):

             | multi-row insert stragegy |       S3 Copy strategy    |
             |---------------------------+---------------------------+
             |       insert query        | upload to s3 | COPY query |
-------------+---------------------------+--------------+------------+
1 record     |           0.25s           |     0.20s    |   0.50s    |
1k records   |           0.30s           |     0.20s    |   0.50s    |
10k records  |           1.90s           |     1.29s    |   0.70s    |
100k records |           9.10s           |     7.70s    |   1.50s    |

如您所见,在性能方面,首先复制 s3 中的数据似乎没有任何收获。 upload + copy 时间等于insert 时间。

问题:

每种方法的优缺点是什么?最佳做法是什么?我错过了什么吗?

还有一个问题:是否可以通过清单自动从 s3 中红移到 COPY 数据?我的意思是只要将新的.csv 文件添加到 s3 中就复制数据?文档herehere。还是我必须自己创建一个后台工作人员来触发 COPY 命令?

我的快速分析:

In the documentation about consistency,没有提到通过多行插入加载数据。看起来首选方式是来自 s3 的 COPYing 具有唯一对象键(s3 上的每个 .csv 都有自己唯一的名称)...

  • S3 Copy strategy:
    • 优点:看起来像是文档中的良好做法。
    • 缺点:更多工作(我必须管理存储桶和清单以及触发 COPY 命令的 cron...)
  • Multi-row insert strategy
    • 优点:工作量少。我可以从我的应用程序代码中调用 insert 查询
    • 缺点:看起来不像是导入数据的标准方式。我错过了什么吗?

【问题讨论】:

  • 如何确保没有将同一记录复制到 s3 两次?换句话说,您是否每分钟将整个点击桶上传到 S3?我很好奇你是如何避免重复的
  • @KevinMeredith 我认为首选的方法是使用临时表。 Documentation for creating the staging table, Documentation for upserting
  • 注意:AWS 有一项名为 Redshift Spectrum 的服务,可让您直接从 Redshift 查询 s3 数据。请参阅this post 了解更多信息。推荐的格式是将 s3 文件存储为 parquet,但 CSV 也可以。

标签: amazon-s3 amazon-redshift


【解决方案1】:

Redshift 是一个分析型数据库,经过优化,您可以查询数百万条记录。它还经过优化,允许您使用 COPY 命令将这些记录非常快速地提取到 Redshift 中。

COPY 命令的设计是将多个文件并行加载到集群的多个节点中。例如,如果您有 5 个小节点 (dw2.xl) 集群,如果您的数据是多个文件(例如 20 个),则复制数据的速度可以提高 10 倍。文件数量和每个文件中的记录数量之间存在平衡,因为每个文件都有一些小的开销。

这应该会引导您在 COPY 的频率(例如每 5 或 15 分钟而不是每 30 秒)与事件文件的大小和数量之间取得平衡。

要考虑的另一点是您拥有的 2 种 Redshift 节点,SSD 节点(dw2.xl 和 dw2.8xl)和磁性节点(dx1.xl 和 dw1.8xl)。 SSD 在摄取方面也更快。由于您正在寻找非常新鲜的数据,您可能更喜欢使用 SSD 运行,对于少于 500GB 的压缩数据,通常成本较低。如果随着时间的推移,你有超过 500GB 的压缩数据,你可以考虑运行 2 个不同的集群,一个用于 SSD 上的“热”数据和上周或一个月的数据,一个用于磁盘上的“冷”数据,所有你的历史数据。

最后,您实际上并不需要将数据上传到 S3,这是您摄取时间的主要部分。您可以使用 SSH COPY 选项直接从服务器复制数据。在此处查看更多信息:http://docs.aws.amazon.com/redshift/latest/dg/loading-data-from-remote-hosts.html

如果您能够将您的 Redis 队列拆分到多个服务器或至少多个具有不同日志文件的队列,您可能会获得非常好的每秒记录摄取速度。

您可能要考虑允许近乎实时分析的另一种模式是使用流服务 Amazon Kinesis。它允许在几秒钟内对数据进行分析,同时准备数据以更优化的方式复制到 Redshift。

【讨论】:

    【解决方案2】:

    在数据负载较大的情况下,S3 副本的工作速度更快。当您说需要将数千条记录加载到 redshift 时,s3 上传 + 复制将比插入查询更快。

    S3 副本在并行模式下工作。

    当您创建表并进行插入时,批量大小会受到限制。单个 SQL 的最大大小为 16 MB。所以你需要注意 SQL Batch 的大小(取决于每个插入查询的大小)

    S3 副本会自动为您的表应用编码(压缩)。当您创建表并使用复制进行样本加载时,您可以看到自动应用了压缩。

    但是,如果您使用插入命令开始,您会注意到没有应用压缩,这将导致 redshift 中的表空间更多,并且在某些情况下查询处理时间变慢。

    如果您希望使用插入命令,则创建表时每列都应用了编码以节省空间并加快响应时间。

    【讨论】:

    • 你确定inserted 的行没有被压缩吗?我在哪里可以在文档中找到这个?这可以用VACUUM 和/或ANALYSE 解决吗?
    • 当我们创建了一个没有任何编码类型的空表并且我们使用 insert 语句插入它时,则不应用压缩。要测试每个列的编码,请在命令下方触发。 select "column", type, encoding from pg_table_def where tablename = 'mutable' .....尝试创建新的空表并使用复制命令加载数据并触发上述查询,您会看到不同
    • @ 确保要测试这两种情况,您创建空表并在一个表中使用副本加载数据并在另一个表中插入。确保您加载 10k 条记录,同时查看表大小的差异。参考这个以查看表格检查器脚本docs.aws.amazon.com/redshift/latest/dg/…
    【解决方案3】:

    在向 Redshift 执行批量上传时,可能值得实施微批处理。这篇文章可能值得一读,因为它还包含为更好地执行 COPY 命令而需要遵循的其他技术。

    http://blogs.aws.amazon.com/bigdata/post/Tx2ANLN1PGELDJU/Best-Practices-for-Micro-Batch-Loading-on-Amazon-Redshift

    【讨论】:

      【解决方案4】:

      我的测试结果有点不同。我正在从 OS Windows 桌面将 CSV 文件加载到 Redshift。

      • 行插入最慢。
      • 多行插入比行插入快 5 倍。
      • S3+COPY 比多行插入快 3 倍。

      是什么促成了更快的批量 S3+COPY 插入。

      • 您不必从 CSV 行解析插入语句。
      • 流在分段上传到 S3 之前被压缩。
      • COPY 命令非常快。

      我将所有发现都编译到了一个 Python 脚本中 CSV_Loader_For_Redshift

      【讨论】:

      • 帖子包含的结果太浅(查询大小依赖?趋势?)
      • @ivan_pozdeev 与它的趋势有什么关系?
      • 趋势是指比较时间如何随不同输入大小而变化
      • @ivan_pozdeev 说得通。
      • 嗨,@AlexB 指向 CSV_Loader_For_Redshift 的 python 脚本链接已损坏
      【解决方案5】:

      我的意思是只要将新的 .csv 文件添加到 s3 中就复制数据?

      是的,可以为此使用 AWS Lambda,当您上传新文件时可以触发

      【讨论】:

        猜你喜欢
        • 2018-09-12
        • 1970-01-01
        • 2021-08-16
        • 2013-05-07
        • 1970-01-01
        • 2013-07-16
        • 1970-01-01
        • 1970-01-01
        • 2016-12-28
        相关资源
        最近更新 更多