Cassandra并发写入场景下读延迟无整体升高仅存随机尖刺咨询
读写并发下读延迟未整体升高的原因
你之前认为写入负载会导致读延迟均匀上升的预期存在偏差,本质是对Cassandra的读写链路逻辑、当前测试场景的负载压力判断不符合实际:
- Cassandra基于LSM树架构设计,写入链路是顺序写CommitLog + 内存写MemTable,正常写入不会对读路径加持久互斥锁,写入完成即返回的机制本身就不会持续阻塞读请求。
- 当前测试负载整体压力极低:读请求仅50RPS,基准延迟仅10ms,测试表总数据量仅10000条,热数据几乎全部常驻在Key Cache、Row Cache内存区域,绝大多数读请求直接命中内存返回,根本不会触碰到磁盘上的SSTable文件,写入带来的SSTable增量短时间内完全影响不到缓存命中率,自然不会出现持续性的读延迟抬升。
- 一致性配置的实际开销远低于你的预期:你业务使用的
search键空间副本因子仅为1,此时配置的读QUORUM、写ALL一致性本质和单副本读写的ONE一致性效果一致,没有多副本同步排队的持续性开销;同时你的读请求没有配置SERIAL读级别,不会全程参与写请求的轻量事务Paxos流程,不会被写入流程持续阻塞。 - 你使用的批量写入是单次攒60条提交的突发批次模式,不是持续平稳的高压写入,集群的CPU、磁盘、内存余量完全可以轻松消化这部分写入负载,不会出现资源被持续占满导致的延迟整体上升。
随机延迟尖刺的成因判断
你观测到的随机延迟尖刺和MemTable刷盘直接相关,但不是唯一诱因:
- 从你提供的
nodetool tpstats结果看,MemtableFlushWriter线程已经累计完成4272次刷盘任务,没有出现任务排队阻塞,说明刷盘流程本身没有积压。但MemTable刷盘是触发式的后台IO动作(触发条件包括MemTable大小达阈值、CommitLog总大小超限、定时刷盘规则),刷盘瞬间会占用磁盘IO带宽,如果你的集群磁盘IO预留空间不足,刚好在刷盘窗口期的少量读请求(尤其是缓存未命中需要读取SSTable的请求)就会出现延迟跳变;由于刷盘不是持续运行的动作,只会产生随机尖刺,不会带来整体延迟上升。 - 除了MemTable刷盘之外,两个后台动作也会触发同类随机尖刺:
- 写请求配置了SERIAL一致性级别,会走轻量事务的Paxos多轮提案流程,读请求刚好命中正在加分区锁做提案的副本时,会短暂等待锁释放,带来随机延迟。
- MemTable刷盘生成SSTable文件后,会触发后台Compaction合并操作,Compaction是高IO、高CPU消耗的后台任务,运行期间会抢占部分节点资源,刚好撞上的读请求也会出现延迟尖刺,你可以通过
nodetool tpstats查看CompactionExecutor的任务计数、通过nodetool compactionstats命令确认运行状态。
补充说明:你贴出的写请求语句
INSERT into table values(id,..) where id = X;存在语法错误,标准CQL的INSERT语句不支持WHERE子句,如果你实际使用了带条件的轻量事务写入(比如IF EXISTS/IF NOT EXISTS),确实会带来少量随机锁开销,但不会造成持续性的延迟影响。

内容的提问来源于stack exchange,提问作者Tipok
相关产品推荐
相关产品推荐

