开发者社区> 技术小胖子> 正文
阿里云
为了无法计算的价值
打开APP
阿里云APP内打开

mongodb+分片集群+ycsb测试一例

简介:
+关注继续查看

简介

mongodb是很出名的nosql数据库了,属于集合-文档型的特有架构nosql数据库,也是被誉为最像关系型数据库的非关系型数据库,但是不支持事务.

由于mongodb原生就支持分布式架构,所以部署简单,灵活,可伸缩,自动平衡数据结构等优点,继而性能也非常高.所以搭建mongodb来使用的公司,90%都会使用到mongodb集群.

YCSB是Yahoo开发的一个专门用来对新一代数据库进行基准测试的工具。全名是Yahoo! Cloud Serving Benchmark。包括支持的数据库有:cassandra, hbase,mongodb,redis等数据库.YCSB的几大特性:

  1. 支持常见的数据库读写操作,如插入,修改,删除及读取

  2. 多线程支持。YCSB用Java实现,有很好的多线程支持。

  3. 灵活定义场景文件。可以通过参数灵活的指定测试场景,如100%插入, 50%读50%写等等

  4. 数据请求分布方式:支持随机,zipfian(只有小部分的数据得到大部分的访问请求)以及最新数据几种请求分布方式

  5. 可扩展性:可以通过扩展Workload的方式来修改或者扩展YCSB的功能


安装mongodb

个人建议直接装二进制版本就算了,方便简单,编译版就显得略麻烦了.

现在mongodb最新的正式版本是3.6的,个人觉得太新,这编文章测试用的还是3.2的版本,还请各位知照.

总下载地址:


https://www.mongodb.com/download-center?jmp=nav#community


记得是选择community server的版本,然后选取你的操作系统和系统的版本(我这里是rhel的linux),他只显示最新版的下载地址,你要下旧版就要点下面的All Version Binaries.

1.png

然后就有一堆地址,你自己选择需要的版本吧,例如我要下的是这个地址.

1
2
#在linux下用wget下载
wget http://downloads.mongodb.org/linux/mongodb-linux-x86_64-rhel70-3.2.18.tgz?_ga=2.240790083.1507844543.1517391237-2141045386.1517391237

下载完成,就开始安装了,因为是二进制版的,很简单就是了.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#先安装下依赖包,因为他是用c写的,主要就是C的东西了
yum -y install gcc gcc-c++ glibc glibc-devel glib2 glib2-devel 
#解压压缩包
tar xf mongodb-linux-x86_64-rhel70-3.2.18.tgz
#把压缩包放到安装目录
mv mongodb-linux-x86_64-rhel70-3.2.18 /usr/local/
#创建安装目录的软连接
ln -sf /usr/local/mongodb-linux-x86_64-rhel70-3.2.18/ /usr/local/mongodb
#创建命令文件的软连接,那就不用加到环境变量了
ln -sf /usr/local/mongodb/bin//usr/bin/
#创建用户
useradd mongodb
#创建数据目录文件夹
mkdir -p /data/mongodb/data
#更改文件夹属主权限
chown -R mongodb:mongodb /data/mongodb/

这就安装完成了,后面就是初始化数据库了,初始化之前,必须先有配置文件,二进制版本安装的程序是不带配置文件模板的,所以就要自己编辑了,配置文件存放的位置可以随意,因为启动是需要指定位置的,例如下面这个:

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
33
34
35
36
#编辑配置文件,并指定位置
vim /usr/local/mongodb/mongod_data_40001.conf
#数据目录
dbpath=/data/mongodb/data
#日志文件
logpath=/data/mongodb/data/mongodb_data.log
#日志追加
logappend=true
#端口
port = 40001
#绑定ip,可以限制IP登录,不配置就是允许所有ip登入
#bind_ip = 10.21.1.208
#最大连接数
maxConns=200
pidfilepath = /data/mongodb/data/mongo_40001.pid
#日志,redo log
journal = true
#刷写提交机制
journalCommitInterval = 200
#守护进程模式,也可以叫后台启动
fork = true
#刷写数据到日志的频率
syncdelay = 60
#storageEngine = wiredTiger
#操作日志,单位M
oplogSize = 1000
#命名空间的文件大小,默认16M,最大2G。
nssize = 16
noauth = true
unixSocketPrefix = /tmp
#是否config端,做集群的配置端使用,后面详细介绍,这里不需要
#configsvr = true
#指定认证文件,没开认证就不用指定,注释关闭即可
#keyFile  = /data/mongodb/data/keyfile
#是否开启认证模式,不开就不用用户名密码就能登录数据库,测试环境可以不开
#auth = true

配置文件有了,就可以初始化启动了,因为我没有开启认证模式,启动就可以使用了.

1
2
3
4
5
6
7
8
9
10
11
12
13
#开启mongodb的数据端
mongod -f /usr/local/mongodb/mongod_data_40001.conf
about to fork child process, waiting until server is ready for connections.
forked process: 15808
child process started successfully, parent exiting
#来测试一下
mongo --port=40001
MongoDB shell version: 3.2.18
connecting to: 127.0.0.1:40001/test
Server has startup warnings: 
2018-01-31T11:12:12.537+0800 I CONTROL  [initandlisten] 
> show dbs
local   0.000GB

然后,这个mongodb数据库就可以正常使用的了,当然,我们不是只使用单台mongodb,开头也说了,90%的公司,使用mongodb都是会使用到集群,后面来看怎么搭建分片集群.


搭建mongodb分片集群

先来介绍一下架构,需要三个角色,

  1. 配置服务器,config端,需要1台或3台,不能是双数,保存集群和分片的元数据,即各分片包含了哪些数据的信息,配置文件指定configsvr选项.

  2. 路由服务器,router端,随便多少台都行,本身不保存数据,在启动时从配置服务器加载集群信息,开启mongos进程需要知道配置服务器的地址,指定configdb选项.也可以理解为代理端

  3. 分片服务器,sharding端,保存真实数据信息,可以是一个副本集也可以是单独的一台服务器,支持主从故障切换.也可以叫数据端.

总共有8台机器,配置是8核16G的虚拟机.

10.21.1.205    config端(1)+router端(1)

10.21.1.206    sharding端(1)

10.21.1.207    sharding端(1)

10.21.1.208    sharding端(1)

10.21.1.209    sharding端(1)

10.21.1.210    sharding端(1)

10.21.1.211    sharding端(1)

10.21.1.212    sharding端(1)

由于是测试环境,不想纠结太复杂,config端和router端都是一台,当启动router端的时候会抛出一个警告,"只有一台config端的集群建议只用来测试",是的,我就是用来做测试.

