Cassandra单节点转双节点集群后吞吐量骤降的原因及优化咨询
分析与解决方案:双节点Cassandra集群TPS下降问题
为什么TPS从38k降到12k?
核心原因是一致性级别调整+双节点架构带来的额外开销,具体拆解:
- 一致性级别的成本飙升:单节点时你大概率用的是
ONE一致性(默认),写操作只需要1个节点确认即可完成;切换到双节点+TWO一致性后,每一次写操作必须等待两个节点都完成持久化/确认,读操作也需要从两个节点拉取数据并校验一致性。这直接把单节点时的"单次IO/网络往返"变成了"两次IO+跨节点网络协调",开销翻倍都不止。 - 复制策略与数据分布的隐性负载:如果你的双节点集群用的是默认
SimpleStrategy且复制因子设为2,那么每一条数据都会被写入两个节点。单节点时只需要写一次磁盘,现在要写两次——如果磁盘IO本来就接近瓶颈,这个变化会直接压垮性能。 - 客户端负载均衡的低效:C++ Driver默认的
RoundRobinPolicy在双节点下可能会出现"协调器转发"的额外开销——比如客户端把请求发给节点A,但这条数据的token归属是节点B,A需要把请求转发给B再返回结果,多了一次跨节点网络跳转。 - 资源竞争加剧:同机架双节点如果共享磁盘存储(比如同一台物理机的两个虚拟机)或者带宽,会出现磁盘IO、网络带宽的竞争,进一步拉低整体吞吐量。
如何把TPS提升到40k左右?
结合你的场景,分优先级给出优化方案:
1. 先调整一致性级别(最快见效)
如果业务允许,降低写操作的一致性要求是提升TPS最直接的手段:
- 写操作改用
LOCAL_ONE:只需要同机架内1个节点确认即可完成,写性能会大幅回升;读操作如果需要强一致性,保留TWO或者改用LOCAL_QUORUM(双节点下LOCAL_QUORUM等价于TWO,但语义更清晰)。 - 如果业务必须写强一致性,考虑把集群扩展到3个节点,复制因子设为3,此时写
TWO只需要2个节点确认——3个节点可以分散IO和网络压力,比双节点的"必须两个都写"的压力小很多。
2. 优化客户端配置(零成本调整)
虽然你说客户端配置没改,但针对双节点场景可以做针对性优化:
- 启用
TokenAwarePolicy:让客户端直接发送请求到负责对应token的节点,避免协调器转发的开销。在C++ Driver里可以这样配置:auto policy = cass_cluster_set_load_balance_policy(cluster, cass_token_aware_policy_new(cass_round_robin_policy_new())); - 增加IO线程数:双节点需要处理更多的跨节点网络IO,把IO线程从10调到15-20,调度线程也可以同步增加到15,提升并发处理能力。
3. 集群层面的性能调优
- 磁盘IO优化:如果用的是HDD,换成SSD可以大幅提升写性能;如果已经是SSD,检查
commitlog_sync配置——把commitlog_sync_period_in_ms从默认的10000调到5000(或者更大,根据数据丢失容忍度调整),减少同步磁盘的频率。 - 调整Cassandra并发参数:修改
cassandra.yaml里的concurrent_writes(从默认的32调到64)、memtable_flush_writers(从默认的2调到4),提升写并发能力;read_request_timeout_in_ms和write_request_timeout_in_ms可以适当调大,避免因为跨节点协调导致超时。 - 避免热点数据:检查你的数据模型,如果某个partition key的访问量特别大,会导致对应的节点压力过载。重新设计partition key,比如加入时间戳或者随机后缀,把热点分散到多个节点。
4. 批量操作优化
在客户端使用异步批量写(注意不要过度批量,避免单请求过大导致超时),减少网络往返次数。C++ Driver里可以用CassBatch对象来批量处理多个写请求:
CassBatch* batch = cass_batch_new(CASS_BATCH_TYPE_UNLOGGED); // 添加多个语句到batch cass_batch_add_statement(batch, statement1); cass_batch_add_statement(batch, statement2); // 异步执行批量请求 cass_session_execute_batch(session, batch, callback, NULL); cass_batch_free(batch);
注意用UNLOGGED批量,比LOGGED批量性能更高(如果业务允许的话)。
是否需要添加更多数据节点?
如果你的业务必须保持TWO的一致性级别,添加到3个节点是非常有必要的:
- 3个节点+复制因子3,写
TWO只需要2个节点确认,相比双节点的"必须两个都写",3个节点可以分散IO压力,每个节点的写负载会降低; - 数据分布更均匀,避免双节点下可能出现的token分布不均导致的节点负载差异;
- 后续要提升到40k TPS,3个节点的架构比双节点有更大的扩容空间,甚至可以继续扩展到4-5个节点,进一步分散压力。
如果业务可以接受降低写一致性,那么双节点也能通过调整一致性级别和参数优化回到接近38k的TPS,甚至达到40k。
内容的提问来源于stack exchange,提问作者Raghunath Murmu
相关产品推荐
相关产品推荐

