我在24节点集群中运行Cassandra 3.7,每个节点有3个数据中心和256个vnode,并且每个节点使用cron作业在一天中的不同时段每天运行一次"nodetool repair -pr"与其他节点.
有时维修需要一个多小时才能完成并且维修重叠.发生这种情况时,修复开始获得异常并且可能挂起状态不佳.这会导致级联故障,其中每小时另一个节点将尝试启动修复,它也将挂起.
从中恢复很困难.我发现的唯一方法是不仅重新启动卡住修复的节点,而且还要重新启动集群中的所有节点.
我处理这个问题的唯一想法是构建某种服务,在开始修复之前检查是否有任何其他节点正在运行修复,也许通过在修复过程中在Cassandra表中发布.
我不知道如果集群变大,我将如何能够修复所有节点,因为很快就会在一天之内没有足够的时间在所有节点上逐一运行修复.
所以我的主要问题是,我是否正确地运行修复以及定期修复大型集群的所有节点的建议方法是什么?
有没有办法一次修复多个节点?文档暗示有,但不清楚如何做到这一点.在一次在多个节点上运行时,修复是否会崩溃并烧毁,这是正常的吗?有没有比重新启动所有节点更容易杀死卡住的维修?
我试过的一些事情:
我的密钥空间每个数据中心只保留一个副本,所以我认为我不能使用-local选项.
修复程序挂起时我看到的一些例外情况是:
ERROR [ValidationExecutor:4] 2016-07-07 12:00:31,938 CassandraDaemon.java (line 227) Exception in thread Thread[ValidationExecutor:4,1,main]
java.lang.NullPointerException: null
at org.apache.cassandra.service.ActiveRepairService$ParentRepairSession.getActiveSSTables(ActiveRepairService.java:495) ~[main/:na]
at org.apache.cassandra.service.ActiveRepairService$ParentRepairSession.access$300(ActiveRepairService.java:451) ~[main/:na]
at org.apache.cassandra.service.ActiveRepairService.currentlyRepairing(ActiveRepairService.java:338) ~[main/:na]
at org.apache.cassandra.db.compaction.CompactionManager.getSSTablesToValidate(CompactionManager.java:1320) ~[main/:na]
ERROR [Repair#6:1] 2016-07-07 12:00:35,221 CassandraDaemon.java (line 227) Exception in thread Thread[Repair#6:1,5,RMI Runtime]
com.google.common.util.concurrent.UncheckedExecutionException: org.apache.cassandra.exceptions.RepairException: [repair #67bd9b10-...
]]] Validation failed in /198.18.87.51
at com.google.common.util.concurrent.Futures.wrapAndThrowUnchecked(Futures.java:1525) ~[guava-18.0.jar:na]
at com.google.common.util.concurrent.Futures.getUnchecked(Futures.java:1511) ~[guava-18.0.jar:na]
at org.apache.cassandra.repair.RepairJob.run(RepairJob.java:160) ~[main/:na]
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) ~[na:1.8.0_71]
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) …Run Code Online (Sandbox Code Playgroud) 我正在寻找使用 Cassandra 消除重复事件的最佳方法。
我有很多客户端接收事件 ID(每秒数千个)。我需要确保每个事件 id 被处理一次,并且只处理一次,具有高可靠性和高可用性。
到目前为止,我已经尝试了两种方法:
使用事件 ID 作为分区键,并执行“INSERT ... IF NOT EXISTS”。如果失败,则该事件是重复的,可以删除。这是一个很好的清洁方法,但由于 Paxos,吞吐量不是很大,尤其是在复制因子较高的情况下,例如 3。它也很脆弱,因为 IF NOT EXISTS 总是需要法定人数才能工作,并且没有办法退回到较低的如果法定人数不可用,则保持一致性。因此,几个停机节点将完全阻止处理某些事件 ID。
允许客户端在相同的事件 id 上发生冲突,但随后使用聚类列检测冲突。所以插入使用事件id作为分区键,客户端生成timeuuid作为集群列。然后客户端将等待一段时间(以防其他客户端插入相同的分区键),然后读取限制为 1 的事件 ID,以返回最旧的聚集行。如果它读回的 timeuuid 与它插入的内容匹配,那么它就是“赢家”并处理事件。如果 timeuuid 不匹配,则它是重复的,可以删除。
与使用 IF NOT EXISTS 相比,碰撞(面包师算法)方法具有更好的吞吐量和可用性,但它更复杂且风险更大。例如,如果客户端上的系统时钟不正常,那么重复事件看起来就像是非重复事件。我所有的客户端和 Cass 节点都使用 NTP,但这在同步时钟方面并不总是完美的。
有人对使用哪种方法有建议吗?有没有另一种方法可以做到这一点?
另请注意,我的集群将设置三个数据中心,DC 之间的延迟约为 100 毫秒。
谢谢。
我真的是卡桑德拉的初学者.我需要在INSERT中使用一些SELECT结果.像这样的东西:
insert into data_tbl
(value_type, time, value, key_id)
values
(
'test1',
now(),
'my first value',
(select key_id from keys where key='123')
);
Run Code Online (Sandbox Code Playgroud)
可能吗 ?