sharding端我不打算详细说了,就按照上面安装mongodb的方式去操作并启动就ok,不需要额外的配置,只需要等配置端把他们地址加载就可以,然后就会自动连接并分配数据块起来,暂时也不需要研究其他东西.就是需要一台台去装就比较麻烦一点,各位自行操作.


1.配置并启动config端:

配置服务器也是一个mongod进程,其实也可以按照上面的配置文件来,配置服务器必须开启1个或则3个,开启2个则会报错,

1
BadValue need either 1 or 3 configdbs

所以要注意数量,这里我就设一个就算了.

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
#也和上面一样,没有模板,只能自己编辑
vim /usr/local/mongodb/mongod_config_20000.conf
#数据目录,目录名字区分于数据节点
dbpath=/data/mongodb/config/
#日志文件
logpath=/data/mongodb/mongodb_config.log
#日志追加
logappend=true
#端口
port = 20000
#最大连接数
maxConns = 300
pidfilepath = /data/mongodb/mongo_20000.pid
#日志,redo log
journal = true
#刷写提交机制
journalCommitInterval = 200
#守护进程模式
fork = true
#刷写数据到日志的频率
syncdelay = 60
#storageEngine = wiredTiger
#操作日志,单位M
oplogSize = 1000
#命名空间的文件大小,默认16M,最大2G。
nssize = 16
noauth = true
#套接字存放位置
unixSocketPrefix = /tmp
#是否config端,这里当然是了
configsvr = true

其实和上面只是多了最后一行,标记是config端而已,然后启动.

1
2
3
4
5
#启动config端
mongod -f /usr/local/mongodb/mongod_config_20000.conf
about to fork child process, waiting until server is ready for connections.
forked process: 18535
child process started successfully, parent exiting

这里就不需要测试了,因为不需要在这里控制config端,然后看router端.



2.配置并启动router端:

路由服务器本身不保存数据,把日志记录一下即可,他都是直接调用config端来使用.而所有客户端程序想要连接mongodb集群,其实就是连接这个router端的端口来使用,并不是连接config端和sharding端,所以也说是类似于代理的形式.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#也和上面一样,没有模板,只能自己编辑
vim /usr/local/mongodb/mongos_route_30000.conf
#日志文件
logpath=/data/mongodb/mongodb_route.log
#日志追加
logappend=true
#端口
port = 30000
#最大连接数
maxConns = 300
#绑定地址,可以限制IP登录,不配置就是允许所有ip登入
#bind_ip=10.21.1.205
pidfilepath = /data/mongodb/mongo_30000.pid
configdb = 10.21.1.205:20000
#必须是1个或则3个配置 。例如:
#configdb=10.21.1.205:20000,10.21.1.205:20001,10.21.1.205:20002
#但是不能使用127.0.0.1,不然就报错
#configdb=127.0.0.1:20000
#守护进程模式 
fork = true

最重要的参数是configdb,指定config端的地址,可以1个或3个,但是不能在其后面带的配置服务器的地址写成localhost或则127.0.0.1,需要设置成其他分片也能访问的地址,即10.21.1.205:20000/20001/20002。否则在添加分片地址的时候会报错.

然后是启动:

1
2
3
4
5
6
#启动方式略有不同,要使用mongos
mongos -f /usr/local/mongodb/mongos_route_30000.conf
2018-02-01T10:27:26.604+0800 W SHARDING [main] Running a sharded cluster with fewer than 3 config servers should only be done for testing purposes and is not recommended for production.
about to fork child process, waiting until server is ready for connections.
forked process: 6355
child process started successfully, parent exiting

启动完成后会看到个警告,不过这里可以忽略,就是我开头说的,提示你只有一台config的话只建议用来测试.原因就是这台config存储的是各分片的数据块信息,假如这台config挂了,那么各分片之间的数据块就不知道怎么关联了,是一个非常大的安全隐患,所以生产环境一定要保证有3台,最好还是错开在不同的服务器上面,提高安全性.


3.添加删除配置分片信息

按上面的步骤启动完毕,那就可以开始配置分片了,当然,前提就是那些sharding端都已经全部部署启动完毕.然后,就登录进去操作了:

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
#使用客户端像一般登录mongodb那样操作,这里没有认证
mongo --port=30000 --host=10.21.1.205
MongoDB shell version: 3.2.18
connecting to: 10.21.1.205:30000/test
Server has startup warnings: 
2018-02-01T10:27:26.619+0800 I CONTROL  [main] 
mongos>
#看看现在的状态,现在当然是什么也没有
mongos>sh.status()
--- Sharding Status --- 
  sharding version: {
      "_id" : 1,
      "minCompatibleVersion" : 5,
      "currentVersion" : 6,
      "clusterId" : ObjectId("5a69925ee61d3e7c0519035a")
  }
  shards:
  active mongoses:
      "3.2.18" : 1
  balancer:
    Currently enabled:  yes
    Currently running:  no
    Failed balancer rounds in last 5 attempts:  0
    Migration Results for the last 24 hours: 
        No recent migrations
  databases:

然后,我们来添加分片,sh.addShard("IP:Port")

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
33
34
35
36
#添加分片,如此类推
mongos> sh.addShard("10.21.1.206:40001")
"shardAdded" "shard0000""ok" : 1 }
mongos> sh.addShard("10.21.1.207:40001")
"shardAdded" "shard0001""ok" : 1 }
mongos> sh.addShard("10.21.1.208:40001"
"shardAdded" "shard0002""ok" : 1 }
    .
    .
    .
#全部加完了,看看状态,
mongos>sh.status()
--- Sharding Status --- 
  sharding version: {
      "_id" : 1,
      "minCompatibleVersion" : 5,
      "currentVersion" : 6,
      "clusterId" : ObjectId("5a69925ee61d3e7c0519035a")
  }
  shards:
        {  "_id" "shard0000",  "host" "10.21.1.206:40001" }
        {  "_id" "shard0001",  "host" "10.21.1.207:40001" }
        {  "_id" "shard0002",  "host" "10.21.1.208:40001" }
        {  "_id" "shard0003",  "host" "10.21.1.209:40001" }
        {  "_id" "shard0004",  "host" "10.21.1.210:40001" }
        {  "_id" "shard0005",  "host" "10.21.1.211:40001" }
        {  "_id" "shard0006",  "host" "10.21.1.212:40001" }
  active mongoses:
        "3.2.18" : 1
  balancer:
    Currently enabled:  yes
    Currently running:  no
    Failed balancer rounds in last 5 attempts:  0
    Migration Results for the last 24 hours: 
        No recent migrations
  databases:

这个时候,7个分片都添加完毕,不过,现在还没有数据库,所以还要创建数据库和数据库的片键.创建数据库应该还能理解,片键是什么,下面来简单解析一下:

