一个多月没有更新博客了。我在积累,频繁更新的话,就没有东西写了-_-。不过还是要定期的总结,以备忘,以分享,以交流,以提高。
这篇博客说的问题是Cassandra在memtable flush为sstable的时候,大小是如何计算的,以及flush的阈值是如何确定的。这个过程是动态的,并不是设定某个内存的大小,或者qps多少的时候,进行flush。一方面计算过程可能并不那么直接,另一方面1.1.3版本之前,这里隐藏了比较严重的bug:
- 可能会造成内存溢出(很严重)
- 可能会造成L0层的sstable文件很小(长期来看,也比较严重,严重影响读性能)
可能会有以下的日志:
- WARN [MemoryMeter:1] 2012-09-04 16:04:50,405 Memtable.java (line 181) setting live ratio to maximum of 64 instead of Infinity
-
INFO [MemoryMeter:1] 2012-09-04 16:04:50,393 Memtable.java (line 186) CFS(Keyspace='YourKeyspace', ColumnFamily='YourCF') liveRatio is 64.0 (just-counted was 64.0). calculation took 96ms for 0 columns
这个是基于1.0.10版本Cassandra的。造成这个现象的具体原因是insert,delete等操作变化过于剧烈。上面的第二个问题,我亲身遇到过。主要场景是,开始大批量写入,然后大批量删除。造成两次flush之间只有删除操作,或者大量的都是删除,只有少数的insert。此时,live ratio就会计算为64,导致非常小的sstable大小。 下面具体结合代码分析一下什么是live ratio,如何计算,对memtable大小的影响。最关键的三个类:
- MeteredFlusher:在ColumnFamilyStore中启动,定期执行
- Memtable:包含memtable实际操作的代码,flush等
- ColumnFamilyStore:代表一个column family综合管理memtable,sstable,Compaction等。
对这个进行分析,也是以后分析写过程,改进写过程的基础。上面提高的问题,已经在1.1.3版本中基本修正了。
【完】
【后记】
我已经尽量不涉及太多公式了,写完了,自己还是觉得很枯燥,就写给遇到这个bug的同学吧。另外,Cassandra内存管理,有一些比较先进的理念。以后可以多多总结。欢迎交流。