溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

mongodb+分片集群+ycsb測試一例

發布時間:2020-09-06 05:33:57 來源:網絡 閱讀:15575 作者:arthur376 欄目:關系型數據庫

簡介

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.

mongodb+分片集群+ycsb測試一例

然后就有一堆地址,你自己選擇需要的版本吧,例如我要下的是這個地址.

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

下載完成,就開始安裝了,因為是二進制版的,很簡單就是了.

#先安裝下依賴包,因為他是用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/
#修改資源限制參數,添加mongodb相關項
vim /etc/security/limits.conf
mongod          soft   nofile         64000
mongod          hard   nofile         64000
mongod          soft   nproc          32000
mongod          hard   nproc          32000

這就安裝完成了,后面就是初始化數據庫了,初始化之前,必須先有配置文件,二進制版本安裝的程序是不帶配置文件模板的,所以就要自己編輯了,配置文件存放的位置可以隨意,因為啟動是需要指定位置的,例如下面這個:

#編輯配置文件,并指定位置
vim /usr/local/mongodb/mongod_data_40001.conf
#數據目錄
dbpath=/data/mongodb/data
#日志文件
logpath=/data/mongodb/data/mongodb_data.log
#日志形式為追加到文件后
logappend=true
#端口
port = 40001
#指定訪問地址,不指定就是全網,但是在3.6之后必須制定這個參數才能啟動.0.0.0.0代表全網匹配
bind_ip = 0.0.0.0
#最大連接數
maxConns = 5000
pidfilepath = /data/mongodb/data/mongo_40001.pid
#日志,redo log
journal = true
#刷寫提交機制
journalCommitInterval = 200
#守護進程模式
fork = true
#刷寫數據到日志的頻率
syncdelay = 60
#存儲引擎,3.2之后默認就是wiredTiger
#storageEngine = wiredTiger
#操作日志,單位M
oplogSize = 2000
#命名空間的文件大小,默認16M,最大2G。
nssize = 16
unixSocketPrefix = /tmp
#指定一個數據庫一個文件夾,必須在初始化前配置,在已有數據庫上新增這個參數會報錯
directoryperdb=true
#開啟慢查詢分析功能,0:關閉,不收集任何數據。1:收集慢查詢數據,默認是100毫秒.2:收集所有數據
profile=1
#慢查詢的時間,單位ms,超過這個時間將被記錄
slowms=200
#是否開啟認證模式,不開就不用用戶名密碼就能登錄數據庫,測試環境可以不開
#auth = true
#關閉認證模式,和上面的沖突
noauth = true
#指定集群認證文件,沒開認證就不用指定,注釋關閉即可,需要用openssl來生成
#keyFile  = /data/mongodb/data/keyfile
#標識這臺mongodb數據庫為分片集群使用
#shardsvr = true
#副本集名稱,這里測的是單臺,不設置
#replSet=shard1
#是否config端,做集群的配置端使用,后面詳細介紹,這里不需要
#configsvr = true
#禁止HTTP狀態接口,3.6后不用
nohttpinterface=true
#禁止REST接口-在生產環境下建議不要啟用MongoDB的REST接口,,3.6后不用
rest=false
#打開web監控,和上面相反,這里不開了
#httpinterface=true
#rest=true

配置文件有了,就可以初始化啟動了,因為我沒有開啟認證模式,啟動就可以使用了.

#開啟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-31×××1:12:12.537+0800 I CONTROL  [initandlisten] 
> show dbs
local   0.000GB

============分割線開始=============

其實官方是推薦下面這種啟動方式,不過我為了方便,就簡單化啟動了.

