搭建 MongoDB分片(sharding) / 分割槽 / 叢集環境

搜雲庫技術團隊發表於2018-02-01

1. 安裝 MongoDB

三臺機器

關閉防火牆

systemctl stop firewalld.service 
複製程式碼
192.168.252.121 192.168.252.122 192.168.252.123
mongos mongos mongos
config server config server config server
shard server1 主節點 shard server1 副節點 shard server1 仲裁
shard server2 仲裁 shard server2 主節點 shard server2 副節點
shard server3 副節點 shard server3 仲裁 shard server3 主節點

埠分配:

mongos:20000
config:21000
shard1:27001
shard2:27002
shard3:27003
複製程式碼

下載並且安裝

wget https://fastdl.mongodb.org/linux/mongodb-linux-x86_64-amazon-3.6.2.tgz
tar -xzvf mongodb-linux-x86_64-amazon-3.6.2.tgz  -C /usr/local/
複製程式碼

所有版本二進位制檔案,自行下載

https://www.mongodb.org/dl/win32/x86_64-2008plus-ssl?_ga=2.87139544.1567998244.1517190032-1153843332.1517190032&_gac=1.204211492.1517212002.EAIaIQobChMI44v9_9b82AIV1AcqCh0lcABIEAAYASAAEgKI1_D_BwE
複製程式碼

改名

cd /usr/local/
mv  mongodb-linux-x86_64-amazon-3.6.2 mongodb
複製程式碼

分別在每臺機器建立conf、mongos、config、shard1、shard2、shard3六個目錄,因為mongos不儲存資料,只需要建立日誌檔案目錄即可。

mkdir -p /usr/local/mongodb/conf \
mkdir -p /usr/local/mongodb/mongos/log \
mkdir -p /usr/local/mongodb/config/data \
mkdir -p /usr/local/mongodb/config/log \
mkdir -p /usr/local/mongodb/shard1/data \
mkdir -p /usr/local/mongodb/shard1/log \
mkdir -p /usr/local/mongodb/shard2/data \
mkdir -p /usr/local/mongodb/shard2/log \
mkdir -p /usr/local/mongodb/shard3/data \
mkdir -p /usr/local/mongodb/shard3/log
複製程式碼

配置環境變數

vi /etc/profile
# MongoDB 環境變數內容
export MONGODB_HOME=/usr/local/mongodb
export PATH=$MONGODB_HOME/bin:$PATH
複製程式碼

使立即生效

source /etc/profile
複製程式碼

2. config server配置伺服器

mongodb3.4以後要求配置伺服器也建立副本集,不然叢集搭建不成功。

(三臺機器)新增配置檔案

vi /usr/local/mongodb/conf/config.conf

## 配置檔案內容
pidfilepath = /usr/local/mongodb/config/log/configsrv.pid
dbpath = /usr/local/mongodb/config/data
logpath = /usr/local/mongodb/config/log/congigsrv.log
logappend = true
 
bind_ip = 0.0.0.0
port = 21000
fork = true
 
#declare this is a config db of a cluster;
configsvr = true

#副本集名稱
replSet = configs
 
#設定最大連線數
maxConns = 20000
複製程式碼

啟動三臺伺服器的config server

mongod -f /usr/local/mongodb/conf/config.conf
複製程式碼

登入任意一臺配置伺服器,初始化配置副本集

連線 MongoDB

mongo --port 21000
複製程式碼

config 變數

config = {
	_id : "configs",
	members : [
	{_id : 0, host : "192.168.252.121:21000" },
	{_id : 1, host : "192.168.252.122:21000" },
	{_id : 2, host : "192.168.252.123:21000" }
	]
}
複製程式碼

初始化副本集

rs.initiate(config)
複製程式碼

其中,"_id" : "configs"應與配置檔案中配置的 replicaction.replSetName 一致,"members" 中的 "host" 為三個節點的 ip 和 port

響應內容如下

