我的专栏地址:
一、ycsb压测工具
1.1ycsb workload
ycsb的workloads目录下保存了6种不同的workload类型,代表了不同的压测负载类型,详细的介绍列在下面:
workloada:混合了50%的读和50%的写;workloadb:Read mostly workload,混合了95%的读和5%的写,该workload侧重于测试集群的读能力;workloadc:Read only,100%只读workloadd:Read latest workload,插入数据,接着就读取这些新插入的数据workloade:Short ranges,短范围scan,不同于随机读,每个测试线程都会去scan一段数据workloadf:Read-modiy-wirte,读改写,客户端读出一个记录,修改它并将被修改的记录返回1.2workload配置文件字段说明
fieldcount: 每条记录字段个数 (default: 10)fieldlength: 每个字段长度 (default: 100)readallfields: 是否读取所有字段true或者读取一个字段false (default: true)readproportion: 读取作业比例 (default: 0.95)updateproportion: 更新作业比例 (default: 0.05)insertproportion: 插入作业比例 (default: 0)scanproportion: 扫描作业比例 (default: 0)readmodifywriteproportion: 读取一条记录修改它并写回的比例 (default: 0)requestdistribution: 请求的分布规则 uniform, zipfian or latest (default: uniform)maxscanlength: 扫描作业最大记录数 (default: 1000)scanlengthdistribution: 在1和最大扫描记录数的之间的分布规则 (default: uniform)insertorder: 记录被插入的规则ordered或者hashed (default: hashed)operationcount: 执行的操作数.maxexecutiontime: 执行操作的最长时间,当然如果没有超过这个时间以运行时间为主。table: 测试表的名称 (default: usertable)recordcount: 加载到数据库的纪录条数 (default: 0)
1.3 BinData
BinData()的第一个参数是BSON二进制子类型,如上所述,它是以下之一:generic: \x00 (0)function: \x01 (1)old: \x02 (2)uuid_old: \x03 (3)uuid: \x04 (4)md5: \x05 (5)user: \x80 (128)
1.4ycsb操作命令
加载数据:./bin/ycsb load mongodb -P workloads/test_insert > result_insert_10000.log跑压测:./bin/ycsb run mongodb -P workloads/test_insert > result_insert_10000.log
二、mongodb操作
2.1操作命令
清空表 db.col.remove({})查询一条记录 db.usertable.find().limit(1)删库: db.dropDatabase()查看执行效率:db.usertable.find({"_id":"user4520119406760868179"}).explain("executionStats")查看索引 :db.usertable.getIndexes()集合文档数:db.usertable.count()恢复备份:mongorestore -h 127.0.0.1:27017 --gzip -db collectionName /path集合记录数列表: db.getCollectionNames().forEach((name) => {print(name+","+db[name].stats().count)})集合按记录条数排序: db.getCollectionNames().map((name) => db[name]).sort((a,b) => {return a.count()-b.count()}).forEach((db) => {print(db.getName()+","+db.count())})查看执行效率:db.log.find({"uid":"508076972", "time":{"$gt":ISODate("2019-01-17T00:01:11Z")}}).explain("queryPlanner")查看io: iostat -xdm 1 10
三、压测步骤
3.1 ycsb压测
参考:
1、对mongo进行 95%写入 , 5%查询的测试 2、对mongo进行 100% scan的查询的测试结果:
3.1.1写1亿条日志,hashed写入:
每条日志 大小1KB, 16个字段,字段长度为64。
top命令:
io:
压测完后数据库大小是 136GB:
ycsb 136.250GB
ycsb压测报告:
[OVERALL], RunTime(ms), 2909439[OVERALL], Throughput(ops/sec), 34370.88730851549[TOTAL_GCS_PS_Scavenge], Count, 10132[TOTAL_GC_TIME_PS_Scavenge], Time(ms), 14302[TOTAL_GC_TIME_%_PS_Scavenge], Time(%), 0.4915724302863886[TOTAL_GCS_PS_MarkSweep], Count, 1[TOTAL_GC_TIME_PS_MarkSweep], Time(ms), 27[TOTAL_GC_TIME_%_PS_MarkSweep], Time(%), 9.280139573299182E-4[TOTAL_GCs], Count, 10133[TOTAL_GC_TIME], Time(ms), 14329[TOTAL_GC_TIME_%], Time(%), 0.4925004442437184[CLEANUP], Operations, 100[CLEANUP], AverageLatency(us), 1252.63[CLEANUP], MinLatency(us), 1[CLEANUP], MaxLatency(us), 125055[CLEANUP], 95thPercentileLatency(us), 6[CLEANUP], 99thPercentileLatency(us), 9[INSERT], Operations, 100000000[INSERT], AverageLatency(us), 2873.72475394[INSERT], MinLatency(us), 141[INSERT], MaxLatency(us), 169476095[INSERT], 95thPercentileLatency(us), 8035[INSERT], 99thPercentileLatency(us), 20767[INSERT], Return=OK, 100000000
3.1.2二八原则压测 mongo写入1亿条
每条日志 大小608B, 16个字段,字段长度为38B。
top:
io:
压测完后库的大小是82GB:
> show dbsadmin 0.000GBconfig 0.000GBlocal 0.000GBycsb_1yi 0.697GBycsb_28 82.100GB
ycsb压测报告:
[OVERALL], RunTime(ms), 1732198[OVERALL], Throughput(ops/sec), 57730.12092151128[TOTAL_GCS_PS_Scavenge], Count, 8024[TOTAL_GC_TIME_PS_Scavenge], Time(ms), 10927[TOTAL_GC_TIME_%_PS_Scavenge], Time(%), 0.6308170313093538[TOTAL_GCS_PS_MarkSweep], Count, 2[TOTAL_GC_TIME_PS_MarkSweep], Time(ms), 42[TOTAL_GC_TIME_%_PS_MarkSweep], Time(%), 0.002424665078703474[TOTAL_GCs], Count, 8026[TOTAL_GC_TIME], Time(ms), 10969[TOTAL_GC_TIME_%], Time(%), 0.6332416963880572[CLEANUP], Operations, 100[CLEANUP], AverageLatency(us), 73.68[CLEANUP], MinLatency(us), 1[CLEANUP], MaxLatency(us), 7155[CLEANUP], 95thPercentileLatency(us), 3[CLEANUP], 99thPercentileLatency(us), 12[INSERT], Operations, 100000000[INSERT], AverageLatency(us), 1716.96953065[INSERT], MinLatency(us), 141[INSERT], MaxLatency(us), 20643839[INSERT], 95thPercentileLatency(us), 6279[INSERT], 99thPercentileLatency(us), 14743
3.1.1写1亿条日志,顺序写入:
top:
io:
压测完后库的大小是115GB:
test 173.805GBadmin 0.000GBconfig 0.000GBlocal 0.000GBycsb_1yi 0.697GBycsb_1yi_ordered 115.750GBycsb_insert_1w 0.012GBycsb_search 12.562GB
ycsb压测报告:
[OVERALL], RunTime(ms), 1803374[OVERALL], Throughput(ops/sec), 55451.61458466186[TOTAL_GCS_PS_Scavenge], Count, 5738[TOTAL_GC_TIME_PS_Scavenge], Time(ms), 8131[TOTAL_GC_TIME_%_PS_Scavenge], Time(%), 0.4508770781878856[TOTAL_GCS_PS_MarkSweep], Count, 1[TOTAL_GC_TIME_PS_MarkSweep], Time(ms), 27[TOTAL_GC_TIME_%_PS_MarkSweep], Time(%), 0.0014971935937858703[TOTAL_GCs], Count, 5739[TOTAL_GC_TIME], Time(ms), 8158[TOTAL_GC_TIME_%], Time(%), 0.4523742717816715[CLEANUP], Operations, 100[CLEANUP], AverageLatency(us), 54.86[CLEANUP], MinLatency(us), 0[CLEANUP], MaxLatency(us), 5343[CLEANUP], 95thPercentileLatency(us), 7[CLEANUP], 99thPercentileLatency(us), 19[INSERT], Operations, 100000000[INSERT], AverageLatency(us), 1796.96847349[INSERT], MinLatency(us), 147[INSERT], MaxLatency(us), 8028159[INSERT], 95thPercentileLatency(us), 1518[INSERT], 99thPercentileLatency(us), 3451[INSERT], Return=OK, 100000000
插入性能总结:
规格 | 文档大小 | count操作记录数 | _id值 | threads压测端线程数 | throughput(per second)吞吐 | RAL(us)读延时** | WAL(us)写延时** |
---|---|---|---|---|---|---|---|
16核32G | 大小1KB, 16个字段,字段长度为64 | 1亿 | hashed | 100 | 34370 | - | 2873 |
16核32G | 大小608B, 16个字段,字段长度为38B | 1亿 | hashed | 100 | 57730 | - | 1716 |
16核32G | 大小1KB, 27个字段,字段长度为38B | 1亿 | ordered | 100 | 55451 | - | 1796 |
可与阿里云版mongodb性能进行对比:
3.2 场景测试
执行命令:
db.usertable.find({"field1":"joe"}).explain("executionStats")
db.usertable.find({"field1":"joe","field2":"jack"}).explain("executionStats")测试数据查询:
场景1:1千万条成1KB, 扫表时间250秒, 一秒扫4W条。mongo库 12GB,一秒49MB。({"field1":"joe"})场景2:1千万条成1KB, 扫表时间322秒。(({"field1":"joe","field2":"jack"})场景3:1亿条成600B, 扫表时间1800秒, 一秒扫5.5W条。mongo库 82GB,一秒46.7MB。({"field1":"joe"})
生产数据查询:
全表扫描简单条件:
场景1扫描字段({"uid":"508076972"}):233393233(2.3亿)条,每条547B, 扫表时间518秒, 一秒扫450566条。表存储大小56GB,一秒108MB。场景2扫描字段({"eid":"508076972"}):233393233(2.3亿)条,每条547B, 扫表时间564秒, 一秒扫413817条。表存储大小56GB,一秒99MB。场景3扫描字段({"eid":"508076972"}):119963485(1.2亿)条,每条532B, 扫表时间290秒, 一秒扫413667条。表存储大小25GB,一秒87MB。场景4扫描字段({"eid":"508076972"}):10144088(1千万)条,每条536B, 扫表时间28秒, 一秒扫362288条。表数据大小5GB,表存储大小2.5GB,一秒91MB。场景5扫描字段({"uid":"508076972"}):10144088(1千万)条,每条536B, 扫表时间45秒, 一秒扫225424条。表数据大小5GB,表存储大小2.5GB,一秒56MB。
场景4和5有点奇怪,索引字段的效率还不如非索引字段。通过验证,发现是索引字段第一次查询在建立缓存,场景5后续的查询都在5秒左右完成。
全表扫描复合条件:
场景1扫描字段({"eid":"32435346465ddf4","gamechannel":"1010031002"}):233393233(2.3亿)条,每条547B, 扫表时间562秒, 一秒扫415290条。表存储大小56GB,一秒100MB。场景2扫描字段({"uid":"508076972","eid":"32435346465ddf4"}):233393233(2.3亿)条,每条547B, 扫表时间534秒, 一秒扫437065条。表存储大小56GB,一秒105MB。场景2扫描字段({"uid":"508076972","time":"32435346465ddf4"}):秒出结果。
全表扫描结论
日志查询效率: 40W记录/秒, 90MB/秒。 (单字段一次全表扫描,如果复合条件查询加上相应扫描时间)
索引扫描 time + 非uid:
场景1扫描字段({ "time":{"$gt":ISODate("2019-01-17T00:01:11Z"), "$lt":ISODate("2019-01-18T00:01:11Z")}}):16537187(1千万)条,每条547B, 扫表时间23秒, 一秒扫719008条。场景2扫描字段({ "time":{"$gt":ISODate("2019-01-19T00:01:11Z"), "$lt":ISODate("2019-01-20T00:01:11Z")}}):17110050(1千万)条,每条547B, 扫表时间27秒, 一秒扫633705条。场景3扫描字段({ "time":{"$gt":ISODate("2019-01-19T00:01:11Z"), "$lt":ISODate("2019-01-19T12:01:11Z")}}):11050895(1千万)条,每条547B, 扫表时间13秒, 一秒扫850068条。场景4扫描字段({ "eid":"508076972","time":{"$gt":ISODate("2019-01-17T00:01:11Z"), "$lt":ISODate("2019-01-18T00:01:11Z")}}):16537187(1千万)条,每条547B, 扫表时间26秒, 一秒扫636045条。场景5扫描字段({ "time":{"$gt":ISODate("2019-01-19T00:01:11Z"), "$lt":ISODate("2019-01-19T10:01:11Z")}}):9423255(1千万)条,每条547B, 扫表时间10秒, 一秒扫9423255条。场景6扫描字段({ "time":{"$gt":ISODate("2019-01-17T00:01:11Z"), "$lt":ISODate("2019-01-19T00:01:11Z")}}):32972256(3千万)条,每条547B, 扫表时间86秒, 一秒扫383398条。场景7扫描字段({ "time":{"$gt":ISODate("2019-01-17T00:01:11Z"), "$lt":ISODate("2019-01-20T00:01:11Z")}}):50082445(5千万)条,每条547B, 扫表时间95秒, 一秒扫527183条。场景8扫描字段({"eid":"508076972", "time":{"$gt":ISODate("2019-01-17T00:01:11Z"), "$lt":ISODate("2019-01-18T00:01:11Z")}}):3586078(3百万)条,每条547B, 扫表时间5秒, 一秒扫717215条。场景9扫描字段({"eid":"508076972", "time":{"$gt":ISODate("2019-01-18T00:01:11Z"), "$lt":ISODate("2019-01-19T00:01:11Z")}}):4250364(4百万)条,每条547B, 扫表时间7秒, 一秒扫607194条。
索引扫描结论
日志查询效率: 随着记录条目增加,扫描效率会下降。 按10秒响应结果为目标,扫描条目应控制在 1000W条以内。