在Cassandra中优化写入性能

5
我们有一个典型的场景:
1个列族,不到10个简单的列。
当我们从客户端收到请求时,我们需要将这个列族的1000万个记录写入数据库,并且我们分批(每批1000个)地进行写入。这通常需要5-10分钟,具体取决于簇中节点的数量和复制因子。
开始写入后的几个小时内,我们会收到大量的更新(每个记录会更新两次)。
所以,在一天中的某个时间段内(一个小时内),我们有很多写入/更新操作,之后就很少了。
问题是:采取什么措施来提高写入/更新性能。例如,我已经注意到了memtable_flush_queue_size等配置字段,但是我对cassandra的经验不足,不知道具体该做什么。
任何建议都有帮助,
伊万

为什么你又担心写性能了?如果在“大量更新”的时候,你已经完成了原始输入的写入,那就没关系了。 - Ajeet Ganga
4个回答

12
  1. 增加JVM内存(在Java 6+上最大为12GB)- 这将自动增加memtables的大小并减少刷新间隔。这也意味着,频繁的更新将在RAM中合并而不是在压缩期间 - 这也将减少磁盘使用量。像往常一样,缺点是Cassandra将需要更多时间启动,因为提交日志会变得更大(当memtable刷新到SSTable时会被删除)。
  2. 非常重要:为数据和提交日志使用单独的磁盘。您可以使用SSD来存储数据,但对于提交日志没有意义,因为它是顺序写入。
  3. 将副本因子更改为1将在集群中生成较少的负载,因为每个节点将需要处理其数据,而不必处理额外的副本,但可能会丢失数据 - 我不建议这样做。

这些链接可能有助于更好地理解:

http://maciej-miklas.blogspot.de/2012/09/cassanrda-tuning-for-frequent-column.html

http://maciej-miklas.blogspot.de/2012/08/cassandra-11-reading-and-writing-from.html


1
除了Maciej提到的好处外,我想在更高的层面上补充一点,即使用批处理来批量加载普通写入是一种反模式。它的主要影响是使你的工作负载更加“突发”,这是不好的。只有在需要一致性的情况下才使用批处理。
对于批量加载,请考虑在源头进行批处理并使用sstableloader,但我不建议在约100M行级别之前投资这种努力。

“Bursty”是什么意思?您能否解释一下为什么这是反模式?逐个写入比批量写入更快,还是有其他后果?我们目前并没有全部的1000万行数据,它们实际上是以1000行为一批从客户端和我们之间的层中传输过来的(为了简单起见,我忽略了这一层)。 - Ivan Longin

0

您是否确实需要进行批处理?更新是否依赖于之前的行状态?如果不是,那我建议不要使用批处理,因为批处理请求会发往一个节点,而协调节点则需要根据它们的分区键将请求发送到其他节点,这会增加协调节点的工作量。仅当您知道所有批次都只有一个分区键时,批处理才有用。现在,如果您将每个请求分开,则负载也会分布更均匀,并且写入吞吐量也会增加。如果您想更详细了解批处理,请查看下面的链接: https://lostechies.com/ryansvihla/2014/08/28/cassandra-batch-loading-without-the-batch-keyword/


0

Cassandra是一种日志结构化数据库。因此,无论是更新还是新写入,它的行为都是相同的。如果一致性不是非常关键,您可以选择写入一致性级别为1。这应该会有所帮助。另外,请问您使用的是CQL还是thrift客户端?如果您使用的是thrift,则它是同步的,这意味着每个客户端线程将在一个请求上被阻塞。请使用更多的客户端线程。


写操作总是发送到所有副本,因此CL对写吞吐量几乎没有影响 - 只影响可用性/一致性。 - jbellis
我想强调的是,CL 协议只需要等待一个响应,即使它必须向所有副本发送请求。因此,客户端不必长时间阻塞。 - APKar

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