> config = {
... _id : "configs",
... members : [
... {_id : 0, host : "192.168.252.121:21000" },
... {_id : 1, host : "192.168.252.122:21000" },
... {_id : 2, host : "192.168.252.123:21000" }
... ]
... }
{
	"_id" : "configs",
	"members" : [
		{
			"_id" : 0,
			"host" : "192.168.252.121:21000"
		},
		{
			"_id" : 1,
			"host" : "192.168.252.122:21000"
		},
		{
			"_id" : 2,
			"host" : "192.168.252.123:21000"
		}
	]
}
> rs.initiate(config);
{
	"ok" : 1,
	"operationTime" : Timestamp(1517369899, 1),
	"$gleStats" : {
		"lastOpTime" : Timestamp(1517369899, 1),
		"electionId" : ObjectId("000000000000000000000000")
	},
	"$clusterTime" : {
		"clusterTime" : Timestamp(1517369899, 1),
		"signature" : {
			"hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
			"keyId" : NumberLong(0)
		}
	}
}
configs:SECONDARY>
複製程式碼

此時會發現終端上的輸出已經有了變化。

//從單個一個
>
//變成了
configs:SECONDARY>
複製程式碼

查詢狀態

configs:SECONDARY> rs.status()
複製程式碼

3. 配置分片副本集

3.1 設定第一個分片副本集

(三臺機器)設定第一個分片副本集

配置檔案

vi /usr/local/mongodb/conf/shard1.conf

#配置檔案內容
#——————————————–
pidfilepath = /usr/local/mongodb/shard1/log/shard1.pid
dbpath = /usr/local/mongodb/shard1/data
logpath = /usr/local/mongodb/shard1/log/shard1.log
logappend = true

bind_ip = 0.0.0.0
port = 27001
fork = true
 
#副本集名稱
replSet = shard1
 
#declare this is a shard db of a cluster;
shardsvr = true
 
#設定最大連線數
maxConns = 20000
複製程式碼

啟動三臺伺服器的shard1 server

mongod -f /usr/local/mongodb/conf/shard1.conf
複製程式碼

登陸任意一臺伺服器,初始化副本集(除了192.168.252.123)

連線 MongoDB

mongo --port 27001
複製程式碼

使用admin資料庫

use admin
複製程式碼

定義副本集配置

config = {
    _id : "shard1",
     members : [
         {_id : 0, host : "192.168.252.121:27001" },
         {_id : 1, host : "192.168.252.122:27001" },
         {_id : 2, host : "192.168.252.123:27001" , arbiterOnly: true }
     ]
 }
複製程式碼

初始化副本集配置

rs.initiate(config)
複製程式碼

響應內容如下

> use admin
switched to db admin
> config = {
...     _id : "shard1",
...      members : [
...          {_id : 0, host : "192.168.252.121:27001" },
...          {_id : 1, host : "192.168.252.122:27001" },
...          {_id : 2, host : "192.168.252.123:27001" , arbiterOnly: true }
...      ]
...  }
{
	"_id" : "shard1",
	"members" : [
		{
			"_id" : 0,
			"host" : "192.168.252.121:27001"
		},
		{
			"_id" : 1,
			"host" : "192.168.252.122:27001"
		},
		{
			"_id" : 2,
			"host" : "192.168.252.123:27001",
			"arbiterOnly" : true
		}
	]
}
> rs.initiate(config)
{ "ok" : 1 }
複製程式碼

此時會發現終端上的輸出已經有了變化。

//從單個一個
>
//變成了
shard1:SECONDARY>
複製程式碼

查詢狀態

shard1:SECONDARY> rs.status()
複製程式碼

3.2 設定第二個分片副本集

設定第二個分片副本集

配置檔案

vi /usr/local/mongodb/conf/shard2.conf

#配置檔案內容
#——————————————–
pidfilepath = /usr/local/mongodb/shard2/log/shard2.pid
dbpath = /usr/local/mongodb/shard2/data
logpath = /usr/local/mongodb/shard2/log/shard2.log
logappend = true

