• 使用YCSB测试mongodb


    项目里面需要对mongodb的性能进行测试,看了下网上很多做法都是使用YCSB进行测试,因此开始学习使用YCSB。 

    参考资料:

    1. YCSB github地址:https://github.com/brianfrankcooper/YCSB 
    2. wiki: https://github.com/brianfrankcooper/YCSB/wiki 
    3. 安装参考:https://github.com/brianfrankcooper/YCSB/tree/master/mongodb 
    4. 之前的一些测试经验:http://www.sdpnosql.net/index.php/archives/3/    http://www.sdpnosql.net/index.php/archives/13/

    1 安装

    基于参考文档(https://github.com/brianfrankcooper/YCSB/tree/master/mongodb )安装java,mvn,ycsb 
    基本上安装了python(2.7.5版本以上),java(需要是jdk,而不是jre),mvn和ycsb之后就可以了

    1.1 YCSB目录结构

    安装好YCSB之后,查看YCSB目录如下:

    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类

    2 使用

    ycsb在执行的时候,分为两阶段:load阶段 和 transaction阶段

    2.1 load阶段

    该阶段主要用于构造测试数据,ycsb会基于参数设定,往db里面构造测试需要的数据,如:

    ./bin/ycsb load mongodb-async -s -P workloads/workloada > outputLoad.txt

    mongodb-async

    在ycsb中,对于不同的db都有一些选项,比如mongo就有mongodb 和 mongodb-async。 
    默认的mongodb表示同步,即load和run使用同步的方式,ycsb会调用mongodb/src底下对应的MongodbClient实现对应的insert/update等操作。如果设置了mongodb-async,ycsb会调用mongodb/src底下对应的AsyncMongoDbClient.java实现

    参数设置:

    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) // 客户端线程数

    参数解读:

    -P workload文件

    在ycsb的目录下有多种workload,参考:https://github.com/brianfrankcooper/YCSB/wiki/Core-Workloads,我们以workloada举例子 
    基础配置:

    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配置,如下:

    mongodb.url=mongodb://192.168.137.10:34001/ycsb?  # mongodb对应的uri等
    mongodb.database=ycsb # 对应的db
    mongodb.writeConcern=normal # 写级别

    -p选项

    -p用于设置一些对应的参数,如果workload中的参数,也可以以-p的方式放在命令行中设置

    -s

    -s是表示,在运行中,把一些状态打印到stderr中,一般status信息,用于表示在运行中的一些中间状态(比如当前处理了多少请求,还有多少请求等)

    -target n

    表示1s中总共的操作次数(各个线程加起来的),如果性能不满足,比如最高性能只有100,你设置了1000,那么ycsb会尽量往这个数目去靠近。默认是不做限制

    -thread 线程数

    设置ycsb client的并发测试线程数,默认是1,单线程,所以再测试的时候,一定要设置这个选项

    2.2 transcation阶段

    在2.1load数据结束之后,ycsb就可以进行测试了,也就是transaction阶段。在transaction阶段,会基于workload中的比例设置,和线程参数设置进行db的压测。具体参数如上

    3 一些自定义操作

    由于这次在使用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函数实现
    如下:
    原来的实现:
    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;
        }
    }
    修改后:
    public final int update(final String table, final String key, final HashMap<String, ByteIterator> values) {
    // 对原来的update函数做修改,在每次update时都多做几次操作
    int ret = updateOneTable(table, key, values);
    if (ret != 0) {
    return ret;
    }

    for (int i = 0; i < TABLE_NUM; ++i) {
    String tableName = table + String.valueOf(i);
    ret = updateOneTable(tableName, key, values);
    if (ret != 0) {
    return ret;
    }
    }

    return 0;
    }

    public final int updateOneTable(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;
    }
    }

    其中TABLE_NUM可以根据实际需求进行设置(实际中,我们设置了该值为4,表示一次写5个table)

  • 相关阅读:
    [轉][Windows] 已啟用Win7遠端桌面,從家中連回去卻無法連線?
    [轉]False SQL Injection and Advanced Blind SQL Injection
    SQL Injection with INFORMATION_SCHEMA (Mysql)
    Exploiting hard filtered SQL Injections
    Mysql 5 以上有内置库 information_schema,存储着mysql的所有数据库和表结构信息
    12个月内自学完成4年麻省理工学院计算机科学的33门课程的scotthyoung所谓的超速学习理论&方法(费曼技巧)?
    SQLi filter evasion cheat sheet (MySQL)
    [轉]字符形注入
    [轉]渗透测试必备Firefox全套渗透装
    Phpexcel範例
  • 原文地址:https://www.cnblogs.com/SailorXiao/p/5808828.html
Copyright © 2020-2023  润新知