时间:2021-07-01 10:21:17 帮助过:9人阅读
参考资料:
基于参考文档(https://github.com/brianfrankcooper/YCSB/tree/master/mongodb )安装java,mvn,ycsb
基本上安装了python(2.7.5版本以上),java(需要是jdk,而不是jre),mvn和ycsb之后就可以了
安装好YCSB之后,查看YCSB目录如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
drwxr-xr-x. 3 root root 30 Oct 10 18:20 accumulo
drwxr-xr-x. 3 root root 46 Oct 10 18:20 aerospike
drwxr-xr-x. 2 root root 17 Oct 13 05:03 bin
drwxr-xr-x. 3 root root 56 Oct 10 18:20 binding-parent
-rw-r--r--. 1 root root 877 Oct 10 18:20 BUILD
drwxr-xr-x. 3 root root 30 Oct 10 18:20 cassandra
-rw-r--r--. 1 root root 7216 Oct 10 18:20 checkstyle.xml
drwxr-xr-x. 4 root root 60 Oct 13 03:18 core
drwxr-xr-x. 3 root root 46 Oct 10 18:20 couchbase
drwxr-xr-x. 3 root root 30 Oct 10 18:20 distribution
drwxr-xr-x. 4 root root 4096 Oct 10 18:20 doc
drwxr-xr-x. 4 root root 54 Oct 10 18:20 dynamodb
drwxr-xr-x. 3 root root 46 Oct 10 18:20 elasticsearch
drwxr-xr-x. 3 root root 30 Oct 10 18:20 gemfire
drwxr-xr-x. 2 root root 36 Oct 10 18:20 hbase094
drwxr-xr-x. 3 root root 46 Oct 10 18:20 hbase098
drwxr-xr-x. 3 root root 46 Oct 10 18:20 hbase10
drwxr-xr-x. 3 root root 43 Oct 10 18:20 hypertable
drwxr-xr-x. 3 root root 46 Oct 10 18:20 infinispan
drwxr-xr-x. 3 root root 30 Oct 10 18:20 jdbc
-rw-r--r--. 1 root root 8082 Oct 10 18:20 LICENSE.txt
drwxr-xr-x. 3 root root 43 Oct 10 18:20 mapkeeper
drwxr-xr-x. 4 root root 59 Oct 13 03:19 mongodb
drwxr-xr-x. 3 root root 43 Oct 10 18:20 nosqldb
-rw-r--r--. 1 root root 479 Oct 10 18:20 NOTICE.txt
drwxr-xr-x. 3 root root 46 Oct 10 18:20 orientdb
-rw-r--r--. 1 root root 5263 Oct 10 18:20 pom.xml
-rw-r--r--. 1 root root 2033 Oct 10 18:20 README.md
drwxr-xr-x. 3 root root 46 Oct 10 18:20 redis
drwxr-xr-x. 3 root root 46 Oct 10 18:20 tarantool
drwxr-xr-x. 3 root root 30 Oct 10 18:20 voldemort
drwxr-xr-x. 2 root root 4096 Oct 13 01:09 workloads
|
这里面有几个目录需要注意下:
bin:
- 目录下有个可执行的ycsb文件,是个python脚本,是用户操作的命令行接口。ycsb主逻辑是:解析命令行、设置java环境,加载java-libs,封装成可以执行的java命令,并执行
workloads:
- 目录下有各种workload的模板,可以基于workload模板进行个性化修改
core:
- 包含ycsb里各种核心实现,比如DB的虚拟类DB.java,各个db子类都要继承该类;还有比如workload抽象类,如果我们要自定义workload实现也需要继承该类
各种DB的目录:
- 比如mongo,redis等,里面包含了对应测试的源码等。
- 当ycsb mvn编译后,会在对应的目录下生成target文件,ycsb会加载对应target文件中的class类
ycsb在执行的时候,分为两阶段:load阶段 和 transaction阶段
该阶段主要用于构造测试数据,ycsb会基于参数设定,往db里面构造测试需要的数据,如:
1 |
. /bin/ycsb load mongodb-async -s -P workloads /workloada > outputLoad.txt
|
在ycsb中,对于不同的db都有一些选项,比如mongo就有mongodb 和 mongodb-async。
默认的mongodb表示同步,即load和run使用同步的方式,ycsb会调用mongodb/src底下对应的MongodbClient实现对应的insert/update等操作。如果设置了mongodb-async,ycsb会调用mongodb/src底下对应的AsyncMongoDbClient.java实现
参数设置:
1 2 3 4 5 6 7 8 |
Options:
-P file Specify workload file // workload文件
- cp path Additional Java classpath entries
-jvm-args args Additional arguments to the JVM
-p key=value Override workload property // 一些设置
-s Print status to stderr // 把状态达到stderr中
-target n Target ops /sec (default: unthrottled) // 每秒总共操作的次数
-threads n Number of client threads (default: 1) // 客户端线程数
|
参数解读:
在ycsb的目录下有多种workload,参考:https://github.com/brianfrankcooper/YCSB/wiki/Core-Workloads,我们以workloada举例子
基础配置:
1 2 3 4 5 6 7 8 9 10 11 12 |
recordcount=1000 # 总共的操作条数
operationcount=1000 # 总共操作的次数
workload=com.yahoo.ycsb.workloads.CoreWorkload=
readallfields= true # 在读取的时候,是否需要读取所有字段
readproportion=0.5 # 读取比例
updateproportion=0.5 # update比例
scanproportion=0
insertproportion=0
requestdistribution=zipfian
|
workloada的负载比较中,read和update类比例为1:1,里面一些设置参数如上,如果我们再设置mongo的时候,还需要再workload中增加对应的mongo配置,如下:
1 2 3 |
mongodb.url=mongodb: //192 .168.137.10:34001 /ycsb ? # mongodb对应的uri等
mongodb.database=ycsb # 对应的db
mongodb.writeConcern=normal # 写级别
|
-p用于设置一些对应的参数,如果workload中的参数,也可以以-p的方式放在命令行中设置
-s是表示,在运行中,把一些状态打印到stderr中,一般status信息,用于表示在运行中的一些中间状态(比如当前处理了多少请求,还有多少请求等)
表示1s中总共的操作次数(各个线程加起来的),如果性能不满足,比如最高性能只有100,你设置了1000,那么ycsb会尽量往这个数目去靠近。默认是不做限制
设置ycsb client的并发测试线程数,默认是1,单线程,所以再测试的时候,一定要设置这个选项
在2.1load数据结束之后,ycsb就可以进行测试了,也就是transaction阶段。在transaction阶段,会基于workload中的比例设置,和线程参数设置进行db的压测。具体参数如上
由于这次在使用ycsb测试mongodb中主要是为了测试mongodb3.0的性能,同时需要和2.6.9进行对比。而3.0性能写性能大幅度提升是因为锁力度从db锁升级到collection锁。而默认的insert、update操作都是对于同一个collection操作(usertable),没法体现这个优势。
因此我们需要修改对应的insert、update和read接口实现一次性写多个db。修改如下:
修改mongodb底下的MongoDbClient和AsyncMongoDbClient中关于insert、update、read函数实现
如下:
原来的实现:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
public final int update(final String table, final String key,
final HashMap<String, ByteIterator> values) {
try {
final MongoCollection collection = database.getCollection(table);
final DocumentBuilder query = BuilderFactory.start().add( "_id" , key);
final DocumentBuilder update = BuilderFactory.start();
final DocumentBuilder fieldsToSet = update.push( "$set" );
for (final Map.Entry<String, ByteIterator> entry : values.entrySet()) {
fieldsToSet.add(entry.getKey(), entry.getValue().toArray());
}
final long res =
collection.update(query, update, false , false , writeConcern);
return res == 1 ? 0 : 1;
} catch (final Exception e) {
System.err.println(e.toString());
return 1;
}
}
|
修改后:
1 |
public final int update( final String table, final String key, final HashMap<String, ByteIterator> values) {<br> // 对原来的update函数做修改,在每次update时都多做几次操作<br> int ret = updateOneTable(table, key, values);<br> if (ret != 0) {<br> return ret;<br> }<br> <br> for (int i = 0; i < TABLE_NUM; ++i) {<br> String tableName = table + String.valueOf(i);<br> ret = updateOneTable(tableName, key, values);<br> if (ret != 0) {<br> return ret;<br> }<br> } <br> <br> return 0; <br>} <br><br>public final int updateOneTable(final String table, final String key, final HashMap<String, ByteIterator> values) {<br> try { <br> final MongoCollection collection = database.getCollection(table);<br> final DocumentBuilder query = BuilderFactory.start().add("_id", key);<br> final DocumentBuilder update = BuilderFactory.start();<br> final DocumentBuilder fieldsToSet = update.push("$set");<br> <br> for (final Map.Entry<String, ByteIterator> entry : values.entrySet()) { <br> fieldsToSet.add(entry.getKey(), entry.getValue().toArray()); <br> }<br> <br> final long res = collection.update(query, update, false, false, writeConcern);<br> return res == 1 ? 0 : 1; <br> } catch (final Exception e) {<br> System.err.println(e.toString()); return 1; <br> } <br>}
|
其中TABLE_NUM可以根据实际需求进行设置(实际中,我们设置了该值为4,表示一次写5个table)
[OVERALL], RunTime(ms), 704740.0 #执行时间
[OVERALL], Throughput(ops/sec), 1418.9630218236514 #每秒操作数,吞吐量
[CLEANUP], Operations, 100.0
[CLEANUP], AverageLatency(us), 279.56
[CLEANUP], MinLatency(us), 0.0
[CLEANUP], MaxLatency(us), 27823.0
[CLEANUP], 95thPercentileLatency(us), 2.0
[CLEANUP], 99thPercentileLatency(us), 18.0
[INSERT], Operations, 50147.0 #insert操作数
[INSERT], AverageLatency(us), 69745.87736055996 #insert平均操作时间
[INSERT], MinLatency(us), 461.0 #insert 最小操作时间
[INSERT], MaxLatency(us), 3080191.0 #insert 最大操作时间
[INSERT], 95thPercentileLatency(us), 138623.0 #insert 95%操作时间
[INSERT], 99thPercentileLatency(us), 150911.0 #insert 99%操作时间
[INSERT], Return=OK, 50147 #insert 操作成功数
[READ], Operations, 949853.0
[READ], AverageLatency(us), 70395.02938033569
[READ], MinLatency(us), 262.0
[READ], MaxLatency(us), 3135487.0
[READ], 95thPercentileLatency(us), 138751.0
[READ], 99thPercentileLatency(us), 151039.0
[READ], Return=OK, 675134
[READ], Return=NOT_FOUND, 274719
【转】使用YCSB测试mongodb
标签:trie ttl 中间 性能 文件中 query lan order github