bind_ip = 0.0.0.0
port = 27002
fork = true
 
#副本集名稱
replSet=shard2
 
#declare this is a shard db of a cluster;
shardsvr = true
 
#設定最大連線數
maxConns=20000
複製程式碼

啟動三臺伺服器的shard2 server

mongod -f /usr/local/mongodb/conf/shard2.conf
複製程式碼

連線 MongoDB

mongo --port 27002
複製程式碼

使用admin資料庫

use admin
複製程式碼

定義副本集配置

config = {
    _id : "shard2",
     members : [
         {_id : 0, host : "192.168.252.121:27002"  , arbiterOnly: true },
         {_id : 1, host : "192.168.252.122:27002" },
         {_id : 2, host : "192.168.252.123:27002" }
     ]
 }
複製程式碼

初始化副本集配置

rs.initiate(config)
複製程式碼

響應內容如下

> use admin
switched to db admin
> config = {
...     _id : "shard2",
...      members : [
...          {_id : 0, host : "192.168.252.121:27002"  , arbiterOnly: true },
...          {_id : 1, host : "192.168.252.122:27002" },
...          {_id : 2, host : "192.168.252.123:27002" }
...      ]
...  }
{
	"_id" : "shard2",
	"members" : [
		{
			"_id" : 0,
			"host" : "192.168.252.121:27002",
			"arbiterOnly" : true
		},
		{
			"_id" : 1,
			"host" : "192.168.252.122:27002"
		},
		{
			"_id" : 2,
			"host" : "192.168.252.123:27002"
		}
	]
}
> rs.initiate(config)
{ "ok" : 1 }
shard2:SECONDARY> rs.status()
複製程式碼

3.3 設定第三個分片副本集

vi /usr/local/mongodb/conf/shard3.conf

#配置檔案內容
#——————————————–
pidfilepath = /usr/local/mongodb/shard3/log/shard3.pid
dbpath = /usr/local/mongodb/shard3/data
logpath = /usr/local/mongodb/shard3/log/shard3.log
logappend = true

bind_ip = 0.0.0.0
port = 27003
fork = true

#副本集名稱
replSet=shard3
 
#declare this is a shard db of a cluster;
shardsvr = true
 
#設定最大連線數
maxConns=20000
複製程式碼

啟動三臺伺服器的shard3 server

mongod -f /usr/local/mongodb/conf/shard3.conf
複製程式碼

登陸任意一臺伺服器,初始化副本集(除了192.168.252.121)

mongo --port 27003
複製程式碼

使用admin資料庫

use admin
複製程式碼

定義副本集配置

config = {
    _id : "shard3",
     members : [
         {_id : 0, host : "192.168.252.121:27003" },
         {_id : 1, host : "192.168.252.122:27003" , arbiterOnly: true},
         {_id : 2, host : "192.168.252.123:27003" }
     ]
 }
複製程式碼

初始化副本集配置

rs.initiate(config)
複製程式碼

響應內容如下

> use admin
switched to db admin
> config = {
...     _id : "shard3",
...      members : [
...          {_id : 0, host : "192.168.252.121:27003" },
...          {_id : 1, host : "192.168.252.122:27003" , arbiterOnly: true},
...          {_id : 2, host : "192.168.252.123:27003" }
...      ]
...  }
{
	"_id" : "shard3",
	"members" : [
		{
			"_id" : 0,
			"host" : "192.168.252.121:27003"
		},
		{
			"_id" : 1,
			"host" : "192.168.252.122:27003",
			"arbiterOnly" : true
		},
		{
			"_id" : 2,
			"host" : "192.168.252.123:27003"
		}
	]
}
> rs.initiate(config)
{ "ok" : 1 }
shard3:SECONDARY> rs.status()
複製程式碼

3.4 配置路由伺服器 mongos

(三臺機器)先啟動配置伺服器和分片伺服器,後啟動路由例項啟動路由例項:

vi /usr/local/mongodb/conf/mongos.conf

