AWS红移JDBC插入性能

AWS红移JDBC插入性能,jdbc,amazon-redshift,Jdbc,Amazon Redshift,我正在编写一个概念验证应用程序,旨在以每秒1000条左右的速度获取实时点击流数据,并将其写入Amazon Redshift 我正在努力获得其他人声称的性能(例如) 我正在运行一个带有2个dw.hs1.xlarge节点(+leader)的集群,执行加载的机器是一个EC2 m1.xlarge实例,与运行64位Ubuntu 12.04.1的红移集群位于同一VPC上 我正在使用Java1.7(来自Ubuntu repos的openjdk-7-jdk)和Postgresql 9.2-1002驱动程序(主要

我正在编写一个概念验证应用程序,旨在以每秒1000条左右的速度获取实时点击流数据,并将其写入Amazon Redshift

我正在努力获得其他人声称的性能(例如)

我正在运行一个带有2个dw.hs1.xlarge节点(+leader)的集群,执行加载的机器是一个EC2 m1.xlarge实例,与运行64位Ubuntu 12.04.1的红移集群位于同一VPC上

我正在使用Java1.7(来自Ubuntu repos的openjdk-7-jdk)和Postgresql 9.2-1002驱动程序(主要是因为它是Maven Central中唯一一个使我的构建更容易的驱动程序!)

我已经尝试了所有展示的技巧,除了最后一个

我不能使用
COPY FROM
,因为我们想“实时”加载数据,所以通过S3或DynamoDB暂存数据实际上不是一个选项,而且出于某种原因,Redshift不支持
COPY FROM stdin

下面是我日志中的一段摘录,其中显示了以大约15/秒的速度插入单个行:

2013-05-10 15:05:06,937 [pool-1-thread-2] INFO  uk.co...redshift.DatabaseWriter - Beginning batch of 170
2013-05-10 15:05:18,707 [pool-1-thread-2] INFO  uk.co...redshift.DatabaseWriter - Done
2013-05-10 15:05:18,708 [pool-1-thread-2] INFO  uk.co...redshift.DatabaseWriter - Beginning batch of 712
2013-05-10 15:06:03,078 [pool-1-thread-2] INFO  uk.co...redshift.DatabaseWriter - Done
2013-05-10 15:06:03,078 [pool-1-thread-2] INFO  uk.co...redshift.DatabaseWriter - Beginning batch of 167
2013-05-10 15:06:14,381 [pool-1-thread-2] INFO  uk.co...redshift.DatabaseWriter - Done
我做错了什么?我还可以采取什么其他方法?

Redshift(又名ParAccel)是一个分析数据库。目标是使分析查询能够在非常大的数据量上快速得到回答。为此,红移以列格式存储数据。每列单独保存,并根据列中以前的值进行压缩。这种压缩往往非常有效,因为给定的列通常包含许多重复和相似的数据

这种存储方法在查询时提供了许多好处,因为只需要读取请求的列,并且要读取的数据非常压缩。然而,这样做的代价是插入速度较慢,需要付出更多的努力。此外,在表被清空之前,顺序不完美的插入可能会导致查询性能差

因此,通过一次插入一行,您完全违背了红移的工作方式。数据库必须将您的数据连续附加到每一列并计算压缩。这有点像(但不完全像)向大量zip归档文件添加单个值。此外,即使在插入数据之后,在运行真空重新组织表之前,仍然无法获得最佳性能

如果您想“实时”分析数据,那么出于所有实际目的,您可能应该选择另一个数据库和/或方法。在我的脑海里有三个:

  • 接受“小”配料窗口(5-15分钟),并计划至少每天进行真空操作
  • 选择一个分析数据库(更多美元),它可以处理小的插入,例如Vertica
  • 使用允许单路径分析的“NoSQL”数据库进行实验,例如Acunu Cassandra

  • 通过在同一个insert语句中批处理多个请求,我们能够以每秒1000行的红移速度插入数据(在本例中,我们必须在每次插入中批处理约200个值元组)。如果您使用像Hibernate这样的ORM层,您可以将其配置为批处理(例如参见)

    通过对每个事务75000条记录的事务进行批处理,我已经能够实现每秒2400次插入。正如您可能期望的那样,每个记录都很小,每个记录只有大约300字节

    我正在查询安装在EC2实例上的MariaDB,并将记录插入安装Maria的同一EC2实例的红移中

    更新

    我修改了写操作的方式,以便它在5个并行线程中加载MariaDB中的数据,并从每个线程写入RedShift。这将性能提高到每秒12000多次写入


    是的,如果你计划得当,你可以从红移写入中获得很好的性能。

    单次插入速度慢的原因是红移处理提交的方式。红移有一个提交队列

    假设插入第1行,然后提交—它将转到红移提交队列以完成提交

    下一行,第2行,然后提交-再次转到提交队列。假设在此期间,如果第1行的提交未完成,第2行将等待第1行的提交完成,然后开始第2行的提交

    因此,如果批处理插入,它只执行一次提交,并且比向红移系统提交一次要快

    您可以通过问题提示#9:在下面的链接中维护有效的数据加载来获取提交队列信息。

    谢谢您的回复。我理解你的所有观点,但它并没有真正解释为什么10000 x单行插入要比从S3批量加载单个10000行CSV慢得多-我的意思是,压缩分析等仍然需要完成。记住,我这里说的不是10000笔交易。即使是一个包含10000个插入的单事务也运行缓慢,在这种情况下,红移应该能够最大限度地减少块写入。除此之外,我们这里也不讨论10%的差异!我们谈论的是15行/秒,而我随后在S3批量加载中实现了100000行/秒!不幸的是,这就是这只野兽的本性。我不会假设在一个事务中包装的10k个插入是批量处理的,特别是如果你说这没有什么好处的话。我怀疑红移要么是批量的,要么是逐行的。将10k写入CSV,然后批量加载以查看差异。正如我所提到的,从S3加载时,我看到了高达100k行/秒的速度。我只是觉得很难相信有这么大的差别。我的意思是-如果你说我可以从CSV/S3以每秒10万行的速度运行,但通过SQL INSERT语句只能以每秒20万行的速度运行,我会对这种差异感到震惊。但是10万对15根本没有任何逻辑意义!顺便说一句,自从我回答这个问题以来,我一直在研究SAP的HANA One数据库,它实际上可能更适合您的场景。它在AWS市场上以每小时1美元的价格提供,超过实例成本。有很多东西