我们为提升 Cassandra 读性能做了哪些努力?

目录 (Table of Contents)

  • 关于Cassandra
  • 提升读性能

关于Cassandra

Apache Cassandra是一个高度可扩展的高性能分布式数据库,
用于处理大量常规服务器上的大量数据,提供高可用性,无单点故障。它是一种NoSQL类型的数据库。

我们看一下国外权威机构DB-Engines最近的数据库全球流行程度排名:

可以看出,Cassandra 是排名前十中四个仅有的NoSQL数据库之一。Cassandra在国外这样受欢迎,其性能可想而知不会差,
但是在国内貌似还没有多少公司使用,且国内关于 Cassandra方面的资料较少。

提升读性能

Cassandra 在我们的项目中用来存储时序数据,经过测试,在三台4核16G的虚拟机上,
指标数据的写入TPS可以达到6.5W/s,基本可以满足我们的业务需求。
但是读取性能可能就会差很多,因为数据查询速度跟每次查询的数据量关系比较大,此处也不好定义TPS。
产品查询一周以上的指标数据时,经常会出现加载缓慢,甚至查询超时。为了改善查询状况,我们进行了不少努力。

此处不讨论纵向扩展和横向扩展带来的性能提升。

1. 加快墓碑回收甚至去除墓碑

在Cassandra中,当你删除一条数据时,其实是给这条数据进行update,给它update上一个标识,就是一个墓碑标识。
当Cassandra集群在不同节点之间同步删除信息的时候,也会用到Tombstones(墓碑),可以说墓碑是一种允许Cassandra快速写入的机制。

关于墓碑的更多消息,可参考 Cassandra 数据维护官方文档

可以这样理解,大量的墓碑数据会使查询时搜索的数据量变大,直接影响查询时的效率。
所以,为了消除这种影响,我们可以加快墓碑数据的回收,避免产生大量的墓碑数据。
甚至,当我们在写入时,若写入一致性的值与副本因子数量相等时,可以不产生墓碑数据,直接删掉该无效数据。
具体可通过 调整 table 中 gc_grace_seconds 参数来实现,默认为 864000(10天),我们可以设为 86400(1天)或者0(直接删除)。

2. 降低read repair 的几率

每一次读操作,Cassandra都会在后台进行read repair操作。
如果只要求读一个节点数据,Cassandra在读到一个节点后,就将结果返回客户端,
然后用read repair对其他的replicas进行同步(根据timestamp)。
如果要求读多个节点,那么Cassandra就读多个节点,然后根据timestamp进行比较,返回客户端最新的数据,
然后再调用read repair对其他节点进行同步。
Read repair在后台的操作,会占用一定的CPU和I/O,所以影响读性能。
我们可以降低read repair 的几率,以提高读取性能。

通过修改 table 中 read_repair_chance(取值范围 0-1)参数来设置read repair 的几率,建议设为 0.1。

3. 指标数据预聚合

思路:我们存在数据库中的指标数据,读取时会将指定时间范围内的数据进行聚合。
如果提前将数据按基本时间段提前聚合为一个值,读取时,只读取时间范围内的时间段的汇聚结果,将大大减少查询耗时。

4. 合理部署产品

公司的其他产品使用了mongoDB,线上环境中发现,这两个NoSQL数据库部署在一起时会相互争夺内存资源,
十分影响性能,因此最好将这两个数据库分开部署。

5. 设置合理的堆内存大小和GC策略

堆内存设置的太小,将导致频繁GC甚至OOM,设置的太大同样也不好。可参考官方的公式:
MAX_HEAP_SIZE=max(min(1/2 ram, 1024MB), min(1/4 ram, 8GB)

关于GC策略,官方的建议是:小于16G,用CMS收集器;16-64G,用G1收集器。

6. 设置合理的压式策略

Cassandra 将落到磁盘的数据存放在SStable中,压实是将多个SSTable 文件合并为一个的过程。合并后将减少重复的数据,使数据更紧凑。
Cassandra 有多种触发压实的策略,选一个适合的压实策略,可以更好地压实数据。
比如,我们使用的Kairosdb建议采用 DateTieredCompactionStrategy (DTCS))压实策略。

7. 启用 row cache

row cache 把整个row 的内容都放在内存中。
适合的情况是,有一小部分hot data是经常反问的,或者要返回整个columns.在使用row cache时,用注意它对内存的影响。
可参考 Cassandra 的官方文档设置row cache。

其他

安利一个入门Cassandra 的好博客:learn Cassandra