#啟動之前,要先把文件夾權限確保一下
chown mongodb:mongodb -R /data/mongodb/data/*
#然后關閉numa并使用mongodb用戶啟動
su - mongodb -s /bin/bash -c "numactl --interleave=all /usr/local/mongodb/bin/mongod -f /usr/local/mongodb/mongod_data_40001.conf"

這種啟動方式好處是顯然的,對于數據庫來說,最怕就是被***提權,然后控制整臺機器,所以限制數據庫的啟動用戶是很有意義的.

而numa這個功能,對于大內存應用是很不友好的,會變成性能瓶頸,所以無論是sql還是nosql都最好是關閉了這個功能,那性能就更好一些了.

===========分割線結束==============

然后,這個mongodb數據庫就可以正常使用的了,當然,我們不是只使用單臺mongodb.

開頭也說了,90%的公司使用mongodb都是會使用到集群,在3.4版本之前,一般就用上面的配置就可以搭建集群,但是在3.4之后,如果不在啟動的時候指定這是分片端,則分片集群就不能被正常使用.

#標識這臺mongodb數據庫為分片集群使用
shardsvr = true

只有開啟了這個參數,分片集群才會正常使用.

如果,需要加載到服務啟動項,就添加以下腳本:

vim /etc/init.d/mongod

#!/bin/sh
#
#mongod - Startup script for mongod
#
# chkconfig: - 85 15
# description: Mongodb database.
# processname: mongod
# Source function library
 . /etc/rc.d/init.d/functions
mongod="/usr/local/mongodb/bin/mongod"
configfile=" -f /etc/mongod.conf"
lockfile=/var/lock/subsys/mongod
 
if test -f /sys/kernel/mm/transparent_hugepage/enabled; then 
   echo never > /sys/kernel/mm/transparent_hugepage/enabled 
fi 
 
if test -f /sys/kernel/mm/transparent_hugepage/defrag; then 
    echo never > /sys/kernel/mm/transparent_hugepage/defrag 
fi
 
ulimit -f unlimited
ulimit -t unlimited
ulimit -v unlimited
ulimit -n 64000
ulimit -m unlimited
ulimit -u 64000
ulimit -l unlimited
 
start()
{
  echo -n $"Starting mongod: "
  daemon --user mongod "$mongod $configfile"
    retval=$?
    echo
    [ $retval -eq 0 ] && touch $lockfile
}
 
stop()
{
  echo -n $"Stopping mongod: "
   $mongod --shutdown $configfile
  retval=$?
  echo
  [ $retval -eq 0 ] && rm -f $lockfile
}
 
restart () {
        stop
        start
}
 
case "$1" in
  start)
    start
    ;;
  stop)
    stop
    ;;
  restart|reload|force-reload)
    restart
    ;;
  condrestart)
    [ -f $lockfile ] && restart || :
    ;;
  status)
    status $mongod
    retval=$?
    ;;
  *)
    echo "Usage: $0 {start|stop|status|restart|reload|force-reload|condrestart}"
    retval=1
esac
exit $retval

這樣就可以chkconfig或者systemd了


搭建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個則會報錯,

BadValue need either 1 or 3 configdbs

所以要注意數量,這里我就設一個就算了.

#也和上面一樣,沒有模板,只能自己編輯
vim /usr/local/mongodb/mongod_config_20000.conf
#數據目錄,目錄名字區分于數據節點
dbpath=/data/mongodb/config/
#日志文件
logpath=/data/mongodb/mongodb_config.log
#日志追加
logappend=true
#端口
port = 20000
#綁定ip,可以限制IP登錄,例如bind_ip=10.21.1.208,3.2默認是允許所有ip登入,之后是允許127.0.0.1,只有配置0.0.0.0才是允許所有
bind_ip = 0.0.0.0
#最大連接數
maxConns = 5000
pidfilepath = /data/mongodb/mongo_20000.pid
#日志,redo log
journal = true
#刷寫提交機制
journalCommitInterval = 200
#守護進程模式
fork = true
#刷寫數據到日志的頻率
syncdelay = 60
#存儲引擎
#storageEngine = wiredTiger
#操作日志,單位M
oplogSize = 2000
#命名空間的文件大小,默認16M,最大2G。
nssize = 16
#套接字存放位置
unixSocketPrefix = /tmp
#指定一個數據庫一個文件夾,必須在初始化前配置,在已有數據庫上新增這個參數會報錯
directoryperdb=true
#關閉認證模式,config端可以不需要,也視乎你的需求
noauth = true
#是否config端,這里當然是了
configsvr = true
#副本集名稱,3.4之前可以不做集群,之后都需要設置config集群才可以使用
replSet=configs

其實和上面只是多了最后一行,標記是config端而已,然后啟動.

#啟動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端.

注意:3.4之后的版本使用分片集群,config端必須使用副本集,不然router端無法啟動.


2.配置并啟動router端:

路由服務器本身不保存數據,把日志記錄一下即可,他都是直接調用config端來使用.而所有客戶端程序想要連接mongodb集群,其實就是連接這個router端的端口來使用,并不是連接config端和sharding端,所以也說是類似于代理的形式.

#也和上面一樣,沒有模板,只能自己編輯
vim /usr/local/mongodb/mongos_route_30000.conf
#日志文件
logpath=/data/mongodb/mongodb_route.log
#日志追加
logappend=true
#端口
port = 30000
#綁定ip,可以限制IP登錄,例如bind_ip=10.21.1.208,3.2默認是允許所有ip登入,之后是允許127.0.0.1,只有配置0.0.0.0才是允許所有
bind_ip = 0.0.0.0
#最大連接數
maxConns = 5000
pidfilepath = /data/mongodb/mongo_30000.pid
#指定config端地址,不能使用127.0.0.1,會報錯,3.4后config必須是集群,
#還必須在地址前面帶上副本集名稱,3.0和3.2可以點,例如:configdb=172.25.33.98:20000,單會提示警告
configdb=configs/172.25.33.98:20000,172.25.33.99:20000,172.25.33.101:20000
#守護進程模式 
fork = true

最重要的參數是configdb,指定config端的地址,可以1個或3個,但是不能在其后面帶的配置服務器的地址寫成localhost或則127.0.0.1,需要設置成其他分片也能訪問的地址,即10.21.1.205:20000/20001/20002。否則在添加分片地址的時候會報錯.

然后是啟動:

#啟動方式略有不同,要使用mongos
mongos -f /usr/local/mongodb/mongos_route_30000.conf
2018-02-01×××0: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端都已經全部部署啟動完畢.然后,就登錄進去操作了:

#使用客戶端像一般登錄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-01×××0: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")

#添加分片,如此類推
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的.

#關閉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})

#創建一個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
###########################################


==============分割線開始==================

在mongodb單純創建數據庫和表,并不需要另外的create命令操作,只需要直接插入一條數據就好了,也就代表創建成功

#當前沒有新的數據庫
> show dbs
admin  0.000GB
local  0.000GB
#單純切換到數據庫,也算是新建數據庫的了
> use foo
switched to db foo
> db
foo
#但是這個時候,你還是看不到的
> show dbs
admin  0.000GB
local  0.000GB
#插入一條數據,createtmp是要新建的表名,
> db.createtmp.insert({"name":"create database"})
WriteResult({ "nInserted" : 1 })
#你就能看到了
> show dbs
foo            0.000GB
admin            0.000GB
local            0.000GB
#而且你的表也創建好了
> show collections
createtmp

不過,我們如果做分片的話,一開始有表是不合適的,因為要做片鍵,所以才在這里另外來說這個問題.

==============分割線結束==================


這樣添加的原因是后面的ycsb測試工具的需要,他會生成一個名為ycsb的數據庫,里面有一個usertable集合(表),然后其中有_id這個列,至于hash規則我想就不解析了.然后,在看看狀態:

#看看現在的狀態,很長
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就是沒數據了,各分片也沒有數據.

不過,有時候會因為信息太長而導致顯示不全,并提示

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

那么我們就要用下列命令來顯示了,三個都可以,然后就顯示全部了,但是更長.

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


4.刪除分片信息

最后來看刪除分片,有添加,就當然有刪除了,雖然不是這里的重點, db.runCommand({"removeshard":"mmm"})

#登進管理數據庫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自己去跑就算了.

需要特別注意的是刪除主分片,則需要先遷移走數據庫到別的分片,

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

#安裝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

#下載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

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,這里編輯好,那壓測效果才會出來,那么里面有些什么呢,西面來看看:

#打開這個文件來看
vim workloads/workloada
#YCSB load(加載元數據)命令的參數,表示加載的記錄條數,也就是可用于測試的總記錄數。
recordcount=1000000
#YCSB run(運行壓力測試)命令的參數,測試的總次數。和maxexecutiontime參數有沖突,誰先完成就中斷測試退出,結合下面的增改讀掃參數,按比例來操作.
#operationcount=1000000
#測試的總時長,單位為秒,和operationcount參數有沖突,誰先完成就中斷測試退出,這里3600秒就代表一小時,也是結合下面的增改讀掃參數,按比例來操作.
maxexecutiontime=3600
#java相關參數,指定了workload的實現類為 com.yahoo.ycsb.workloads.CoreWorkload
workload=com.yahoo.ycsb.workloads.CoreWorkload
#表示查詢時是否讀取記錄的所有字段
readallfields=true
#表示讀操作的比例,該場景為0.54,即54%
readproportion=0.54
#表示更新操作的比例,該場景為0.2,即20%
updateproportion=0.2
#表示掃描操作的比例,即1%,通常是用來模擬沒有索引的查詢
scanproportion=0.01
#表示插入操作的比例,即25%
insertproportion=0.25
#表示請求的分布模式,YCSB提供uniform(隨機均衡讀寫),zipfian(偏重讀寫少量熱數據),latest(偏重讀寫最新數據)三種分布模式
requestdistribution=uniform
#插入文檔的順序方式:哈希(hashed)/隨機 (insertorder)
insertorder=hashed
#測試數據的每一個字段的長度,單位字節
fieldlength=2000
#測試數據的每條記錄的字段數,也就是說一條記錄的總長度是2000*10=20000字節
fieldcount=10
#####################以下是不自帶的參數#############################
#把數據庫連接地址寫到這里,那么輸命令的時候就不用輸地址了,我這里沒有設用戶名密碼,當然是不需要了
mongodb.url=mongodb://10.21.1.205:30000/ycsb?w=0
#如果你是有很多個mongos的話,就要這樣寫
#mongodb.url=mongodb://172.25.31.101:30000,172.25.31.102:30000,172.25.31.103:30000/ycsb?w=0
#如果是有用戶名密碼的話,就要這樣寫,還記得上面一開始的模板嘛,mongodb://user:pwd@server1.example.com:9999
#mongodb.url=mongodb://ycsbtest:ycsbtest@10.21.1.205:30000/ycsb?w=0
#寫安全設置,Unacknowledged(不返回用戶是否寫入成功{w:0}),Acknowledged(寫入到主節點內存就返回寫入成功{w:1}),Journaled(寫入到主節點journal log才返回寫入成功{w:1,j:true}),Replica Acknowledged(寫入到所有副本集內存和主節點journal log才返回寫入成功{w:2}),Available Write Concern(寫入到所有節點journal log才返回寫入成功{w:2,j:true}),選項越往后,安全性越高,但是性能越差.
mongodb.writeConcern=acknowledged
#線程數,也就是說100個并發,既然是壓測,怎么可能是單線程
threadcount=100

還有一些參數沒列出,然后我們得出自己需要的參數文件,這個是100%純插入1億條記錄的參數文件,如下所示:

#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=hashed
fieldlength=250
fieldcount=8
mongodb.url=mongodb://10.21.1.205:30000/ycsb?w=0
mongodb.writeConcern=acknowledged
threadcount=100

每個文檔大小大約2KB(fieldlength x fieldcount),數據總大小大概是200G+12G的索引,數量還是比較多,如果是單點,估計是比較難撐,查詢也超級慢.但是做了分片的話,程序會自動分配,把他們平均分配到每一個分片中,那么壓力就減輕很多了,分布式架構的優勢出來了.


3.執行純插入測試

上面我自己寫的配置文件,就是為了做插入測試,總共7個分片,插入1億條數據,花了兩個多小時,看來時間還是要預足夠.

#執行下面命令進行插入測試
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: ×××5363 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即100
readproportion=1
updateproportion=0
scanproportion=0
insertproportion=0

然后就可以執行了

#執行下面命令進行只讀測試
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輸出的結果,當然那些結果還是很有參考價值的,但是真正的結果其實是下面這些,

#打開結果文件
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值,


mongodb+分片集群+ycsb測試一例

單臺分片磁盤利用率,


mongodb+分片集群+ycsb測試一例


單臺分片cpu使用率,


mongodb+分片集群+ycsb測試一例


測試集群ops值,


mongodb+分片集群+ycsb測試一例

測試集群平均延時,單位是微秒(us)


mongodb+分片集群+ycsb測試一例


7分片1億只讀數據圖表:

單臺分片的iops值,

mongodb+分片集群+ycsb測試一例

單臺分片磁盤利用率,

mongodb+分片集群+ycsb測試一例

單臺分片cpu使用率,

mongodb+分片集群+ycsb測試一例

測試集群ops值,

mongodb+分片集群+ycsb測試一例

測試集群平均延時,單位是微秒(us)

mongodb+分片集群+ycsb測試一例


7分片3億只讀數據圖表:

單臺分片的iops值,

mongodb+分片集群+ycsb測試一例

單臺分片磁盤利用率,

mongodb+分片集群+ycsb測試一例

單臺分片cpu使用率,

mongodb+分片集群+ycsb測試一例

測試集群ops值,

mongodb+分片集群+ycsb測試一例

測試集群平均延時,單位是微秒(us)

mongodb+分片集群+ycsb測試一例


補充信息

1.創建副本集

config端的副本集:

一個架構穩定的分片集群,應該需要多個節點副本集,防止一掛全掛現象,這是對數據安全的基本要求.而上面我們也談到一點,在3.4版本之后,mongos的啟動已經強制使用config端的副本集模式,如果沒有副本集,你也是啟動不起來的,所以這里特別補充一下.

首先,說說在3.4情況下,我們的config端必須要建立副本集,所以要在config端設置,就是上面強調的一個參數replSet

#打開config的配置文件
vim /usr/local/mongodb/mongod_config_20000.conf
    .
    .
    .
#開啟副本集功能,并指定副本集名稱為configs
replSet=configs

當然,上面也說了,至少要1個或3個config端,那么我們需要開啟三個config端,具體配置不詳細解析,也不要吐槽為什么放一起,只是測試而已.

#看一下有多少個配置文件
ll /usr/local/mongodb/
drwxr-xr-x. 2 root root   248 Mar 14 10:21 bin
-rw-r--r--. 1 root root 34520 Feb 23 03:53 GNU-AGPL-3.0
-rw-r--r--. 1 root root   622 Mar 14 14:26 mongod_config_20000.conf
-rw-r--r--. 1 root root   622 Mar 14 14:28 mongod_config_20001.conf
-rw-r--r--. 1 root root   622 Mar 14 14:35 mongod_config_20002.conf
-rw-r--r--. 1 root root   419 Mar 14 14:41 mongos_route_30000.conf
#看一下運行的mongo進程
ps aux |grep mongo
root     17211  1.1  0.7 1718800 60916 ?       Sl   14:36   1:57 mongod -f /usr/local/mongodb/mongod_config_20000.conf
root     17244  1.0  0.7 1551432 58216 ?       Sl   14:36   1:41 mongod -f /usr/local/mongodb/mongod_config_20001.conf
root     17277  1.0  0.7 1551432 57920 ?       Sl   14:36   1:40 mongod -f /usr/local/mongodb/mongod_config_20002.conf
#看一下當前端口情況
ss -ntplu |grep mongo
tcp    LISTEN     0      128       *:20000                 *:*                   users:(("mongod",pid=17211,fd=11))
tcp    LISTEN     0      128       *:20001                 *:*                   users:(("mongod",pid=17244,fd=11))
tcp    LISTEN     0      128       *:20002                 *:*                   users:(("mongod",pid=17277,fd=11))

三臺都可以用了,但是也只是創建了而已,關聯關系還是要做初始化,就像mysql的change master的意思一樣.

#連接其中一臺config端
mongo --port 20000
#輸入命令,添加關聯關系
>config = {_id:"configs",members:[{_id:0, host:"10.21.1.205:20000" },{_id:1, host:"10.21.1.205:20001" },{_id:2, host:"10.21.1.205:20002" }]}
#初始化副本集
rs.initiate(config)

要注意出現 "ok" : 1, 那才是成功初始化,不成功就需要看看哪里出了問題,包括權限.

chown -R mongodb:mongodb /data/mongodb/

然后再次啟動,就ok了,那就可以用了,愉快的使用mongos啟動router端吧.


節點分片的副本集:

如果是節點分片的副本集則有點不一樣,參數是一樣要加的.

#編輯配置文件
vim /usr/local/mongodb/mongod_data_40001.conf
    .
    .
    .
#開啟副本集功能,并指定副本集名稱為shard1
replSet=shard1

這里倒沒有強制你用多少個副本集,兩個三個十個都可以,只要你覺得有必要,這里也就不詳細描述了.但是關聯關系,那當然是必須的.

#連接其中一臺節點
mongo --port 40001
#進入管理數據庫admin
>use admin
#輸入命令,添加關聯關系,和上面不同的點也是這里,
>config = { _id : "shard1", members : [ {_id : 0, host : "10.21.1.208:40001" }, {_id : 1, host : "10.21.1.208:40002" }, {_id : 2, host : "10.21.1.208:40003" , arbiterOnly: true } ]}
#初始化副本集,這里是一樣的
rs.initiate(config)

不同的點就是arbiterOnly參數,表示這個成員為仲裁節點,不接收數據.使用他的原因是當副本集發生故障時,需要一個仲裁機制來決定誰頂上來接收新的數據,屬于故障切換機制,還是比較嚴密的.


節點副本集添加分片:

另外,由于創建了副本集,分片添加有點不一樣了,刪除倒是一樣的,按分片名字就好了.

#副本集模式添加分片的方式
sh.addShard("shard1/10.21.1.208:40001,10.21.1.208:40002,10.21.1.208:40003")



向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

亚洲午夜精品一区二区_中文无码日韩欧免_久久香蕉精品视频_欧美主播一区二区三区美女