Cassandra内存表过多相关咨询:压缩机制与读写流程疑问
嘿,我来帮你拆解这些Cassandra压缩相关的问题,都是日常运维里常碰到的点,咱们一个个说清楚:
1. 10个1MB-50MB Memtable场景下的压缩机制运作
首先得明确:Memtable是内存中的写缓存,本身不会被压缩,只有当Memtable写满(或者达到配置的flush阈值)后,会被刷到磁盘变成SSTable,压缩机制是针对SSTable生效的。
你现在有10个这样的Memtable,它们会陆续被flush成10个大小在1MB-50MB之间的SSTable。接下来压缩的运作逻辑取决于你用的压缩策略(默认是SizeTieredCompactionStrategy,也就是分层压缩):
- 后台压缩线程会定期扫描SSTable,把大小相近的SSTable归为一组(比如几个10MB左右的、几个40MB左右的)。
- 当同一组的SSTable数量达到阈值(默认是4个),就会触发压缩:读取这组里的所有SSTable,合并数据(去重、清理已标记删除的数据、合并同一分区的多版本数据),生成一个或多个新的SSTable,最后删除旧的SSTable。
- 整个压缩过程是后台异步执行的,不会阻塞写操作,但会占用一定的IO和CPU资源——不过因为你的SSTable都不大,压缩的开销相对可控。
2. Minor压缩与Major压缩的区别及触发频率
这俩是Cassandra压缩体系里的核心概念,区别可大了:
核心区别
- Minor压缩(分层压缩):是增量式的局部压缩,只会合并某一组大小相近的SSTable,不会碰所有数据。它的目标是减少SSTable数量、轻量清理无效数据、合并同分区的多版本数据,速度快,资源占用低,是日常运行中最常见的压缩类型。
- Major压缩:是全量压缩,会把节点上某个列族的所有SSTable全部合并。它会彻底清理所有已标记删除的数据、过期数据、重复数据,最终生成极少数(甚至一个)大的SSTable。但这个过程非常耗IO和CPU,速度很慢,对集群性能影响较大。
触发频率
- Minor压缩:自动触发的场景很多,比如:
- 同大小层级的SSTable数量达到配置阈值(默认4个);
- SSTable总大小达到列族磁盘占用的一定比例;
- 后台压缩线程定期扫描(默认10分钟一次)发现满足压缩条件。
- Major压缩:默认情况下Cassandra不会自动触发,一般需要手动执行命令
nodetool compact来触发。虽然可以通过配置major_compaction_interval开启自动触发,但绝大多数生产环境都不建议这么做——毕竟太耗资源了,通常只在需要彻底清理数据、优化读性能的时候手动执行。
3. 单个分区下两个1KB SSTable压缩时的读请求流程与延迟
先纠正一个小误区:Memtable不会被压缩,你说的应该是这两个Memtable flush成了1KB的SSTable,且属于同一个分区,此时这两个SSTable正在被压缩的场景。
读请求工作流程
当读请求到达时,Cassandra的查询逻辑是这样的:
- 先查活跃Memtable(当前正在接收写请求的内存缓存);
- 再查Immutable Memtable(已经写满等待flush的内存缓存);
- 最后查磁盘上的所有SSTable——包括正在被压缩的旧SSTable,以及压缩过程中已经生成的新SSTable。
因为压缩过程中旧的SSTable不会被立即删除,直到新SSTable完全生成并校验完成,所以读请求可以正常从旧SSTable中读取数据,完全不会因为压缩被阻塞。
读延迟问题
一般来说不会产生明显的读延迟:
- 压缩是后台异步执行的,不会阻塞读操作的执行;
- 这两个SSTable只有1KB大小,压缩过程会非常快,就算占用一点IO资源,持续时间也极短;
- Cassandra会通过配置压缩线程数、IO优先级来限制压缩对业务的影响,避免资源抢占。
当然,如果集群本身IO资源已经很紧张,压缩可能会导致读请求的IO等待时间略有增加,但这种情况在小SSTable的压缩场景下几乎可以忽略。
内容的提问来源于stack exchange,提问作者Coder
相关产品推荐
相关产品推荐

