并发写入cassandra副本 - 重复是否可能?

时间:2013-08-12 22:07:45

标签: cassandra replication

我有一个运行Cassandra 1.2.6的两个机器集群。我正在使用复制因子为2的密钥空间。但我的应用程序要求我并行写入两个副本,并让Cassandra进行复制,并希望Cassandra不复制副本节点上的键/值。

例如:

  • 我有节点Node1和Node2。我有一个键空间,其上配置了复制因子2,以及一个用于推送键/值对的列族
  • 我使用python客户端(pycassa)写入集群。
  • 密钥“KeyX”,散列到Node1和Node2。 (我通过node tool命令找出哪些服务器的哪些键哈希。(`$ nodetool getendpoints KeyspaceName ColumnFamilyName KeyHexString`)
  • 我使用客户端同时向节点Node1和Node2写入(KeyX,Value)。 (在连接池中,我只提供特定的服务器名称)
  • 写作时,我等待一次写入成功(对主人)。 (一致性等级ONE)
  • 现在,我通过`$ nodetool status`命令监视集群使用的磁盘空间量。
  • 我写了大约100个密钥,每个密钥有2MB的值。

理想情况下,这应该在磁盘上存储大约400MB,并且存储密钥的一些开销与我使用的值大小相比应该是边缘的。

观察:

  • 如果我不写入密钥哈希的所有节点,Cassandra会在内部处理复制,数据大小约为400MB。 (每个节点200MB,100个密钥,2MB值)
  • 如果我写密钥哈希的所有节点,Cassandra正在写入超过预期数量的数据到磁盘。它高达15%。在我们的测试中,Cassandra写了~460MB而不是400MB。

我的问题是,预期的行为(15%的开销)是什么?是否有任何我们需要调整的配置,以便Cassandra正确处理对所有副本的并发写入。

谢谢!

1 个答案:

答案 0 :(得分:2)

我能想到的15%额外空间有两种可能的原因。

一个是因为有时副本会临时存储一列的两个副本。如果你在Cassandra中稍微不同的时间两次写一个列,那么这两个副本可能会进入单独的memtables,因此最终会在磁盘上的单独SSTable中。稍后,当SSTables通过压缩过程合并时,旧的值将被丢弃,从而释放空间。在您的测试中,您可以运行nodetool compact来强制压缩,并查看空间使用情况是否下降。

另一个可能的原因取决于您没有写入两个节点时的测试方式。如果您在一致性级别ONE执行此操作,则有可能某些写入被另一个副本删除,因此它还没有所有键。您可以通过运行nodetool repair来确定它。因此,您第一次观察时使用的空间可能不适用于所有按键。

您应该知道,以一致性级别ONE写入所有副本并不能保证每个副本都拥有副本。接收数据的节点不必存储它以返回写入的成功,即使它是副本。它可能会过载(在您的工作负载中,这很可能是由于没有足够的I / O来写出数据)并放弃写入,同时成功将其写入不同的副本。这样可以减少在第二次观察中使用的空间,但可能不会在测试中发生,因为它是相对少量的数据。

如果您需要保证有两份副本,则应以一致性级别ALL写入,并且只写一次。