#內容
pidfilepath = /usr/local/mongodb/mongos/log/mongos.pid
logpath = /usr/local/mongodb/mongos/log/mongos.log
logappend = true

bind_ip = 0.0.0.0
port = 20000
fork = true

#監聽的配置伺服器,只能有1個或者3個 configs為配置伺服器的副本集名字
configdb = configs/192.168.252.121:21000,192.168.252.122:21000,192.168.252.123:21000
 
#設定最大連線數
maxConns = 20000
複製程式碼

啟動三臺伺服器的mongos server

mongos -f /usr/local/mongodb/conf/mongos.conf
複製程式碼

4. 串聯路由伺服器

目前搭建了mongodb配置伺服器、路由伺服器,各個分片伺服器,不過應用程式連線到mongos路由伺服器並不能使用分片機制,還需要在程式裡設定分片配置,讓分片生效。

登陸任意一臺mongos

mongo --port 20000
複製程式碼

使用admin資料庫

use  admin
複製程式碼

串聯路由伺服器與分配副本集

sh.addShard("shard1/192.168.252.121:27001,192.168.252.122:27001,192.168.252.123:27001");
sh.addShard("shard2/192.168.252.121:27002,192.168.252.122:27002,192.168.252.123:27002");
sh.addShard("shard3/192.168.252.121:27003,192.168.252.122:27003,192.168.252.123:27003");
複製程式碼

檢視叢集狀態

sh.status()
複製程式碼

響應內容如下

mongos> sh.status()
--- Sharding Status --- 
  sharding version: {
  	"_id" : 1,
  	"minCompatibleVersion" : 5,
  	"currentVersion" : 6,
  	"clusterId" : ObjectId("5a713a37d56e076f3eb47acf")
  }
  shards:
        {  "_id" : "shard1",  "host" : "shard1/192.168.252.121:27001,192.168.252.122:27001",  "state" : 1 }
        {  "_id" : "shard2",  "host" : "shard2/192.168.252.122:27002,192.168.252.123:27002",  "state" : 1 }
        {  "_id" : "shard3",  "host" : "shard3/192.168.252.121:27003,192.168.252.123:27003",  "state" : 1 }
  active mongoses:
        "3.6.2" : 3
  autosplit:
        Currently enabled: yes
  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:
        {  "_id" : "config",  "primary" : "config",  "partitioned" : true }

mongos> 
複製程式碼

5. 啟用集合分片生效

目前配置服務、路由服務、分片服務、副本集服務都已經串聯起來了,但我們的目的是希望插入資料,資料能夠自動分片。連線在mongos上,準備讓指定的資料庫、指定的集合分片生效。

登陸任意一臺mongos

mongo --port 20000
複製程式碼

使用admin資料庫

use  admin
複製程式碼

指定testdb分片生效

db.runCommand( { enablesharding :"testdb"});
複製程式碼

指定資料庫裡需要分片的集合和片鍵,雜湊id 分片

db.runCommand( { shardcollection : "testdb.table1",key : {"id": "hashed"} } );
複製程式碼

我們設定testdb的 table1 表需要分片,根據 id 自動分片到 shard1 ,shard2,shard3 上面去。要這樣設定是因為不是所有mongodb 的資料庫和表 都需要分片!

測試分片配置結果

連線 MongoDB 路由服務

mongo  127.0.0.1:20000
複製程式碼

切換到 testdb 資料庫

use  testdb;
複製程式碼

插入測試資料

for(i=1;i<=100000;i++){db.table1.insert({"id":i,"name":"penglei"})};
複製程式碼

總條數

db.table1.aggregate([{$group : {_id : "$name", totle : {$sum : 1}}}])
複製程式碼

檢視分片情況如下

  • shard1: "count": 33755
  • shard2: "count": 33143,
  • shard3: "count": 33102

結論資料基本均勻

