1. 程式人生 > >MongoDB3.6分片復制集群

MongoDB3.6分片復制集群

path .org collect 0.10 x86_64 ren 登錄 state 們的

概念

  • mongos
    數據庫集群請求的入口,所有的請求都通過mongos進行協調,不需要在應用程序添加一個路由選擇器,mongos自己就是一個請求分發中心,它負責把對應的數據請求請求轉發到對應的shard服務器上。在生產環境通常有多mongos作為請求的入口,防止其中一個掛掉所有的mongodb請求都沒有辦法操作。
  • config server
    顧名思義為配置服務器,存儲所有數據庫元信息(路由、分片)的配置。mongos本身沒有物理存儲分片服務器和數據路由信息,只是緩存在內存裏,配置服務器則實際存儲這些數據。mongos第一次啟動或者關掉重啟就會從 config server 加載配置信息,以後如果配置服務器信息變化會通知到所有的 mongos 更新自己的狀態,這樣 mongos 就能繼續準確路由。在生產環境通常有多個 config server 配置服務器,因為它存儲了分片路由的元數據,防止數據丟失!
  • shard
    分片(sharding)是指將數據庫拆分,將其分散在不同的機器上的過程。將數據分散到不同的機器上,不需要功能強大的服務器就可以存儲更多的數據和處理更大的負載。基本思想就是將集合切成小塊,這些塊分散到若幹片裏,每個片只負責總數據的一部分,最後通過一個均衡器來對各個分片進行均衡(數據遷移)。
  • replica set
    中文翻譯副本集,其實就是shard的備份,防止shard掛掉之後數據丟失。復制提供了數據的冗余備份,並在多個服務器上存儲數據副本,提高了數據的可用性, 並可以保證數據的安全性。
  • 仲裁者(Arbiter)
    是復制集中的一個MongoDB實例,它並不保存數據。仲裁節點使用最小的資源並且不要求硬件設備,不能將Arbiter部署在同一個數據集節點中,可以部署在其他應用服務器或者監視服務器中,也可部署在單獨的虛擬機中。為了確保復制集中有奇數的投票成員(包括primary),需要添加仲裁節點做為投票,否則primary不能運行時不會自動切換primary。

總結一下,應用請求mongos來操作mongodb的增刪改查,配置服務器存儲數據庫元信息,並且和mongos做同步,數據最終存入在shard(分片)上,為了防止數據丟失同步在副本集中存儲了一份,仲裁在數據存儲到分片的時候決定存儲到哪個節點。

環境準備

系統:cenos7.4
服務器: 10.10.16.52/53/54
mongodb包: mongodb-linux-x86_64-rhel70-3.6.3.tgz

規劃

mongodb-16-52 mongodb-16-53 mongodb-16-54
mongos/20000 mongos/20000 mongos/20000
config server/21000 config server/21000 config server/21000
shard server1 主節點(27001) shard server1 副節點(27001) shard server1 仲裁(27001)
shard server2 仲裁(27002) shard server2 主節點(27002) shard server2 副節點(27002)
shard server3副節點(27003) shard server1 仲裁(27003) shard server3 主節點(27003)

集群搭建

安裝mongodb

wget https://fastdl.mongodb.org/linux/mongodb-linux-x86_64-rhel70-3.6.3.tgz
cd /usr/lcoal/
ln -sf mongodb-linux-x86_64-rhel70-3.6.3/ mongodb

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

mkdir -p /data/mongodb/conf
mkdir -p /data/mongodb/mongos/log
mkdir -p /data/mongodb/config/data
mkdir -p /data/mongodb/config/log
mkdir -p /data/mongodb/shard1/data
mkdir -p /data/mongodb/shard1/log
mkdir -p /data/mongodb/shard2/data
mkdir -p /data/mongodb/shard2/log
mkdir -p /data/mongodb/shard3/data
mkdir -p /data/mongodb/shard3/log

添加用戶、配置環境變量

useradd -M -u 8000 -s /sbin/nologin mongo
chown -R mongo.mongo /usr/local/mongodb
chown -R mongo.mongo /data/mongodb

config server 配置服務

mongodb3.4以後要求配置服務器也創建副本集,不然集群搭建不成功

添加配置文件

cat >> /data/mongodb/conf/config.conf << EOF
## 配置文件內容
pidfilepath = /data/mongodb/config/log/config-srv.pid
dbpath = /data/mongodb/config/data
logpath = /data/mongodb/config/log/config-srv.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
EOF

systemd 啟動腳本

cat >> /usr/lib/systemd/system/mongo-config.service << EOF
[Unit]  
  
Description=mongodb-config   
After=network.target remote-fs.target nss-lookup.target  
  
[Service]  
Type=forking
User=mongo
Group=mongo
ExecStart=/usr/local/mongodb/bin/mongod -f /data/mongodb/conf/config.conf
ExecReload=/bin/kill -s HUP $MAINPID  
ExecStop=/usr/local/mongodb/bin/mongod --shutdown -f /data/mongodb/conf/config.conf 
PrivateTmp=true  
    
