我正在编写一个概念验证应用程序,旨在以每秒约1000条消息的速度获取实时点击流数据,并将其写入Amazon Redshift。
我正在努力获得其他人声称的表现(例如,here)。
我正在运行一个包含2个dw.hs1.xlarge节点(+ leader)的集群,正在执行加载的计算机是与运行64位Ubuntu 12.04的Redshift集群在同一VPC上的EC2 m1.xlarge实例0.1。
我正在使用Java 1.7(来自Ubuntu repos的openjdk-7-jdk)和Postgresql 9.2-1002驱动程序(主要是因为它是Maven Central中唯一一个使我的构建更容易!)。
我已经尝试了here所示的所有技术,除了最后一种。
某些人我不能使用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
我做错了什么?我可以采取哪些其他方法?
答案 0 :(得分:17)
Redshift(又名ParAccel)是一个分析数据库。目标是使分析查询能够在非常大量的数据上快速得到解答。为此,Redshift以列式格式存储数据。每列单独保存,并根据列中的先前值进行压缩。这种压缩往往非常有效,因为给定的列通常包含许多重复和类似的数据。
此存储方法在查询时提供了许多好处,因为只需要读取请求的列并且要读取的数据被非常压缩。然而,这样做的成本是插入件往往更慢并且需要更多的努力。此外,未完全排序的插入可能导致查询性能较差,直到表为VACUUM。
因此,通过一次插入一行,您完全违背了Redshift的工作方式。数据库必须连续将数据附加到每个列并计算压缩。它有点(但不完全)就像为大量的zip存档添加单个值。此外,即使在插入数据后,在运行VACUUM重新组织表之前,仍然无法获得最佳性能。
如果您想“实时”分析数据,那么出于所有实际目的,您应该选择其他数据库和/或方法。我的头顶是3:
答案 1 :(得分:3)
我们已经能够在Redshift中插入1000行/秒,在同一个INSERT语句中将几个请求一起批处理(在我们的例子中,我们必须在每个INSERT中批量处理~200个值元组)。如果您使用像Hibernate这样的ORM层,可以将其配置为批处理(例如,参见http://docs.jboss.org/hibernate/orm/3.3/reference/en/html/batch.html)
答案 2 :(得分:1)
单个插入缓慢的原因是Redshift处理提交的方式。 Redshift有一个提交队列。
假设您插入第1行,然后提交 - 它将转到红色提交队列以完成提交。
下一行,第2行,然后提交 - 再次进入提交队列。假设在此期间,如果第1行的提交未完成,则第2行将等待提交1完成,然后开始在第2行提交时工作。
因此,如果批量插入,它只执行一次提交,并且比Redshift系统的单次提交更快。
您可以通过以下链接中的问题#8获取提交队列信息。 https://aws.amazon.com/blogs/big-data/top-10-performance-tuning-techniques-for-amazon-redshift/
答案 3 :(得分:0)
我通过批量写入每笔交易75,000条记录的交易,每秒能够达到2,400次插入。正如您所料,每条记录都很小,每条记录只有大约300字节。
我查询安装在EC2实例上的MariaDB,并将记录从安装了Maria的同一EC2实例插入RedShift。
<强>更新强>
我修改了写入的方式,以便在5个并行线程中从MariaDB加载数据,并从每个线程写入RedShift。这使得性能提高到12,000+次/秒。
所以,是的,如果你正确地计划,你可以从RedShift写得很好。