db.table1.stats();
複製程式碼
mongos> db.table1.stats();
{
    "sharded": true,
    "capped": false,
    "ns": "testdb.table1",
    "count": 100000,
    "size": 5200000,
    "storageSize": 1519616,
    "totalIndexSize": 3530752,
    "indexSizes": {
        "_id_": 892928,
        "id_hashed": 2637824
    },
    "avgObjSize": 52,
    "nindexes": 2,
    "nchunks": 6,
    "shards": {
        "shard1": {
            "ns": "testdb.table1",
            "size": 1755260,
            "count": 33755,
            "avgObjSize": 52,
            "storageSize": 532480,
            "capped": false,
            "wiredTiger": {
			...省略很多
            }
        },
        "shard2": {
            "ns": "testdb.table1",
            "size": 1723436,
            "count": 33143,
            "avgObjSize": 52,
            "storageSize": 479232,
            "capped": false,
            "wiredTiger": {
			...省略很多
            }
        },
        "shard3": {
            "ns": "testdb.table1",
            "size": 1721304,
            "count": 33102,
            "avgObjSize": 52,
            "storageSize": 507904,
            "capped": false,
            "wiredTiger": {
			...省略很多
            }
        }
    },
    "ok": 1,
    "$clusterTime": {
        "clusterTime": Timestamp(1517488062, 350),
        "signature": {
            "hash": BinData(0, "AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
            "keyId": NumberLong(0)
        }
    },
    "operationTime": Timestamp(1517488062, 350)
}
mongos> 
複製程式碼

分組檢視總數量是:100000

mongos> db.table1.aggregate([{$group : {_id : "$name", totle : {$sum : 1}}}])
{ "_id" : "penglei", "totle" : 100000 }
mongos>
複製程式碼

後期運維

參考

手把手教你 MongoDB 的安裝與詳細使用(一)

www.ymq.io/2018/01/26/…

手把手教你 MongoDB 的安裝與詳細使用(二)

www.ymq.io/2018/01/29/…

建立索引

db.table1.createIndex({"name":1})
db.table1.getIndexes()
複製程式碼

啟動

mongodb的啟動順序是,先啟動配置伺服器,在啟動分片,最後啟動mongos.

mongod -f /usr/local/mongodb/conf/config.conf
mongod -f /usr/local/mongodb/conf/shard1.conf
mongod -f /usr/local/mongodb/conf/shard2.conf
mongod -f /usr/local/mongodb/conf/shard3.conf
mongos -f /usr/local/mongodb/conf/mongos.conf
複製程式碼

啟動報錯

about to fork child process, waiting until server is ready for connections.
forked process: 1303
child process started successfully, parent exiting
[root@node1 ~]# mongod -f /usr/local/mongodb/conf/shard1.conf
about to fork child process, waiting until server is ready for connections.
forked process: 1384
複製程式碼

刪除 mongod.lock

cd /usr/local/mongodb/shard1/data
rm -rf mongod.lock
複製程式碼

關閉防火牆(不關防火牆也會遇到這樣的問題)

systemctl stop firewalld.service 
複製程式碼

關閉

#debian、ubuntu系統下:

apt-get install psmisc

#centos或、rhel系統下:

yum install psmisc
複製程式碼

關閉時,直接killall殺掉所有程式

killall mongod
killall mongos
複製程式碼

參考:

mongodb 3.4 叢集搭建:分片+副本集 www.ityouknow.com/mongodb/201…

Runoob 教程:http://www.runoob.com/mongodb/mongodb-tutorial.html
Tutorials 教程:Pointhttps://www.tutorialspoint.com/mongodb/mongodb_advantages.htm
MongoDB 官網地址:https://www.mongodb.com
MongoDB 官方英文文件:https://docs.mongodb.com/manual
MongoDB 各平臺下載地址:https://www.mongodb.com/download-center#community
MongoDB 安裝 https://docs.mongodb.com/manual/tutorial/install-mongodb-enterprise-on-ubuntu

Contact

關注公眾號-搜雲庫
搜雲庫

相關文章