leveldb学习记录-YCSB测试
YCSB环境安装
昨天在服务器上安装YCSB的测试环境,用来测试leveldb的性能,跑一下实验。本篇博客主要做一个记录,方便日后查看。
ycsb英文全称为Yahoo! Cloud Serving Benchmark (YCSB) 。是Yahoo公司的一个用来对云服务进行基础测试的工具,leveldb的论文中实验测试评估这一章节,主要是采用提供的db_bench作为microbenchmark微基准测试工具,和YCSB作为macrobenchmarks宏基准测试工具,模仿实际的工作load。在运行YCSB的时候,可以配置不同的workload和DB,也可以指定线程数&并发数等其他参数。
主要参考博客:YCSB 测试 LevelDB 数据库
1.介绍
YCSB 是一种测试数据库的benchmark
它的使用原理是:
==A.== 目标数据库(待测试的数据库像Leveldb、Hbase等)作为服务端运行起来,并提供数据库操作相关的restful api,比如
1 | http://localhost:8080/put |
==B.== YCSB Client 作为客户端,通过restful api调用数据库,从而测试数据库的性能。
将leveldb数据库作为服务端运行起来
由于leveldb是不具有服务端的功能的,也就是无法提供数据库操作相关的restful api的。
因此,我们需要借助一个工具,simplehttp
和simpleleveldb
由于leveldb不提供restful api,此处借用的simpleleveldb却可以提供一套restful api与leveldb数据库连接起来。所以ycsb调用restful api就会首先调用simpleleveldb提供的相关操作,然后simpleleveldb再调用leveldb的put、get等操作。所以simpleleveldb就起到一个中间件的作用,将ycsb和leveldb连接起来。
先用git命令获得simplehttp
1 | git clone https://github.com/bitly/simplehttp.git |
接着安装simpleleveldb
首先进入你的leveldb数据库的源码文件夹,编译并拷贝至shared libraries folder
1 | cd leveldb |
其次安装依赖库 JSON :
1 | sudo apt install libjson-c-dev |
由于simplehttp/simpleleveldb源码中,include的路径有错误,需要稍微改动一下源码,把json
改为json-c
1 | 打开 simplehttp str_list_set.c修改 |
同时makefile文件中,对json库的引用也是错误的,-ljson应改为-ljson-c。
打开 makefile,将
LIBS = -L. -L$(LIBSIMPLEHTTP_LIB) -L$(LIBEVENT)/lib -L/usr/local/lib -L$(LIBLEVELDB)/lib -levent -ljson -lsimplehttp -lleveldb -lm -lstdc++ -lsnappy -lpthread
更改为
LIBS = -L. -L$(LIBSIMPLEHTTP_LIB) -L$(LIBEVENT)/lib -L/usr/local/lib -L$(LIBLEVELDB)/lib -levent -ljson-c -lsimplehttp -lleveldb -lm -lstdc++ -lsnappy -lpthread
其次安装依赖库Snappy
1 | sudo apt install libsnappy-dev |
安装依赖库Event
根据github的issure : https://github.com/bitly/simplehttp/issues/14
里面提到simplehttp目前仅与libevent 1.4兼容
所以libevent的版本必须是1.4版本!!!注意
进入网页下载 http://libevent.org/ 选择libevent 1.4.14b版本下载
tar解压之后输入以下命令
1 | cd libevent-1.4.14b-stable |
安装依赖库simplehttp (进入到 simplehttp/simplehttp):
1 | cd simplehttp |
安装 simpleleveldb
1 | cd simpleleveldb |
simpleleveldb 试运行
打开终端,输入
simpleleveldb --address=localhost --port=8080 --db-file=test
打开浏览器,地址栏输入
http://localhost:8080/put?key=name&value=Niko
然后会显示一段json,状态码是200
再输入
http://localhost:8080/get?key=name
会显示一个json,状态码是200,并且返回 Niko
至此,LevelDB的服务端就运行成功了!
后面就可以下载编译YCSB客户端,运行./ycsb做测试了
运行YCSB客户端
下载并编译YCSB客户端:
1 | git clone https://github.com/jtsui/ycsb-leveldb.git |
在输入mvn -pl com.yahoo.ycsb:leveldb-binding -am clean package
命令,由于需要使用jdk环境,而由于ubuntu16.04自带了开源版本openjdk8,不知道为什么还是会报错,找不到java的compiler。故我又重新安装了jdk8.
安装java开发环境jdk8
下载完安装包后解压得到jdk1.8.0_271文件夹,将其放在/opt目录下
在/bin目录下创建java软链接
1 | cd /bin |
验证软链接的正确性。
修改环境变量
输入下面的命令打开环境变量配置文件:
1 | sudo vi ~/.bashrc |
在最末尾添加如下内容(其中的jdk1.8.0_271是我安装的版本,如果你的版本不是jdk1.8.0_271,则需要修改一下):
1 | export JAVA_HOME=/opt/jdk1.8.0_271 |
保存并退出,使用source命令使之生效:
1 | source ~/.bashrc |
最后输入java -version查看是否安装成功
至此,安装成功!
之后再输入mvn -pl com.yahoo.ycsb:leveldb-binding -am clean package
就不会再报错啦!!!
现在就可以正式运行YCSB客户端测试数据库了,请注意,应该先启动LevelDB的服务端。
1 | ./ycsb load leveldb -P workloads/workloada |
上面的实例是采用wordload a。ycsb还提供了workload a、b、c、d、e。
Running the ycsb
command without any argument will print the usage.运行不带任何参数的ycsb命令可以打印用法。
1 | Usage: ./ycsb command database [options] |
有关如何运行工作负载的详细文档,请参阅https://github.com/brianfrankcooper/YCSB/wiki/Running-a-Workload。
运行工作负载有6个步骤:
1、设置要测试的数据库
2、选择合适的DB接口层
3、选择合适的工作负载
4、选择合适的运行时参数(客户机线程数、目标吞吐量等)
5、load 数据
6、执行工作负载
这里描述的步骤假设您运行的是单个客户机服务器。这对于小型到中型集群(例如10台左右的机器)应该足够了。
step1、设置要测试的数据库
我们采用的就是LevelDB
step2、选择合适的DB接口层
DB接口层是一个java类,它将YCSB客户机生成的读、插入、更新、删除和扫描调用执行到针对数据库API的调用中。这个类是com.yahoo中的抽象DB类的子类。ycsb包。您将在运行YCSB客户机时在命令行上指定层的类名,客户机将动态加载您的接口类。命令行上或命令行上指定的参数文件中指定的任何属性都将传递给DB接口实例,并可用于配置层(例如,告诉它您正在进行基准测试的数据库的主机名)。
YCSB客户端带有一个简单的虚拟接口层com.yahoo.ycsb.BasicDB。这一层只是将它将要执行的操作打印到System.out。它对于确保客户机正常运行和调试工作负载非常有用。
您可以使用
ycsb
命令直接对数据库运行命令。这个客户端使用DB接口层向数据库发送命令。您可以使用这个客户机来确保DB层正常工作,数据库设置正确,DB层可以连接到数据库,等等。它还为各种数据库提供了一个公共接口,并可用于检查数据库中的数据。
1 | $ ./bin/ycsb shell basic |
step3、选择合适的工作负载
工作负载定义在load阶段将load到数据库中的数据,以及在事务transaction
阶段将对数据集执行的操作。
a workload is a combination of:
- Workload java类(com.yahoo.ycsb.Workload的子类)
- 参数文件(Java属性格式)
在运行ycsb命令时指定的参数 是load还是run,确定是load阶段还是run阶段
step4、选择合适的运行时参数(客户机线程数、目标吞吐量等)
尽管workload类和参数文件定义了特定的工作负载,但是您可能希望为基准测试的特定运行指定其他设置。当您运行YCSB客户端时,这些设置在命令行中提供。包括以下选项:
-threads
:客户端线程数,ycsb客户端默认是使用单个工作线程。-target
:每秒的目标操作数。默认情况下,YCSB客户端将尝试执行尽可能多的操作。例如,如果每个操作平均花费100毫秒,客户端将在每个工作线程上每秒执行10个操作。但是,您可以限制每秒操作的目标数量。例如,要生成延迟与吞吐量曲线,您可以尝试不同的目标吞吐量,并测量每个目标吞吐量的结果延迟。-s
:status,对于长期运行的工作负载,让客户机报告状态可能是有用的,这只是为了确保它没有崩溃,并让您了解它的进度。通过在命令行中指定“-s”,客户端将每10秒向stderr报告一次状态。
step5、load数据
工作负载有两个可执行阶段:load阶段(定义要插入的数据)和事务阶段(定义要对数据集执行的操作)。要加载数据,您需要运行YCSB客户机并告诉它执行加载部分。
输入以下命令./ycsb load leveldb -P workloads/workloada
-p参数是用来load属性文件的,此处使用它来加载workload参数文件
step6、执行工作负载
./ycsb run leveldb -P workloads/workloada
运行结束时,客户机将报告stdout上的性能统计数据。默认情况下,为每个操作类型(读取、更新等)生成平均、最小、最大、第95和99百分位延迟,每个操作的返回代码计数,以及每个操作的延迟柱状图。返回代码由数据库接口层定义,允许您查看工作负载期间是否有任何错误。
这个输出显示:
- 总的执行时间是3.799s
- 平均吞吐为263.2ops/s
- 有491个update操作,以及相关的平均、最小、最大、95和99百分位延迟
- 所有491次update操作的返回码都为0(在本例中是成功的)
- xxx个操作在不到1毫秒内完成,xx个操作在1至2毫秒内完成。
YCSB的核心属性
所有工作负载文件都可以指定以下属性:
- workload: 要使用的工作负载类别(例如com.yahoo.ycsb.workloads.CoreWorkload)
- recordcount: 工作负载开始时数据集 中的record数量。默认1000
- operationcount: 工作负载中要执行的操作数量 (default: 1000)
- db: 使用的数据库,也可以在命令行上指定 (default: com.yahoo.ycsb.BasicDB)
- exporter: measurements exporter class to use要使用的测量结果的输出类 (default: com.yahoo.ycsb.measurements.exporter.TextMeasurementsExporter)
- exportfile: path to a file where output should be written instead of to stdout 用于替代stdout的输出文件路径(default: undefined/write to stdout)
- threadcount: YCSB客户端线程数. Alternatively this may be specified on the command line. (default: 1)
- measurementtype: supported measurement types are hdrhistogram, 支持的测量结果类型有直方图和时间序列 (default: hdrhistogram)
核心工作负载包属性
- fieldcount: the number of fields in a record (default: 10)
- fieldlength: the size of each field (default: 100)
- minfieldlength: the minimum size of each field (default: 1)
- readallfields: should reads read all fields (true) or just one (false) (default: true)
- writeallfields: should updates and read/modify/writes update all fields (true) or just one (false) (default: false)
- readproportion: 读操作的比例 (default: 0.95)
- updateproportion: 更新操作的比例 (default: 0.05)
- insertproportion: 插入操作的比例 (default: 0)
- scanproportion: scan操作的比例(default: 0)
- readmodifywriteproportion: 读-修改-写一条记录的操作比例 (default: 0)
- requestdistribution: 选择要操作的记录的分布– uniform(均匀), zipfian, hotspot, sequential, exponential or latest (default: uniform)
- minscanlength: for scans, what is the minimum number of records to scan (default: 1)
- maxscanlength: scan操作遍历的最大记录数,for scans, what is the maximum number of records to scan (default: 1000)
- scanlengthdistribution: 对于scan,应该使用哪个分布来选择要scan的记录数量, for each scan, between 1 and maxscanlength (default: uniform)
- insertstart: for parallel loads and runs, defines the starting record for this YCSB instance (default: 0)
- insertcount: for parallel loads and runs, defines the number of records for this YCSB instance (default: recordcount)
- zeropadding: for generating a record sequence compatible with string sort order by 0 padding the record number. Controls the number of 0s to use for padding. (default: 1)
For example for row 5, with zeropadding=1 you get ‘user5’ key and with zeropading=8 you get ‘user00000005’ key. In order to see its impact, zeropadding needs to be bigger than number of digits in the record number. - insertorder: 记录是否应该有序插入(ordered),或者是哈希顺序(hashed) (default: hashed)
- fieldnameprefix: what should be a prefix for field names, the shorter may decrease the required storage size (default: “field”)
测量结果属性
这些属性被应用于每一个测量结果类型:
直方图
- histogram.buckets:直方图输出的区间数(默认:1000)
时间序列
- timeseries.granularity:时间序列输出的粒度(默认:1000)
YCSB六个核心工作负载
Workload | Description |
---|---|
YCSB A | write-intensive: 50% updates, 50% reads |
YCSB B | read-intensive: 5% updates, 95% reads |
YCSB C | read-only: 100% reads |
YCSB D | read-latest: 5% updates, 95% reads |
YCSB E | scan-intensive: 5% updates, 95% scans; average scan length 50 elements |
YCSB F | 50% read-modify-write, 50% reads |