[Install]  
WantedBy=multi-user.target 
EOF

啟動三臺服務器的config server

systemctl daemon-reload 
systemctl start mongo-config
systemctl enable mongo-config

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

mongo --port 21000   //登陸

#config變量
config = {
...    _id : "configs",
...     members : [
...         {_id : 0, host : "10.10.16.52:21000" },
...         {_id : 1, host : "10.10.16.53:21000" },
...         {_id : 2, host : "10.10.16.54:21000" }
...     ]
... }

#初始化副本集
rs.initiate(config)
# 查看集群狀態
rs.status()

其中,_id :,configs應與配置文件中配置的 replicaction.replSetName 一致,members 中的 host 為三個節點的 ipport

配置分片副本集(三臺機器)

設置第一個分片副本集

配置文件

cat >> /data/mongodb/conf/shard1.conf << EOF
pidfilepath = /data/mongodb/shard1/log/shard1.pid
dbpath = /data/mongodb/shard1/data
logpath = /data/mongodb/shard1/log/shard1.log
logappend = true
journal = true
quiet = 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
EOF

systemd 啟動腳本

cat >> /usr/lib/systemd/system/mongo-shard1.service << EOF
[Unit]  
  
Description=mongodb-shard1  
After= mongo-config.target network.target
  
[Service]  
Type=forking
User=mongo
Group=mongo
ExecStart=/usr/local/mongodb/bin/mongod -f /data/mongodb/conf/shard1.conf
ExecReload=/bin/kill -s HUP $MAINPID  
ExecStop=/usr/local/mongodb/bin/mongod --shutdown -f /data/mongodb/conf/shard1.conf 
PrivateTmp=true  
    
[Install]  
WantedBy=multi-user.target 
EOF

啟動三臺服務器的shard1 server

systemctl daemon-reload 
systemctl start mongo-shard1
systemctl enable mongo-shard1

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

mongo --port 27001
#使用admin數據庫
use admin
#定義副本集配置,第三個節點的 "arbiterOnly":true 代表其為仲裁節點。不可為當前初始化設置的節點

config = {
...    _id : "shard1",
...     members : [
...         {_id : 0, host : "10.10.16.52:27001" },
...         {_id : 1, host : "10.10.16.53:27001" },
...         {_id : 2, host : "10.10.16.54:27001" , arbiterOnly: true }
...     ]
... }

#初始化副本集配置
rs.initiate(config);

rs.status()

設置第二個分片副本集

配置文件

cat >> /data/mongodb/conf/shard2.conf << EOF
pidfilepath = /data/mongodb/shard2/log/shard2.pid
dbpath = /data/mongodb/shard2/data
logpath = /data/mongodb/shard2/log/shard2.log
logappend = true
journal = true
quiet = 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
EOF

systemd 啟動腳本

cat >> /usr/lib/systemd/system/mongo-shard2.service << EOF
[Unit]  
  
Description=mongodb-shard2  
After= mongo-config.target network.target
  
[Service]  
Type=forking
User=mongo
Group=mongo
ExecStart=/usr/local/mongodb/bin/mongod -f /data/mongodb/conf/shard2.conf
ExecReload=/bin/kill -s HUP $MAINPID  
ExecStop=/usr/local/mongodb/bin/mongod --shutdown -f /data/mongodb/conf/shard2.conf 
PrivateTmp=true  
    
[Install]  
WantedBy=multi-user.target 
EOF

啟動三臺服務器的shard2 server

systemctl daemon-reload 
systemctl start mongo-shard2
systemctl enable mongo-shard2

初始化副本集
登錄任意一臺配置服務器,任意選一臺服務器(註意:不要選擇即將要設置為仲裁節點的服務器)

mongo --port 27002
#使用admin數據庫
use admin
#定義副本集配置,第三個節點的 "arbiterOnly":true 代表其為仲裁節點。不可為當前初始化設置的節點

config = {
...    _id : "shard2",
...     members : [
...         {_id : 0, host : "10.10.16.52:27002", arbiterOnly: true  },
...         {_id : 1, host : "10.10.16.53:27002" },
...         {_id : 2, host : "10.10.16.54:27002" }
...     ]
... }

#初始化副本集配置
rs.initiate(config);
rs.status()

設置第三個分片副本集

配置文件

cat >> /data/mongodb/conf/shard3.conf << EOF
pidfilepath = /data/mongodb/shard3/log/shard3.pid
dbpath = /data/mongodb/shard3/data
logpath = /data/mongodb/shard3/log/shard3.log
logappend = true
journal = true
quiet = 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
EOF

systemd 啟動腳本

cat >> /usr/lib/systemd/system/mongo-shard3.service << EOF
[Unit]  
  
Description=mongodb-shard3  
After= mongo-config.target network.target
  
[Service]  
Type=forking
User=mongo
Group=mongo
ExecStart=/usr/local/mongodb/bin/mongod -f /data/mongodb/conf/shard3.conf
ExecReload=/bin/kill -s HUP $MAINPID  
ExecStop=/usr/local/mongodb/bin/mongod --shutdown -f /data/mongodb/conf/shard3.conf 
PrivateTmp=true  
    