片键必须是一个索引,数据根据这个片键进行拆分分散。通过sh.shardCollection加会自动创建索引。一个自增的片键对写入和数据均匀分布就不是很好,因为自增的片键总会在一个分片上写入,后续达到某个阀值可能会写到别的分片。但是按照片键查询会非常高效。随机片键对数据的均匀分布效果很好。注意尽量避免在多个分片上进行查询。在所有分片上查询,mongos会对结果进行归并排序。也可以说是分片的规则字段了.

================================================================================

需要特别注意的一点是,有些mongodb是用root启动的,所以数据库的文件权限也是root,这样就可能会造成一种奇葩现象,连接不正常,数据异常等,所以我们要确保数据库文件权限是mongodb的.

1
2
3
4
5
6
7
8
#关闭mongodb
killall mongod
#删掉锁文件
rm -rf /data/mongodb/data/*.lock
#更改文件夹权限
chown mongodb:mongodb -R  /data/mongodb/*
#启动
mongod -f /usr/local/mongodb/mongod_data_40001.conf

当然是包括config端的了.

================================================================================

然后,我们就创建数据库并开启分片功能,一条命令就可以,最后再添加个片键就可以用了,命令是sh.enableSharding("库名")、sh.shardCollection("库名.集合名",{"key":1})

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#创建一个ycsb的数据库,并启动他的分片功能
mongos>sh.enableSharding("ycsb")
"ok" : 1 }
#添加这个数据库的片键为_id,规则是hash
mongos>sh.shardCollection("ycsb.usertable", {_id:"hashed"})
"collectionsharded" "ycsb.usertable""ok" : 1 }
###########################################
#假如你已经创建了一个,现在需要重建,那就要先删除旧的数据库了
#mongos> use ycsb
#switched to db ycsb
#mongos> db.dropDatabase()
#{ "dropped" : "ycsb", "ok" : 1 }
#mongos> show dbs
#config  0.013GB
###########################################

这样添加的原因是后面的ycsb测试工具的需要,他会生成一个名为ycsb的数据库,里面有一个usertable集合(表),然后其中有_id这个列,至于hash规则我想就不解析了.然后,在看看状态:

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
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
#看看现在的状态,很长
mongos>sh.status()
--- Sharding Status --- 
  sharding version: {
      "_id" : 1,
      "minCompatibleVersion" : 5,
      "currentVersion" : 6,
      "clusterId" : ObjectId("5a69925ee61d3e7c0519035a")
  }
  shards:
        {  "_id" "shard0000",  "host" "10.21.1.206:40001" }
        {  "_id" "shard0001",  "host" "10.21.1.207:40001" }
        {  "_id" "shard0002",  "host" "10.21.1.208:40001" }
        {  "_id" "shard0003",  "host" "10.21.1.209:40001" }
        {  "_id" "shard0004",  "host" "10.21.1.210:40001" }
        {  "_id" "shard0005",  "host" "10.21.1.211:40001" }
        {  "_id" "shard0006",  "host" "10.21.1.212:40001" }
  active mongoses:
        "3.2.18" : 1
  balancer:
        Currently enabled:  yes
        Currently running:  no
        Failed balancer rounds in last 5 attempts:  5
        Last reported error:  Connection refused
        Time of Reported error:  Thu Feb 01 2018 14:26:07 GMT+0800 (CST)
        Migration Results for the last 24 hours: 
  databases:
        {  "_id" "ycsb",  "primary" "shard0000",  "partitioned" true }
                ycsb.usertable
                        shard key: { "_id" "hashed" }
                        unique: false
                        balancing: true
                        chunks:
                                shard0000    2
                                shard0001    2
                                shard0002    2
                                shard0003    2
                                shard0004    2
                                shard0005    2
                                shard0006    2
                        "_id" : { "$minKey" : 1 } } -->> { "_id" : NumberLong("-7905747460161236400") } on : shard0000 Timestamp(7, 2) 
                        "_id" : NumberLong("-7905747460161236400") } -->> { "_id" : NumberLong("-6588122883467697000") } on : shard0000 Timestamp(7, 3) 
                        "_id" : NumberLong("-6588122883467697000") } -->> { "_id" : NumberLong("-5270498306774157600") } on : shard0001 Timestamp(7, 4) 
                        "_id" : NumberLong("-5270498306774157600") } -->> { "_id" : NumberLong("-3952873730080618200") } on : shard0001 Timestamp(7, 5) 
                        "_id" : NumberLong("-3952873730080618200") } -->> { "_id" : NumberLong("-2635249153387078800") } on : shard0002 Timestamp(7, 6) 
                        "_id" : NumberLong("-2635249153387078800") } -->> { "_id" : NumberLong("-1317624576693539400") } on : shard0002 Timestamp(7, 7) 
                        "_id" : NumberLong("-1317624576693539400") } -->> { "_id" : NumberLong(0) } on : shard0003 Timestamp(7, 8) 
                        "_id" : NumberLong(0) } -->> { "_id" : NumberLong("1317624576693539400") } on : shard0003 Timestamp(7, 9) 
                        "_id" : NumberLong("1317624576693539400") } -->> { "_id" : NumberLong("2635249153387078800") } on : shard0004 Timestamp(7, 10) 
                        "_id" : NumberLong("2635249153387078800") } -->> { "_id" : NumberLong("3952873730080618200") } on : shard0004 Timestamp(7, 11) 
                        "_id" : NumberLong("3952873730080618200") } -->> { "_id" : NumberLong("5270498306774157600") } on : shard0005 Timestamp(7, 12) 
                        "_id" : NumberLong("5270498306774157600") } -->> { "_id" : NumberLong("6588122883467697000") } on : shard0005 Timestamp(7, 13) 
                        "_id" : NumberLong("6588122883467697000") } -->> { "_id" : NumberLong("7905747460161236400") } on : shard0006 Timestamp(7, 14) 
                        "_id" : NumberLong("7905747460161236400") } -->> { "_id" : { "$maxKey" : 1 } } on : shard0006 Timestamp(7, 15) 
#看看有什么数据库
mongos> show dbs
config    0.007GB
ycsb      0.000GB
#登进目标数据库
mongos> use ycsb
switched to db ycsb
#查看数据库的状态
mongos> db.stats()
{
    "raw" : {
        "10.21.1.206:40001" : {
            "db" "ycsb",
            "collections" : 1,
            "objects" : 0,
            "avgObjSize" : 0,
            "dataSize" : 0,
            "storageSize" : 4096,
            "numExtents" : 0,
            "indexes" : 2,
            "indexSize" : 8192,
            "ok" : 1
        },
        "10.21.1.207:40001" : {
            "db" "ycsb",
            "collections" : 1,
            "objects" : 0,
            "avgObjSize" : 0,
            "dataSize" : 0,
            "storageSize" : 4096,
            "numExtents" : 0,
            "indexes" : 2,
            "indexSize" : 8192,
            "ok" : 1
        },
        "10.21.1.208:40001" : {
            "db" "ycsb",
            "collections" : 1,
            "objects" : 0,
            "avgObjSize" : 0,
            "dataSize" : 0,
            "storageSize" : 4096,
            "numExtents" : 0,
            "indexes" : 2,
            "indexSize" : 8192,
            "ok" : 1
        },
        "10.21.1.209:40001" : {
            "db" "ycsb",
            "collections" : 1,
            "objects" : 0,
            "avgObjSize" : 0,
            "dataSize" : 0,
            "storageSize" : 4096,
            "numExtents" : 0,
            "indexes" : 2,
            "indexSize" : 8192,
            "ok" : 1
        },
        "10.21.1.210:40001" : {
            "db" "ycsb",
            "collections" : 1,
            "objects" : 0,
            "avgObjSize" : 0,
            "dataSize" : 0,
            "storageSize" : 4096,
            "numExtents" : 0,
            "indexes" : 2,
            "indexSize" : 8192,
            "ok" : 1
        },
        "10.21.1.211:40001" : {
            "db" "ycsb",
            "collections" : 1,
            "objects" : 0,
            "avgObjSize" : 0,
            "dataSize" : 0,
            "storageSize" : 4096,
            "numExtents" : 0,
            "indexes" : 2,
            "indexSize" : 8192,
            "ok" : 1
        },
        "10.21.1.212:40001" : {
            "db" "ycsb",
            "collections" : 1,
            "objects" : 0,
            "avgObjSize" : 0,
            "dataSize" : 0,
            "storageSize" : 4096,
            "numExtents" : 0,
            "indexes" : 2,
            "indexSize" : 8192,
            "ok" : 1
        }
    },
    "objects" : 0,
    "avgObjSize" : 0,
    "dataSize" : 0,
    "storageSize" : 28672,
    "numExtents" : 0,
    "indexes" : 14,
    "indexSize" : 57344,
    "fileSize" : 0,
    "extentFreeList" : {
        "num" : 0,
        "totalSize" : 0
    },
    "ok" : 1
}

好了,至此,mongodb的分片集群已经搭建好,暂时还没有数据,objects显示是0就是没数据了,各分片也没有数据.

不过,有时候会因为信息太长而导致显示不全,并提示

1
too many chunks to print, use verbose if you want to force print

那么我们就要用下列命令来显示了,三个都可以,然后就显示全部了,但是更长.

1
2
3
mongos> sh.status({"verbose":1})
mongos> db.printShardingStatus("vvvv")
mongos> printShardingStatus(db.getSisterDB("config"),1)

======================================

最后来看删除分片,有添加,就当然有删除了,虽然不是这里的重点, db.runCommand({"removeshard":"mmm"})

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
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
#登进管理数据库admin,3.2隐藏了,不过确实存在.
mongos> use admin
switched to db admin
mongos> db
admin
#删除刚才添加的一个分片,注意state状态,是准备删除,将不会有新数据进入该分片
mongos> db.runCommand({"removeshard":"shard0006"})
{
    "msg" "draining started successfully",
    "state" "started",
    "shard" "shard0006",
    "note" "you need to drop or movePrimary these databases",
    "dbsToMove" : [ ],
    "ok" : 1
}
#这个时候,状态已经改变成draining,但是还没有删除,只是新数据不再写入进去
mongos> sh.status()
--- Sharding Status --- 
  sharding version: {
      "_id" : 1,
      "minCompatibleVersion" : 5,
      "currentVersion" : 6,
      "clusterId" : ObjectId("5a69925ee61d3e7c0519035a")
  }
  shards:
        {  "_id" "shard0000",  "host" "10.21.1.206:40001" }
        {  "_id" "shard0001",  "host" "10.21.1.207:40001" }
        {  "_id" "shard0002",  "host" "10.21.1.208:40001" }
        {  "_id" "shard0003",  "host" "10.21.1.209:40001" }
        {  "_id" "shard0004",  "host" "10.21.1.210:40001" }
        {  "_id" "shard0005",  "host" "10.21.1.211:40001" }
        {  "_id" "shard0006",  "host" "10.21.1.212:40001",  "draining" true }
  active mongoses:
        "3.2.18" : 1
  balancer:
        Currently enabled:  yes
        Currently running:  no
        Failed balancer rounds in last 5 attempts:  0
        Migration Results for the last 24 hours: 
    .
    .
    .
#再操作一次,这次将会完全删除,
#如果里面没数据,会显示state状态为completed,
mongos> db.runCommand({"removeshard":"shard0006"})
{
    "msg" "removeshard completed successfully",
    "state" "completed",
    "shard" "shard0006",
    "ok" : 1
}
#如果有数据,则会等到迁移完才会执行通过,取决于数据量多不多,显示state状态为ongoing
mongos> db.runCommand({"removeshard":"shard0006"})
{
        "msg" "draining ongoing",
        "state" "ongoing",
        "remaining" : {
                "chunks" : NumberLong(2128),
                "dbs" : NumberLong(0)
        },
        "note" "you need to drop or movePrimary these databases",
        "dbsToMove" : [ ],
        "ok" : 1
}
#删除完毕后,再次查看,id为shard0006的分片已经被删除,
mongos> sh.status()
--- Sharding Status --- 
  sharding version: {
      "_id" : 1,
      "minCompatibleVersion" : 5,
      "currentVersion" : 6,
      "clusterId" : ObjectId("5a69925ee61d3e7c0519035a")
  }
  shards:
        {  "_id" "shard0000",  "host" "10.21.1.206:40001" }
        {  "_id" "shard0001",  "host" "10.21.1.207:40001" }
        {  "_id" "shard0002",  "host" "10.21.1.208:40001" }
        {  "_id" "shard0003",  "host" "10.21.1.209:40001" }
        {  "_id" "shard0004",  "host" "10.21.1.210:40001" }
        {  "_id" "shard0005",  "host" "10.21.1.211:40001" }
  active mongoses:
        "3.2.18" : 1
  balancer:
        Currently enabled:  yes
        Currently running:  no
        Failed balancer rounds in last 5 attempts:  0
        Migration Results for the last 24 hours: 
    .
    .
    .
#这里显示也没有了该分片地址了
mongos> db.runCommand({ listshards : 1 })
{
    "shards" : [
        {
            "_id" "shard0000",
            "host" "10.21.1.206:40001"
        },
        {
            "_id" "shard0001",
            "host" "10.21.1.207:40001"
        },
        {
            "_id" "shard0002",
            "host" "10.21.1.208:40001"
        },
        {
            "_id" "shard0003",
            "host" "10.21.1.209:40001"
        },
        {
            "_id" "shard0004",
            "host" "10.21.1.210:40001"
        },
        {
            "_id" "shard0005",
            "host" "10.21.1.211:40001"
        }
    ],
    "ok" : 1
}

需要注意的是,不能同时删除两个或以上的分片,只有删除完一个后,另一个才可以开始删除.

另外,分片还有迁移功能,可以是整个迁移或迁移某一个块chunks(sh.moveChunk("db.collection",{块地址},"新片名称")),这里不打算展开来说,日常使用中,这种操作也基本上很少涉及,基本上都让均衡器balancer自己去跑就算了.

需要特别注意的是删除主分片,则需要先迁移走数据库到别的分片,

1
db.adminCommand({"movePrimary":"ycsb","to":"shard0001"})

这样才能删主分片.

======================================

安装删除都完成了,后面来看ycsb要怎么使用了.


搭建ycsb环境

ycsb程序本身是python+java的结合体,是不是很奇怪?主要测试的对象是nosql系列数据库:cassandra, hbase,mongodb,redis这些.程序本身也是二进制版,python其实yum一下也行了,主要就是java了.

由于java的下载地址经常变,包的容量也不少,所以就只给个官方总地址了,去下java se的包就可以了,虽然已经出了9,但是我还是觉得用8就算了.

http://www.oracle.com/technetwork/java/javase/downloads

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#安装python环境
yum install -y python python-devel
#安装java
tar xf jdk-8u144-linux-x64.tar.gz
mv jdk1.8.0_144/ /usr/local/ 
ln -sf /usr/local/jdk1.8.0_144/ /usr/local/jdk
#创建java环境变量
vim /etc/profile.d/java.sh
export JAVA_HOME=/usr/local/jdk
export JRE_HOME=/usr/local/jdk/jre
export CLASSPATH=.:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar:$JRE_HOME/lib
export PATH=$PATH:$JAVA_HOME/bin
#重载环境变量
source /etc/profile
#测试一下
java -version
java version "1.8.0_144"
Java(TM) SE Runtime Environment (build 1.8.0_144-b01)
Java HotSpot(TM) 64-Bit Server VM (build 25.144-b01, mixed mode)

前置的环境安装完毕,就来看怎么安装ycsb了,和java有点像,而且还不用做环境变量,其实我觉得也不能叫安装,直接解压就能用了,现在最新版本是ycsb-0.12.0

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
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
#下载ycsb
wget https://github.com/brianfrankcooper/YCSB/releases/download/0.12.0/ycsb-0.12.0.tar.gz
#解压
tar xf ycsb-0.12.0.tar.gz
#查看目录结构
ll ycsb-0.12.0
total 12
drwxr-xr-x. 4 root root    46 Jan 30 11:23 accumulo-binding
drwxr-xr-x. 3 root root    34 Jan 30 11:23 aerospike-binding
drwxr-xr-x. 3 root root    34 Jan 30 11:23 arangodb-binding
drwxr-xr-x. 3 root root    34 Jan 30 11:23 asynchbase-binding
drwxr-xr-x. 3 root root    34 Jan 30 11:23 azuretablestorage-binding
drwxr-xr-x. 2 root root    76 Feb  1 18:01 bin
drwxr-xr-x. 3 root root    34 Jan 30 11:23 cassandra-binding
drwxr-xr-x. 3 root root    34 Jan 30 11:23 couchbase2-binding
drwxr-xr-x. 3 root root    34 Jan 30 11:23 couchbase-binding
drwxr-xr-x. 3 root root    34 Jan 30 11:23 dynamodb-binding
drwxr-xr-x. 3 root root    34 Jan 30 11:23 elasticsearch-binding
drwxr-xr-x. 3 root root    34 Jan 30 11:23 geode-binding
drwxr-xr-x. 3 root root    34 Jan 30 11:23 googlebigtable-binding
drwxr-xr-x. 3 root root    34 Jan 30 11:23 googledatastore-binding
drwxr-xr-x. 3 root root    34 Jan 30 11:23 hbase094-binding
drwxr-xr-x. 3 root root    34 Jan 30 11:23 hbase098-binding
drwxr-xr-x. 3 root root    34 Jan 30 11:23 hbase10-binding
drwxr-xr-x. 3 root root    34 Jan 30 11:23 hypertable-binding
drwxr-xr-x. 4 root root    46 Jan 30 11:23 infinispan-binding
drwxr-xr-x. 4 root root    46 Jan 30 11:23 jdbc-binding
drwxr-xr-x. 4 root root    46 Jan 30 11:23 kudu-binding
drwxr-xr-x. 2 root root   170 Jan 30 11:23 lib
-rw-r--r--. 1  501 games 8082 Jan 21  2015 LICENSE.txt
drwxr-xr-x. 3 root root    34 Jan 30 11:23 memcached-binding
drwxr-xr-x. 3 root root    34 Jan 30 11:23 mongodb-binding
drwxr-xr-x. 4 root root    46 Jan 30 11:23 nosqldb-binding
-rw-r--r--. 1  501 games  615 Sep 27  2016 NOTICE.txt
drwxr-xr-x. 3 root root    34 Jan 30 11:23 orientdb-binding
drwxr-xr-x. 3 root root    34 Jan 30 11:23 rados-binding
drwxr-xr-x. 3 root root    34 Jan 30 11:23 redis-binding
drwxr-xr-x. 3 root root    34 Jan 30 11:23 rest-binding
drwxr-xr-x. 3 root root    34 Jan 30 11:23 riak-binding
drwxr-xr-x. 4 root root    46 Jan 30 11:23 s3-binding
drwxr-xr-x. 3 root root    34 Jan 30 11:23 solr6-binding
drwxr-xr-x. 3 root root    34 Jan 30 11:23 solr-binding
drwxr-xr-x. 4 root root    46 Jan 30 11:23 tarantool-binding
drwxr-xr-x. 2  501 games  183 Feb  2 11:19 workloads
#和一般程序差不多,bin目录就是命令目录了
ll /opt/ycsb-0.12.0/bin/
total 36
-rw-r--r--. 1 501 games  2672 Nov  1  2016 bindings.properties
-rwxr-xr-x. 1 501 games 12572 Nov  1  2016 ycsb
-rwxr-xr-x. 1 501 games  6431 Sep 30  2016 ycsb.bat
-rwxr-xr-x. 1 501 games  7458 Sep 30  2016 ycsb.sh

其他目录暂时就不研究,不过从字面意思可以理解一些,其实就是各种数据库的驱动.后面来看怎么使用了.


使用ycsb

1.使用简介

使用前,我们要先了解他的命令结构,我们才能知道怎么做才能达到效果.有点类似于测试mysql数据库的sysbench

1
bin/ycsb load/run/shell mongodb/hbase10/basic.. mongodb.url="mongodb://user:pwd@server1.example.com:9999" -P workloads/workloada -s

第一项,bin/ycsb,就不用解析了,就是命令本身.

第二项,load/run/shell,指定这个命令的作用,加载数据/运行测试/交互界面,类似sysbench

第三项,mongodb/hbase10/basic..指定这次测试使用的驱动,也就是这次究竟测的是什么数据库,有很多选项,可以ycsb --help看到所有

第四项,mongodb.url,指定测试的数据库的认证信息,地址端口和用户密码,这里拿的是mongodb的来做演示

第五项,-P workloads/workloada,指定测试的参数文件,默认有6种测试模板,加一个大模板,都可以vim打开来看,大致为:

    workloada:读写均衡型,50%/50%,Reads/Writes

    workloadb:读多写少型,95%/5%,Reads/Writes

    workloadc:只读型,100%,Reads

    workloadd:读最近写入记录型,95%/5%,Reads/insert

    workloade:扫描小区间型,95%/5%,scan/insert

    workloadf:读写入记录均衡型,50%/50%,Reads/insert

    workload_template:参数列表模板

第六项,-s,每10秒打印报告一次到屏幕,可以ycsb --help看到


2.测试参数解析

看了上面的解析,就可以看出来,问题的重点是第五项,-P workloads/workloada,这里编辑好,那压测效果才会出来,那么里面有些什么呢,西面来看看:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#打开这个文件来看
vim workloads/workloada
#YCSB load(加载元数据)命令的参数,默认值1000表示默认加载的记录条数,可以在命令行显示修改该值(后面介绍)。
recordcount=1000
#YCSB run(运行压力测试)命令的参数,默认值1000表示默认选取数据库中的1000条数据进行压力测试。对于workloada这种测试场景,就意味着读数据在500左右,写数据也在500左右
operationcount=1000
#指定了workload的实现类为 com.yahoo.ycsb.workloads.CoreWorkload
workload=com.yahoo.ycsb.workloads.CoreWorkload
#表示查询时是否读取记录的所有字段
readallfields=true
#表示读操作的比例,该场景为0.5,即50%
readproportion=0.5
#表示更新操作的比例,该场景为0.5,即50%
updateproportion=0.5
#表示扫描操作的比例,即0%
scanproportion=0
#表示插入操作的比例,即0%
insertproportion=0
#表示请求的分布模式,YCSB提供uniform, zipfian, latest三种分布模式
requestdistribution=zipfian

还有一些参数没列出,然后我们得出自己需要的参数文件,这个是100%纯插入1亿条记录的参数文件,如下所示:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#100%纯插入的参数文件
vim workloads/mongotest_in_only
#定个小目标,比如1个亿,插入1亿条文档数据
recordcount=100000000
operationcount=100000000
workload=com.yahoo.ycsb.workloads.CoreWorkload
readallfields=true
readproportion=0
updateproportion=0
scanproportion=0
#只有插入的操作,1就是100%
insertproportion=1
requestdistribution=uniform
#插入文档的顺序:哈希/随机 (insertorder),这里是哈希
insertorder=hashed
fieldlength=250
fieldcount=8
#把数据库连接地址写到这里,那么输命令的时候就不用输地址了,我这里没有设用户名密码,当然是不需要了
mongodb.url=mongodb://10.21.1.205:30000/ycsb?w=0
#MongoDB的写安全设置(mongodb.writeConcern)是acknowledged
mongodb.writeConcern=acknowledged
#线程数,也就是说100个并发
threadcount=100

每个文档大小大约2KB(fieldlength x fieldcount),数据总大小大概是200G+12G的索引,数量还是比较多,如果是单点,估计是比较难撑,查询也超级慢.但是做了分片的话,程序会自动分配,把他们平均分配到每一个分片中,那么压力就减轻很多了,分布式架构的优势出来了.


3.执行纯插入测试

上面我自己写的配置文件,就是为了做插入测试,总共7个分片,插入1亿条数据,花了两个多小时,看来时间还是要预足够.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#执行下面命令进行插入测试
bin/ycsb load mongodb -P workloads/mongotest_in_only -s > /home/logs/mongo_ycsb20180131-1.log &
/usr/local/jdk/bin/java -cp /opt/ycsb-0.12.0/mongodb-binding/conf:/opt/ycsb-0.12.0/conf:/opt/ycsb-0.12.0/lib/core-0.12.0.jar:/opt/ycsb-0.12.0/lib/htrace-core4-4.1.0-incubating.jar:/opt/ycsb-0.12.0/lib/jackson-mapper-asl-1.9.4.jar:/opt/ycsb-0.12.0/lib/jackson-core-asl-1.9.4.jar:/opt/ycsb-0.12.0/lib/HdrHistogram-2.1.4.jar:/opt/ycsb-0.12.0/mongodb-binding/lib/logback-classic-1.1.2.jar:/opt/ycsb-0.12.0/mongodb-binding/lib/logback-core-1.1.2.jar:/opt/ycsb-0.12.0/mongodb-binding/lib/mongo-java-driver-3.0.3.jar:/opt/ycsb-0.12.0/mongodb-binding/lib/mongodb-async-driver-2.0.1.jar:/opt/ycsb-0.12.0/mongodb-binding/lib/slf4j-api-1.6.4.jar:/opt/ycsb-0.12.0/mongodb-binding/lib/mongodb-binding-0.12.0.jar com.yahoo.ycsb.Client -db com.yahoo.ycsb.db.MongoDbClient -P workloads/mongotest_in_only -s -load
YCSB Client 0.12.0
Command line: -db com.yahoo.ycsb.db.MongoDbClient -P workloads/mongotest_in_only -s -load
Loading workload...
Starting test.
2018-02-02 11:19:40:314 0 sec: 0 operations; est completion in 0 seconds 
2018-02-02 11:19:50:233 10 sec: 57123 operations; 5703.74 current ops/sec; est completion in 4 hours 52 minutes [INSERT: Count=57144, Max=1724415, Min=150, Avg=12858.59, 90=621, 99=416511, 99.9=1072127, 99.99=1367039] 
2018-02-02 11:20:00:218 20 sec: 188182 operations; 13125.59 current ops/sec; est completion in 2 hours 56 minutes [INSERT: Count=131051, Max=2009087, Min=35, Avg=6348.01, 90=206, 99=140159, 99.9=1202175, 99.99=1803263] 
2018-02-02 11:20:11:036 30 sec: 370000 operations; 18181.8 current ops/sec; est completion in 2 hours 14 minutes [INSERT: Count=181818, Max=2965503, Min=30, Avg=5638.81, 90=122, 99=371, 99.9=1506303, 99.99=2301951] 
2018-02-02 11:20:20:223 40 sec: 576572 operations; 20646.88 current ops/sec; est completion in 1 hours 54 minutes [INSERT: Count=206574, Max=4304895, Min=27, Avg=3766.68, 90=109, 99=276, 99.9=1126399, 99.99=1978367] 
2018-02-02 11:20:31:659 51 sec: 747015 operations; 14904.07 current ops/sec; est completion in 1 hours 53 minutes [INSERT: Count=170445, Max=5423103, Min=27, Avg=6511.35, 90=107, 99=276, 99.9=2037759, 99.99=3981311] 
    .
    .
    .
2018-02-02 13:10:50:218 6670 sec: 99794282 operations; 17292.1 current ops/sec; est completion in 14 seconds [CLEANUP: Count=12, Max=3, Min=2, Avg=2.58, 90=3, 99=3, 99.9=3, 99.99=3] [INSERT: Count=172921, Max=1833983, Min=18, Avg=1729.1, 90=50, 99=202, 99.9=783871, 99.99=1312767] 
2018-02-02 13:11:00:218 6680 sec: 99925363 operations; 13108.1 current ops/sec; est completion in 5 seconds [CLEANUP: Count=16, Max=4, Min=2, Avg=3, 90=4, 99=4, 99.9=4, 99.99=4] [INSERT: Count=131081, Max=1249279, Min=19, Avg=1336.59, 90=54, 99=152, 99.9=607231, 99.99=1011711] 
2018-02-02 13:11:10:218 6690 sec: 99972913 operations; 4755 current ops/sec; est completion in 2 seconds [CLEANUP: Count=5, Max=5, Min=4, Avg=4.2, 90=5, 99=5, 99.9=5, 99.99=5] [INSERT: Count=47550, Max=898559, Min=21, Avg=1097.42, 90=78, 99=136, 99.9=512511, 99.99=825855] 
2018-02-02 13:11:20:218 6700 sec: 99995467 operations; 2255.4 current ops/sec; est completion in 1 seconds [CLEANUP: Count=2, Max=4, Min=4, Avg=4, 90=4, 99=4, 99.9=4, 99.99=4] [INSERT: Count=22554, Max=752127, Min=24, Avg=850.14, 90=68, 99=106, 99.9=500223, 99.99=642559] 
2018-02-02 13:11:23:489 6703 sec: 100000000 operations; 1385.39 current ops/sec; [CLEANUP: Count=1, Max=5411, Min=5408, Avg=5410, 90=5411, 99=5411, 99.9=5411, 99.99=5411] [INSERT: Count=4533, Max=527871, Min=20, Avg=821.06, 90=61, 99=90, 99.9=466175, 99.99=527871]

中间很多行暂时先忽略,因为是会一致输出到运行完毕为止,来看运行解读,每一个项都用分号;来隔开,直接拿例子来说说.这是第二行的数据:

第一个分号前的数值:2018-02-02 11:20:00:218 20 sec: 188182 operations;

    表示"当前的时间,已运行的时间,运行的数据量"三个值,而-s参数默认是每10秒输出一次,直到这1亿数据写完就停止.

第二个分号前的数值:13125.59 current ops/sec;

    表示吞吐量信息,也就是常说的ops值(每秒操作次数),可以用他来做趋势图,看看这个集群的趋势.

后面的所有:est completion in 2 hours 56 minutes [INSERT: Count=131051, Max=2009087, Min=35, Avg=6348.01, 90=206, 99=140159, 99.9=1202175, 99.99=1803263]

    表示预估执行时间,进行了什么操作(这里只有insert),总共操作了多少数据,操作的时间和延时等数据,意义不大,只做参考.


4.执行纯读测试

配置文件和上面可以保持大体一致即可,只修改下面这里

1
2
3
4
5
#只读,1即100
readproportion=1
updateproportion=0
scanproportion=0
insertproportion=0

然后就可以执行了

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#执行下面命令进行只读测试
bin/ycsb run mongodb -P workloads/mongotest_re_only -s > /home/logs/mongo_ycsb20180201-1.log &
/usr/local/jdk/bin/java -cp /opt/ycsb-0.12.0/mongodb-binding/conf:/opt/ycsb-0.12.0/conf:/opt/ycsb-0.12.0/lib/core-0.12.0.jar:/opt/ycsb-0.12.0/lib/htrace-core4-4.1.0-incubating.jar:/opt/ycsb-0.12.0/lib/jackson-mapper-asl-1.9.4.jar:/opt/ycsb-0.12.0/lib/jackson-core-asl-1.9.4.jar:/opt/ycsb-0.12.0/lib/HdrHistogram-2.1.4.jar:/opt/ycsb-0.12.0/mongodb-binding/lib/logback-classic-1.1.2.jar:/opt/ycsb-0.12.0/mongodb-binding/lib/logback-core-1.1.2.jar:/opt/ycsb-0.12.0/mongodb-binding/lib/mongo-java-driver-3.0.3.jar:/opt/ycsb-0.12.0/mongodb-binding/lib/mongodb-async-driver-2.0.1.jar:/opt/ycsb-0.12.0/mongodb-binding/lib/slf4j-api-1.6.4.jar:/opt/ycsb-0.12.0/mongodb-binding/lib/mongodb-binding-0.12.0.jar com.yahoo.ycsb.Client -db com.yahoo.ycsb.db.MongoDbClient -P workloads/mongotest_re_only -s -t
YCSB Client 0.12.0
Command line: -db com.yahoo.ycsb.db.MongoDbClient -P workloads/mongotest_re_only -s -t
Loading workload...
Starting test.
2018-02-02 14:14:03:394 0 sec: 0 operations; est completion in 0 seconds 
2018-02-02 14:14:13:316 10 sec: 52718 operations; 5271.8 current ops/sec; est completion in 5 hours 15 minutes [READ: Count=52726, Max=515839, Min=886, Avg=17807.9, 90=32959, 99=84223, 99.9=215551, 99.99=422655] 
2018-02-02 14:14:23:315 20 sec: 136267 operations; 8354.9 current ops/sec; est completion in 4 hours 4 minutes [READ: Count=83543, Max=71231, Min=740, Avg=11962.2, 90=22063, 99=39167, 99.9=52863, 99.99=65919] 
2018-02-02 14:14:33:315 30 sec: 227979 operations; 9171.2 current ops/sec; est completion in 3 hours 38 minutes [READ: Count=91710, Max=60479, Min=969, Avg=10899.01, 90=18143, 99=29439, 99.9=45055, 99.99=55839] 
2018-02-02 14:14:43:315 40 sec: 319725 operations; 9174.6 current ops/sec; est completion in 3 hours 27 minutes [READ: Count=91747, Max=57215, Min=1036, Avg=10890.33, 90=17919, 99=27007, 99.9=36031, 99.99=49023] 
2018-02-02 14:14:53:318 50 sec: 411156 operations; 9141.27 current ops/sec; est completion in 3 hours 21 minutes [READ: Count=91439, Max=51039, Min=1052, Avg=10932.95, 90=17983, 99=27887, 99.9=37375, 99.99=44639] 
    .
    .
    .
2018-02-02 17:18:53:315 11090 sec: 99690172 operations; 8923 current ops/sec; est completion in 35 seconds [READ: Count=89229, Max=59263, Min=920, Avg=11199.31, 90=18879, 99=30383, 99.9=43423, 99.99=53631] 
2018-02-02 17:19:03:315 11100 sec: 99779154 operations; 8898.2 current ops/sec; est completion in 25 seconds [READ: Count=88982, Max=69119, Min=914, Avg=11232.26, 90=18959, 99=30303, 99.9=42975, 99.99=54751] 
2018-02-02 17:19:13:315 11110 sec: 99868510 operations; 8935.6 current ops/sec; est completion in 15 seconds [READ: Count=89356, Max=72895, Min=720, Avg=11122.55, 90=18591, 99=29871, 99.9=41215, 99.99=48831] [CLEANUP: Count=2, Max=19, Min=5, Avg=12, 90=19, 99=19, 99.9=19, 99.99=19] 
2018-02-02 17:19:23:316 11120 sec: 99956583 operations; 8806.42 current ops/sec; est completion in 5 seconds [READ: Count=88074, Max=67007, Min=886, Avg=9859.62, 90=16527, 99=27039, 99.9=38911, 99.99=51519] [CLEANUP: Count=35, Max=15, Min=4, Avg=5.49, 90=7, 99=15, 99.9=15, 99.99=15] 
2018-02-02 17:19:30:066 11126 sec: 100000000 operations; 6432.15 current ops/sec; [READ: Count=43416, Max=42047, Min=705, Avg=4970.02, 90=8567, 99=16719, 99.9=27343, 99.99=37055] [CLEANUP: Count=63, Max=9311, Min=2, Avg=153.7, 90=6, 99=53, 99.9=9311, 99.99=9311]

和上面差不多,

第一个分号前的数值:2018-02-02 14:14:23:315 20 sec: 136267 operations;

    表示"当前的时间,已运行的时间,运行的数据量"三个值,而-s参数默认是每10秒输出一次,直到这1亿数据写完就停止.

第二个分号前的数值:8354.9 current ops/sec;

    表示吞吐量信息,也就是常说的ops值(每秒操作次数),可以用他来做趋势图,看看这个集群的趋势.

后面的所有:est completion in 4 hours 4 minutes [READ: Count=83543, Max=71231, Min=740, Avg=11962.2, 90=22063, 99=39167, 99.9=52863, 99.99=65919] 

    表示预估执行时间,进行了什么操作(这里只有read),总共操作了多少数据,操作的时间和延时等数据,意义不大,只做参考.

其他测试就不一一细说了,各位自己按实际情况配置这个比例即可.


5.结果解读

上面介绍的其实只是-s输出的结果,当然那些结果还是很有参考价值的,但是真正的结果其实是下面这些,

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
#打开结果文件
vim mongo_ycsb20180202-1.log
mongo client connection created with mongodb://10.21.1.205:30000/ycsb?w=0
[OVERALL], RunTime(ms), 1.112675E7
[OVERALL], Throughput(ops/sec), 8987.350304446492
[TOTAL_GCS_PS_Scavenge], Count, 18117.0
[TOTAL_GC_TIME_PS_Scavenge], Time(ms), 99198.0
[TOTAL_GC_TIME_%_PS_Scavenge], Time(%), 0.891527175500483
[TOTAL_GCS_PS_MarkSweep], Count, 8.0
[TOTAL_GC_TIME_PS_MarkSweep], Time(ms), 254.0
[TOTAL_GC_TIME_%_PS_MarkSweep], Time(%), 0.002282786977329409
[TOTAL_GCs], Count, 18125.0
[TOTAL_GC_TIME], Time(ms), 99452.0
[TOTAL_GC_TIME_%], Time(%), 0.8938099624778125
[READ], Operations, 1.0E8
[READ], AverageLatency(us), 11114.24612337
[READ], MinLatency(us), 672.0
[READ], MaxLatency(us), 515839.0
[READ], 95thPercentileLatency(us), 21871.0
[READ], 99thPercentileLatency(us), 29615.0
[READ], Return=OK, 100000000
[CLEANUP], Operations, 100.0
[CLEANUP], AverageLatency(us), 98.99
[CLEANUP], MinLatency(us), 2.0
[CLEANUP], MaxLatency(us), 9311.0
[CLEANUP], 95thPercentileLatency(us), 10.0
[CLEANUP], 99thPercentileLatency(us), 53.0

关注几个信息:

RunTime(ms):    数据加载所用时间,单位毫秒(ms)

Throughput(ops/sec):    吞吐量,即ops(每秒操作次数)

Operations:    操作的总次数

AverageLatency(us):    平均响应延时,单位是微秒(us)

MinLatency(us):    最小响应时间,单位是微秒(us)

MaxLatency(us):    最大响应时间,单位是微秒(us)

95thPercentileLatency(us):    95%的操作延时,单位是微秒(us)

99thPercentileLatency(us):    99%的操作延时,单位是微秒(us)

Return=OK:    成功返回数,这个值不符合测试要求,则证明测试失败.

[READ]开头的代表只读的操作记录,其他还有例如上面的[insert],[UPDATE]等,

其他可以理解的就是字面意思,不能理解也不需要太过关注.

和其他测试软件一样,这个只能说是基准值,并不是标准值,和真实环境不能全部模拟,所以测试的思维要结合别的测试软件的方法来做.


测试总结

经过对5分片/7分片的1亿/3亿数据的测试来看,其实mongodb的OPS并没有明显提升,但是可以看到cpu负载长期属于低状态,而磁盘压力也没有跑满,内存剩余还算多,所以分片的真正意义是提高了并发能力.

5分片1亿只读数据图表:

单台分片的iops值,


1.png

单台分片磁盘利用率,


2.png


单台分片cpu使用率,


3.png


测试集群ops值,


4.png

测试集群平均延时,单位是微秒(us)


5.png


7分片1亿只读数据图表:

单台分片的iops值,

1.png

单台分片磁盘利用率,

2.png

单台分片cpu使用率,

3.png

测试集群ops值,

4.png

测试集群平均延时,单位是微秒(us)

5.png


7分片3亿只读数据图表: