Cassandra中的删除 - 上传 - 读取访问模式

时间:2015-05-12 16:54:15

标签: cassandra

我使用Cassandra来存储交易信息。根据可用的查询,我设计我的CF如下:

CREATE trades (trading_book text,
               trading_date timestamp,
               OTHER TRADING INFO ...,
               PRIMARY KEY (trading_book, trading_date));

我想以下列方式删除指定日期的所有数据:

  1. 收集所有交易账簿(存放在其他地方);
  2. 在20个主题中均匀分配所有交易账簿;
  3. 在每个帖子中,遍历书籍,
  4. DELETE FROM交易WHERE trading_book ='A_BOOK'AND                          trading_date = '2015年1月1日'

    大约有100万笔交易,删除需要2分钟才能完成。然后在删除完成后立即再次在2015-01-01上插入交易数据(约100万笔交易)。

    当插入完成并重新读取数据时,即使查询超时设置为600秒,我也收到错误:

    ReadTimeout: code=1200 [Coordinator node timed out waiting for replica nodes' responses] message="Operation timed out - received only 0 responses." info={'received_responses': 0, 'required_responses': 1, 'consistency': 'ONE'} info={'received_responses': None, 'required_responses': None, 'consistency': 'Not Set'}
    

    现在看起来CF中的数据不一致,即协调员可以识别分区,但分区上没有数据?

    我的访问模式有什么问题吗?如何解决这个问题?

    任何提示都将受到高度赞赏!谢谢。

2 个答案:

答案 0 :(得分:4)

您正在为该日期的每一列创建逻辑删除(通过执行删除操作),然后在顶部创建新记录。所以现在每次读取必须首先读取原始列,然后是逻辑删除,然后是新记录。如果你做了一个跟踪,你会看到墓碑读取正在杀死你。这种模式对于Cassandra来说是有问题的,所以你应该尝试找到一种不同的(不可变的)方法来做到这一点。另一种方法是简单地覆盖数据,在这种情况下,没有可以协调的墓碑。但是你仍然需要处理两个版本。

答案 1 :(得分:2)

除了rs_atl的回复(其中有关于墓碑的指甲),这里有一些信息可供您理解/解决问题:

什么是墓碑?

因为sstables是不可变的,而不是删除Cassandra中的记录,所以我们插入一个基本上保持空值的新单元格。那是一块墓碑。在gc_grace秒之后,墓碑可用于删除或垃圾收集(可由表配置)。

墓碑和修缮:

我们等待的原因是确保c *有时间将墓碑传播到所有副本。如果逻辑删除没有被复制到所有副本(例如在一些边缘情况下具有低CL写入和翻转节点)然后被删除/ gc,则删除的原始数据将恢复生命。这就是为什么我们至少每个GC_Grace运行修复,确保墓碑一致性和防止僵尸数据。

我打了几个墓碑?

如果您在cqlsh tracing on中启用跟踪或在yaml或通过nodetool启用概率跟踪,您将能够看到您为特定请求命中了多少个逻辑删除。随着此数字变大,您的阅读效果将会下降,直到您看到您提到的超时时间为止。

nodetool cfstats还为您提供了表格中有多少个墓碑的宏细节(每片的平均墓碑)。

sstablemetadata实用程序会显示表格中的墓碑总数。

我该怎样做才能摆脱墓碑?

1)如果您要删除表中的所有内容,truncate table是一种在c *中免费删除数据的方法,因为您可以使整个sstables过期。

2)通过压实去除墓碑。您可以通过减少gc_grace_seconds和/或增加tombstone ratio进行压缩来更积极地删除逻辑删除,但请确保您正在运行修复,否则您可能会看到僵尸数据。