[Install]  
WantedBy=multi-user.target 
EOF

啟動三臺服務器的shard3 server

systemctl daemon-reload 
systemctl start mongo-shard3
systemctl enable mongo-shard3

初始化副本集
登錄任意一臺配置服務器,任意選一臺服務器(註意:不要選擇即將要設置為仲裁節點的服務器)

mongo --port 27003

#使用admin數據庫
use admin

#定義副本集配置,第三個節點的 "arbiterOnly":true 代表其為仲裁節點。不可為當前初始化設置的節點

config = {
...    _id : "shard3",
...     members : [
...         {_id : 0, host : "10.10.16.52:27003" },
...         {_id : 1, host : "10.10.16.53:27003",arbiterOnly: true },
...         {_id : 2, host : "10.10.16.54:27003" }
...     ]
... }

#初始化副本集配置
rs.initiate(config);
rs.status()

配置路由服務器 mongos

先啟動配置服務器和分片服務器,後啟動路由實例:(三臺機器)
配置文件

cat >> /data/mongodb/conf/mongos.conf << EOF
pidfilepath = /data/mongodb/mongos/log/mongos.pid
logpath = /data/mongodb/mongos/log/mongos.log
logappend = true

bind_ip = 0.0.0.0
port = 20000
fork = true

#監聽的配置服務器,只能有1個或者3個 configs為配置服務器的副本集名字
configdb = configs/10.10.16.52:21000,10.10.16.53:21000,10.10.16.54:21000
 
#設置最大連接數
maxConns=20000
EOF

systemd 啟動腳本

cat >> /usr/lib/systemd/system/mongos.service << EOF
[Unit]
Description=Mongo Router Service
After=mongo-config.service

[Service]
Type=forking
User=mongo
Group=mongo
ExecStart=/usr/local/mongodb/bin/mongos --config /data/mongodb/conf/mongos.conf
Restart=on-failure

[Install]
WantedBy=multi-user.target
EOF

啟動三臺服務器的mongos server

systemctl daemon-reload 
systemctl start mongos
systemctl enable mongos

啟用分片

目前搭建了mongodb配置服務器、路由服務器,各個分片服務器,不過應用程序連接到mongos路由服務器並不能使用分片機制,還需要在程序裏設置分片配置,讓分片生效。
登陸任意一臺mongos

mongo --port 20000
#使用admin數據庫
use admin
#串聯路由服務器與分配副本集
sh.addShard("shard1/10.10.16.52:27001,10.10.16.53:27001,10.10.16.54:27001")
sh.addShard("shard2/10.10.16.52:27002,10.10.16.53:27002,10.10.16.54:27002")
sh.addShard("shard3/10.10.16.52:27003,10.10.16.53:27003,10.10.16.54:27003")
#查看集群狀態
sh.status()


sh.status()
--- Sharding Status --- 
  sharding version: {
        "_id" : 1,
        "minCompatibleVersion" : 5,
        "currentVersion" : 6,
        "clusterId" : ObjectId("5a9a97f70d2d5d358998988d")
  }
  shards:
        {  "_id" : "shard1",  "host" : "shard1/10.10.16.52:27001,10.10.16.53:27001",  "state" : 1 }
        {  "_id" : "shard2",  "host" : "shard2/10.10.16.53:27002,10.10.16.54:27002",  "state" : 1 }
        {  "_id" : "shard3",  "host" : "shard3/10.10.16.52:27003,10.10.16.54:27003",  "state" : 1 }
  active mongoses:
        "3.6.3" : 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上,準備讓指定的數據庫、指定的集合分片生效。

#指定testdb分片生效
db.runCommand( { enablesharding :"testdb"});
#指定數據庫裏需要分片的集合和片鍵
db.runCommand( { shardcollection : "testdb.table1",key : {id: 1} } )

我們設置testdb的 table1 表需要分片,根據 id 自動分片到 shard1 ,shard2,shard3 上面去。要這樣設置是因為不是所有mongodb 的數據庫和表 都需要分片!
測試分片配置結果

mongo 127.0.0.1 --port 20000
#使用testdb
use  testdb;
#插入測試數據
for(i=1;i<=1000;i++){db.table1.insert({"id":i,"name":"lovego"})};
# 總條數
db.table1.aggregate([{$group : {_id : "$name", totle : {$sum : 1}}}])
{ "_id" : "lovego", "totle" : 100000 }

#查看分片情況如下,
db.table1.stats();

維護

啟動順序

systemctl start mongo-config
systemctl start mongo-shard1
systemctl start mongo-shard2
systemctl start mongo-shard3
systemctl start mongos

關閉順序

systemctl stop mongos
systemctl stop mongo-shard1
systemctl stop mongo-shard2
systemctl stop mongo-shard3
systemctl stop mongo-config

參考

https://cloud.tencent.com/developer/article/1034843
http://www.ityouknow.com/mongodb/2017/08/05/mongodb-cluster-setup.html
http://www.cnblogs.com/clsn/p/8214345.html

MongoDB3.6分片復制集群