避免Cassandra全表扫描跨DC

时间:2019-02-23 17:37:06

标签: cassandra datastax cassandra-3.0

我有分布在2个数据中心的Cassandra群集节点。每个数据中心6个节点,总共12个节点

我的键空间定义:

CREATE KEYSPACE my_keyspace WITH replication = {'class': 'NetworkTopologyStrategy', 'dc1': '3', 'dc2': '3'} AND durable_writes = true;

在每个节点中,我有64个令牌。

我正在使用Cassandra驱动程序连接到集群,并使用默认的负载平衡策略DCAwareRoundRobinPolicy,并且仅使用dc1个节点作为联系点。因此,我假设dc2节点将具有HostDistance IGNORED,而我的应用程序将无法连接到它们。

注意:对于我的所有读写操作,我都使用相同的配置

我的用例是进行全表扫描。但是,我不能使用Spark。因此,我通过使用metadata.getTokenRanges()获取所有令牌范围并在多个线程中查询这些令牌范围来实现这一目标。

一切正常。但是,metadata.getTokenRanges()返回768个令牌(64 * 12)。这意味着它给了我所有12个节点的令牌范围。

因为我必须遍历所有令牌范围。即使有多个线程,该过程也非常慢。
有什么办法可以让我获得一个数据中心的令牌范围。我什至尝试使用metadata.getTokenRanges("my_keyspace", host from dc1)获取令牌范围。 我确实获得的令牌数量更少(517),但是当我使用此列表时,我获得的数据更少。

如何获得仅1个DC的令牌范围?

编辑:我检查了两个集群的读写延迟。我没有看到在dc2上执行任何操作,而在dc1数据中心上却看到了明显的高峰。

这对我来说更加令人困惑。如果从未询问过dc2,我将如何获得64*12 +1令牌范围?为什么不64*6+1

1 个答案:

答案 0 :(得分:0)

您的replication_factor3+3=6。因此,您的数据可能是实际数据的6倍。 dc1中有3个副本,dc2中有3个副本。

每个节点有64个vnode,所以64*12 =768个vnode。

因此,如果要进行完整的表扫描,则可能必须查询所有令牌范围,即768。缺少的是,由于复制,所有令牌范围的数据都将驻留在dc1中。这样您就可以从dc1本身获取所有数据。

如果您正在使用DCAwareRoundRobinPolicy并将.withLocalDc()设置为dc1和一致性级别为LOCAL_*,则您仅从dc1中读取。 dc1将拥有所有数据,因为dc1的replication_factor为3。