使用 Cassandra 进行事件重复数据删除

Jim*_*yer 6 cql cassandra cassandra-2.0

我正在寻找使用 Cassandra 消除重复事件的最佳方法。

我有很多客户端接收事件 ID(每秒数千个)。我需要确保每个事件 id 被处理一次,并且只处理一次,具有高可靠性和高可用性。

到目前为止,我已经尝试了两种方法:

  1. 使用事件 ID 作为分区键,并执行“INSERT ... IF NOT EXISTS”。如果失败,则该事件是重复的,可以删除。这是一个很好的清洁方法,但由于 Paxos,吞吐量不是很大,尤其是在复制因子较高的情况下,例如 3。它也很脆弱,因为 IF NOT EXISTS 总是需要法定人数才能工作,并且没有办法退回到较低的如果法定人数不可用,则保持一致性。因此,几个停机节点将完全阻止处理某些事件 ID。

  2. 允许客户端在相同的事件 id 上发生冲突,但随后使用聚类列检测冲突。所以插入使用事件id作为分区键,客户端生成timeuuid作为集群列。然后客户端将等待一段时间(以防其他客户端插入相同的分区键),然后读取限制为 1 的事件 ID,以返回最旧的聚集行。如果它读回的 timeuuid 与它插入的内容匹配,那么它就是“赢家”并处理事件。如果 timeuuid 不匹配,则它是重复的,可以删除。

与使用 IF NOT EXISTS 相比,碰撞(面包师算法)方法具有更好的吞吐量和可用性,但它更复杂且风险更大。例如,如果客户端上的系统时钟不正常,那么重复事件看起来就像是非重复事件。我所有的客户端和 Cass 节点都使用 NTP,但这在同步时钟方面并不总是完美的。

有人对使用哪种方法有建议吗?有没有另一种方法可以做到这一点?

另请注意,我的集群将设置三个数据中心,DC 之间的延迟约为 100 毫秒。

谢谢。

ani*_*hek 1

可能会转移到这里,但是如果您的负载太高,您是否尝试过分布式 Redis 锁http://redis.io/topics/distlock以及基于 event_id 的分片,使用 Twemproxy 作为 Redis 的代理。