Cassandra 2.1重启后部分列数据丢失问题求助
针对Cassandra 2.1重启后部分列数据丢失的排查与解决建议
结合你提到的复制因子为1的配置,以及数据写入后可正常查询、重启后部分列丢失的现象,我整理了几个常见的原因和对应的处理思路:
1. Memtable未及时持久化到磁盘
Cassandra写入的数据首先会存入内存中的memtable,默认会在达到内存阈值或定期(默认1小时)自动刷写到磁盘的sstables文件中。如果在写入数据后立刻重启节点,memtable中未完成flush的数据会随内存释放而丢失,导致重启后部分列无法查询。
- 解决/排查:
- 重启节点前,手动执行
nodetool flush命令,强制将所有memtable数据刷写到磁盘; - 检查
cassandra.yaml中的memtable_flush_period_in_ms(默认3600000,即1小时),如果业务场景需要更及时的持久化,可以适当缩短这个周期; - 确认
memtable_flush_writers配置(默认4)足够处理flush负载,避免因线程不足导致flush延迟。
- 重启节点前,手动执行
2. Commit Log未正常同步或损坏
Commit Log是Cassandra用于崩溃恢复的关键组件,当memtable未flush时,重启节点会从Commit Log中恢复数据。如果Commit Log未及时同步到磁盘,或者文件损坏,就会导致部分数据无法恢复。
- 解决/排查:
- 检查
cassandra.yaml中的commitlog_sync配置:- 如果设置为
periodic,确认commitlog_sync_period_in_ms(默认10000,即10秒)是否合理,缩短周期可以降低数据丢失风险; - 生产环境建议优先使用
batch模式,确保每次写入操作都同步到Commit Log磁盘;
- 如果设置为
- 重启节点后查看日志(默认路径
logs/system.log),搜索commitlog相关的错误信息,排查是否存在文件损坏; - 如果Commit Log损坏,可以尝试删除损坏的日志文件(注意:这会导致未恢复的数据永久丢失,需谨慎操作),然后重启节点。
- 检查
3. SSTables文件损坏
如果存储sstables的磁盘出现IO错误、节点异常断电,可能导致sstables文件损坏,重启后加载损坏的文件会导致部分数据无法读取。
- 解决/排查:
- 执行
nodetool scrub命令,该命令会验证所有sstables的完整性,自动修复可恢复的损坏部分,无法修复的会标记为损坏并隔离; - 查看日志中是否有
CorruptedSSTableException等相关错误,定位损坏的sstables文件; - 定期检查磁盘健康状态,避免因硬件问题导致数据损坏。
- 执行
4. 异常关闭节点导致数据丢失
如果关闭Cassandra节点时使用了强制kill(如kill -9)而非正常停止命令(nodetool stop或service cassandra stop),Cassandra没有足够时间完成memtable flush和Commit Log同步,会直接导致内存中未持久化的数据丢失。
- 解决/排查:
- 停止节点时必须使用正常的停止流程,给Cassandra足够的时间完成收尾操作;
- 如果已经发生强制关闭,重启前先执行
nodetool flush(若节点还能启动),或检查Commit Log是否有未同步的数据。
5. 墓碑(Tombstone)误判数据丢失
如果之前对部分列执行过删除操作,Cassandra会生成列级墓碑标记。默认墓碑的gc_grace_seconds为10天,在这段时间内查询时如果读取到墓碑,会返回该列不存在,可能被误认为数据丢失。
- 解决/排查:
- 检查是否有针对这些列的删除操作记录;
- 执行
nodetool tombstoneinfo查看表的墓碑情况,确认是否有大量未清理的墓碑; - 若确认是墓碑导致,可适当调整
gc_grace_seconds(但需注意分布式环境下的 tombstone 同步问题,不过你的RF=1,风险较低),或执行nodetool compact手动触发压缩清理墓碑。
内容的提问来源于stack exchange,提问作者Jenny.D
相关产品推荐
相关产品推荐

