在过去的一段时间中,针对一个应用的场景,我们测试了一下Cassandra的表现。

从测试结果来看,Cassandra的写性能非常突出,但是在读方面表现的不是很理想。

测试环境描述:

硬件环境

共50台测试服务器,25台作为Cassandra节点,25台作为测试节点,每台服务器的配置信息:

  • CPU: 8*E5420 @ 2.50GHz
  • 300 * 6硬盘,无raid,LVM
  • 16GB内存

软件环境

  • OS: RHEL 4 update 5,2.6.9-89.0.19.ELsmp,x86
  • java版本:1.6.0_20
  • Cassandra版本:0.6.1-RELEASE
  • 测试客户端直接调用Cassandra的thrift接口

一些配置参数

修改了Cassandra节点的jvm参数:

JVM_OPTS=” -server -Xms2G -Xmx2G -XX:TargetSurvivorRatio=90 -XX:+AggressiveOpts -XX:+UseParNewGC -XX:+UseConcMarkSweepGC -XX:+CMSParallelRemarkEnabled -XX:+HeapDumpOnOutOfMemoryError -XX:SurvivorRatio=128 -XX:MaxTenuringThreshold=0 -Dcom.sun.management.jmxremote.port=8080 -Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.authenticate=false”

Cassandra的一些主要配置:

测试数据存放的column family:

3

org.apache.cassandra.dht.RandomPartitioner

,按照(2^127/N)*I计算,N=25, I=[1,25]

CommitLogDirectory位于单独的一块磁盘,我没有忽悠你,我们这批机器有12块硬盘 :-)

DataFileDirectories位于6块磁盘组成的LVM分区中

测试的数据格式

用json格式的描述大概如下

userid => {
"1" => {
1234567 : values_11,
1234568 : values_12,
......
},
"2" => {
1234567 : values_21,
1234568 : values_22,
......
}
}

其中key是userId,数字型,supercolumn的key是表示数据的类型,column的key是一个时间戳,value是一个380左右大小的字节流。

测试数据准备

向集群写入数据,共5000万个不同的userId,每个userId下面2个supercolumn,每个supercolumn中100个column,所以总的数据量是100亿个columns。

数据写入后,总的大小是9830.08GB,查看磁盘,共占用11606GB物理空间。

接下去的测试都是在集群中已经有这些数据的基础上执行的。

具体测试

读测试

测试方法

25台服务器作为客户端,每个客户端启动一定的线程数(见图的X轴)执行读取(get_slice)操作,每次读取一个随机用户的随机super column下最新20条columns。读取的范围是500万个用户(总数据的10%)。

读取操作的ConsistencyLevel设置为1,读到一份数据就返回成功。

数据

下图分别是tps和响应时间的趋势图。这是一个测试节点的数据,整个集群的性能可以认为是这个数据*25,下同。
 

写测试

测试方法

25台服务器作为客户端,每个客户端启动一定的线程数(见图的X轴)执行insert操作,每次insert一个随机用户随机super column下的一个column。

写操作的ConsistencyLevel也设置为1,即写入一个节点即返回成功,另两个备份异步写入。

数据

下图分别是tps和响应时间的趋势图。

10:1读写测试

此外,我们还测试了10:1读写情况下Cassandra的表现,但是只测试了每个客户端32个线程的场景。

测试方法

20台服务器作为读客户端,每个客户端启动32个线程执行读取(get_slice)操作,每次读取一个随机用户随机super column下的一个column。读取的范围是500万个用户(总数据的10%)。

2台服务器作为写客户端,每台客户端启动32个线程执行写操作,每次写入一随机用户随机super column下的一个column。

读取和写入的ConsistencyLevel都设置为1.

数据

读节点单台读取的TPS为148,响应时间在200ms左右

写入节点单台写入的TPS为13289,响应时间为2.37ms

总结

得益于Cassandra的写入机制(请求在写入commit log和memory table后即返回成功),写性能很突出,这方面没有什么可担心的。

但是在读方面表现的比较差,这也和其内部的机制有关系。


结论:写性能效率要高于读性能效率!