Yahoo! Cloud Serving Benchmark (YCSB) 是一个Java语言实现的用于云端或者服务器端的数据库性能测试工具,其内部涵盖了常见的NoSQL数据库产品,如Cassandra、MongoDB、HBase、Redis等等。
这个框架具有很好的可扩展性,可以通过配置文件来指定需要进行什么样的workload的测试,比如读写比例多少,每条记录多大,每个字段多大,并发数多大,进行随机选择使用的分布(比如读一条数据的时候)等。
wget https://github.com/brianfrankcooper/YCSB/releases/download/0.17.0/ycsb-mongodb-binding-0.17.0.tar.gz
tar xvfz ycsb-mongodb-binding-0.17.0.tar.gz
chown -R mongod:mongod ycsb-mongodb-binding-0.17.0
默认的6种测试场景如下:
1)workloada:读写均衡型,50%/50%,Reads/Writes
2)workloadb:读多写少型,95%/5%,Reads/Writes
3)workloadc:只读型,100%,Reads
4)workloadd:读最近写入记录型,95%/5%,Reads/insert
5)workloade:扫描小区间型,95%/5%,scan/insert
6)workloadf:读写入记录均衡型,50%/50%,Reads/insert
■ 为指定的库和表指定hash分片
sh.enableSharding("testdb")
sh.shardCollection("testdb.test1", {_id:"hashed"})
■ 测试模型,即workload模型
workload id |workload desc |recordcount
------------|--------------------------------|----------
workload_s1 |100% insert |1亿
workload_s2 |90% update, 10% read |1亿
workload_s3 |65% read, 25% insert, 10% update|1亿
workload_s4 |50% read, 50% update |1亿
workload_s5 |100% read |1亿
------------|--------------------------------|----------
workload_s6 |60% read, 40% insert |100万
与研发负责人沟通,本次测试的业务模型采用如上的s6模型,比较接近业务真是状态。
■ 测试指标
RunTime
Throughput
AverageLatency
评判指标:通过调整线程数,直到发现ops不再增加而平均响应时间继续增加,或者测试主机、集群节点的cpu负荷达到一定程度
■ workload_s6
cat > workloads/workload_s6 << EOF
recordcount=1000000
operationcount=1000000
workload=site.ycsb.workloads.CoreWorkload
readallfields=true
readproportion=0.6
updateproportion=0
scanproportion=0
insertproportion=0.4
requestdistribution=zipfian
EOF
THREADS=100
bin/ycsb load mongodb -threads ${THREADS} -P workloads/workload_s6 -p fieldcount=1 -p fieldlength=1024 -p clientbuffering=true -p table=test1 -p mongodb.url=mongodb://admin:'adminMongoDB!2#'@node1:20000,node2:20000,node3:20000/testdb?authSource=admin 1>workload_s6_load_${THREADS}.result 2>workload_s6_load.log&
tail -100f workload_s6_load_${THREADS}.result
bin/ycsb run mongodb -threads ${THREADS} -P workloads/workload_s6 -p fieldcount=1 -p fieldlength=1024 -p clientbuffering=true -p table=test1 -p mongodb.url=mongodb://admin:'adminMongoDB!2#'@node1:20000,node2:20000,node3:20000/testdb?authSource=admin 1>workload_s6_run_${THREADS}.result 2>workload_s6_run.log&
tail -100f workload_s6_run_${THREADS}.result
使用如上的脚本,调整THREADS参数,反复测试,分析如下。
■ 分片集群性能测试数据统计分析
workload |threads| rows |RunTime|Throughput||Operations|AverageLatency||Operations|AverageLatency||Operations|AverageLatency
| | | (s) | || (Read) | (us) || (Insert) | (us) || (Update) | (us)
-----------|-------|--------|-------|----------||----------|--------------||----------|--------------||----------|--------------
| 10 |1000000 | 145 | 6916 || 600565 | 1486 || 399435 | 1274 || X | X
workload_s6| 20 |1000000 | 71 | 14097 || 598887 | 1357 || 401113 | 1377 || X | X
| 30 |1000000 | 52 | 19102 || 599719 | 1495 || 400281 | 1521 || X | X
| 50 |1000000 | 52 | 19126 || 600574 | 2833 || 399426 | 1835 || X | X
| 80 |1000000 | 69 | 14470 || 599662 | 4440 || 400338 | 2553 || X | X
| 100 |1000000 | 42 | 23628 || 599939 | 3981 || 400061 | 3827 || X | X
| 150 |1000000 | 141 | 7066 || 599882 | 6373 || 400118 | 4007 || X | X
| 150 |1000000 | 45 | 21845 || 601056 | 5593 || 398944 | 4284 || X | X
| 200 |1000000 | 47 | 20879 || 599388 | 6972 || 400612 | 5275 || X | X
| 300 |1000000 | 81 | 12336 || 599795 | 10121 || 400205 | 8441 || X | X
测试表明,开200、300并发时,测试主机的cpu空闲瞬时达到20%左右,集群节点1的cpu空闲5%左右,node2、3分别是25%、40%,可见3节点集群的并发能力基本达到了极限。
可见,开100并发时,集群基本达到了最佳性能。
如果不启用分片,测试如下:
| 50 |1000000 | | || | || | || X | X
| 100 |1000000 | 189 | 5279 || 600016 | 7094 || 399984 | 2572 || X | X
workload_s6| 100 |1000000 | 38 | 26168 || 600205 | 4076 || 399795 | 2696 || X | X
| 150 |1000000 | 39 | 25371 || 600090 | 5650 || 399910 | 5884 || X | X
| 150 |1000000 | 85 | 11764 || 599122 | 6058 || 400878 | 3877 || X | X
此时:
'shard2/node2:27002,node3:27002': {
db: 'testdb',
collections: 1,
views: 0,
objects: 1399984,
可见数据落到了shard2 server,根据之前的规划,shard2的数据实际存储在了node2、3,主节点时node2,从节点时node3,仲裁节点是node1。
100-150并发时,集群的整体性能表现稳定,并没有下降,说明此时即使不使用分片,集群也能承受这个压力。
但是可以预见,一旦并发数大到一定程度,肯定会导致明显的性能下降,此时就需启用3个shard分片,可充分利用3个节点的io及cpu能力。
结论:如果能力需求压力较大,则务必为相关的collection设置分片策略,以充分利用多节点的处理能力。