Linux搭建MongoDB分片集群


一、介紹

1、基本介紹

MongoDB部署架構分為單機、復制集群、分片集群。單機適合學習用,分片集群比較復雜且運維難度高。

分片集群是把大型數據集進行拆分,分片到多個MongoDB節點上,這些節點組成了分片集群。分片結構如下:

2、詞匯表

Shard:分片,存儲集群中的一部分數據。可以是單個mongo服務器,也可以是復制集。生產環境推薦使用復制集。

Config Server:配置服務器。存儲集群的元數據,比如集群的分片信息。mongos 啟動時會從配置服務器讀取元數據到內存中。配置服務器必須是復制集。

Routers:mongos 路由。負責接收客戶端請求,並將請求路由到集群內部對應的分片上。

Shard Key:分片鍵。對於每個需要分片的 collection,通過指定分片鍵進行分片。分片鍵必須是索引字段或者是組合索引的左前綴。

Range分區:范圍分區算法。分片鍵必須是數字或者字符串類型,根據分片鍵將數據分成不同的 chunk,每個 chunk 互相臨近但不重疊。

Hash分區:哈希分區算法。計算分片鍵的hash值,並以此作為 Range 分區。這種方式可以將document更加隨機的分散到不同 chunk 上

 

二、環境准備

虛擬機三台(Centos7.6),分別安裝好MongoDB

分片集群中,一共10個節點:2個分片(每個分片是3個復制集), 1個config(3個復制集),1個路由。

服務網格信息如下:

角色 IP Node
分片0復制集 192.168.20.100:27017、192.168.20.101:27017、192.168.20.102:27017 1主1從1仲裁
分片1復制集 192.168.20.100:27018、192.168.20.101:27018、192.168.20.102:27018 1主1從1仲裁
config復制集 192.168.20.100:28018、192.168.20.101:28018、192.168.20.102:28018 1主2從
mongos節點 192.168.20.100:29019  

 

三、搭建 Shard

1、在100/101/102機器上,創建目錄:

mkdir -p /usr/local/mongo/share/data/db      #分片0的數據保存路徑
mkdir -p /usr/local/mongo/share/data/db2    #分片1的數據保存路徑
mkdir -p /usr/local/mongo/share/conf
mkdir -p /usr/local/mongo/share/pids
mkdir -p /usr/local/mongo/share/logs

2、在100/101/102機器上,/usr/local/mongo/share/conf 目錄下,添加分片0復制集的配置文件:mongo.conf :

#數據保存路徑
dbpath=/usr/local/mongo/share/data/db/
#日志保存路徑
logpath=/usr/local/mongo/share/logs/mongo.log
#進程描述文件
pidfilepath=/usr/local/mongo/share/pids/mongo.pid
#日志追加寫入
logappend=true
#復制集名稱
replSet=rs0
bind_ip_all=true
#mongo端口
port=27017
#操作日志容量
oplogSize=10000
#開啟子進程
fork=true
#代表當前節點是一個shard節點
shardsvr=true

3、在100/101/102機器上,/usr/local/mongo/share/conf 目錄下,添加分片1復制集的配置文件:mongo2.conf :

#數據保存路徑
dbpath=/usr/local/mongo/share/data/db2/
#日志保存路徑
logpath=/usr/local/mongo/share/logs/mongo2.log
#進程描述文件
pidfilepath=/usr/local/mongo/share/pids/mongo2.pid
#日志追加寫入
logappend=true
#復制集名稱
replSet=rs1
bind_ip_all=true
#mongo端口
port=27018
#操作日志容量
oplogSize=10000
#開啟子進程
fork=true
#代表當前節點是一個shard節點
shardsvr=true

4、在100/101/102機器上,分別啟動 mongod 服務:

#分片0(rs0)
/usr/local/mongo/bin/mongod -f /usr/local/mongo/share/conf/mongo.conf
#分片1(rs1)
/usr/local/mongo/bin/mongod -f /usr/local/mongo/share/conf/mongo2.conf

5、登錄復制集:

#分片0(rs0)
/usr/local/mongo/bin/mongo --host 192.168.20.100 --port 27017
#分片1(rs1)
/usr/local/mongo/bin/mongo --host 192.168.20.100 --port 27018

6、初始化復制集:

#分片0(rs0)
rs.initiate({
    _id:"rs0",
    members:[
        {_id:0, host:"192.168.20.100:27017", priority:3},
        {_id:1, host:"192.168.20.101:27017", priority:2},
        {_id:2, host:"192.168.20.102:27017", arbiterOnly:true}
    ]
});
#分片1(rs1)
rs.initiate({
    _id:"rs1",
    members:[
        {_id:0, host:"192.168.20.100:27018", priority:3},
        {_id:1, host:"192.168.20.101:27018", priority:2},
        {_id:2, host:"192.168.20.102:27018", arbiterOnly:true}
    ]
});

 

四、搭建Config Server

1、在100/101/102機器上,創建目錄:

mkdir -p /usr/local/mongo/config-server/data/db
mkdir -p /usr/local/mongo/config-server/conf
mkdir -p /usr/local/mongo/config-server/pids
mkdir -p /usr/local/mongo/config-server/logs

2、在100/101/102機器上,/usr/local/mongo/config-server/conf 目錄下,添加復制集的配置文件:mongo-cfg.conf

dbpath=/usr/local/mongo/config-server/data/db
logpath=/usr/local/mongo/config-server/logs/mongo.log
pidfilepath=/usr/local/mongo/config-server/pids/mongo.pid
logappend=true
replSet=rs_conf
bind_ip_all=true
port=28018
oplogSize=10000
fork=true
#代表當前節點是一個config節點
configsvr=true

3、在100/101/102機器上,分別啟動配置復制集:

/usr/local/mongo/bin/mongod -f /usr/local/mongo/config-server/conf/mongo-cfg.conf

4、登錄復制集:

/usr/local/mongo/bin/mongo --host 192.168.20.100 --port 28018

5、初始化復制集:

rs.initiate({
    _id:"rs_conf",
    configsvr: true,
    members:[
        {_id:0, host:"192.168.20.100:28018", priority:2},
        {_id:1, host:"192.168.20.101:28018", priority:1},
        {_id:2, host:"192.168.20.102:28018", priority:1}
    ]
});

 

五、搭建Router

本案例只配置了一個Router,生產環境通常配置多個。Router不需要數據目錄(dbpath),只需要提供 config server 信息

1、在100機器上,創建目錄:

mkdir -p /usr/local/mongo/router/conf
mkdir -p /usr/local/mongo/router/pids
mkdir -p /usr/local/mongo/router/logs

2、在 /usr/local/mongo/router/conf 目錄下,創建 Router 的配置文件:mongo-router.conf

configdb=rs_conf/192.168.20.100:28018,192.168.20.101:28018,192.168.20.102:28018
logpath=/usr/local/mongo/router/logs/mongos.log
pidfilepath=/usr/local/mongo/router/pids/mongos.pid
port=29019
fork=true
bind_ip_all=true

3、啟動 Router 服務:

/usr/local/mongo/bin/mongos -f /usr/local/mongo/router/conf/mongo-router.conf

4、連接 Router 節點:

/usr/local/mongo/bin/mongo --host 192.168.20.100 --port 29019

5、切換到 admin 庫

use admin

6、添加分片信息:

#分片0
db.runCommand({addShard: "rs0/192.168.20.100:27017,192.168.20.101:27017,192.168.20.102:27017", name: "share0"});
#分片1
db.runCommand({addShard: "rs1/192.168.20.100:27018,192.168.20.101:27018,192.168.20.102:27018", name: "share1"});

7、查看分片:

db.runCommand({listshards: 1})

8、查看分片狀態:

sh.status()

 

六、測試

1、測試分片--哈希策略

連接 Router 節點並切換到 admin 庫。對測試庫 xwjdb 開啟分片功能:

sh.enableSharding("xwjdb")

對集合 account 分片,分片鍵為 nickname,分片策略為哈希:

sh.shardCollection("xwjdb.account", {"nickname": "hashed"})

切換到 xwjdb 庫。向 account 集合中,循環插入1000條數據:

use xwjdb
for(var i=1; i<=1000; i++){db.account.insert({_id: i+"", nickname: "xwj"+i})}

分別連接 分片0 和 分片1 節點,並切換到 xwjdb 庫。查詢 account 集合數據條數:

use xwjdb
db.account.count()

分片0的數據是505條,分片2是495條,總數正好是1000條,說明數據分片成功了

結論:基於哈希策略的分片算法,數據會均勻的分配到不同的分片節點上

2、測試分片-范圍策略

數據塊(chunk)默認大小是64M,填滿后才會考慮向其它片的數據塊填充數據,因此,為了測試可以將其改小,這里改為1M:

use config
db.setting.save({"_id": "chunksize", "value": 1})

切換到 admin 庫。對測試庫 testdb 開啟分片功能:

sh.enableSharding("testdb")

對集合 person 分片,分片鍵為主鍵id,分片策略為范圍:

sh.shardCollection("testdb.person",{_id:1});

切換到庫 testdb。向 person 集合中,批量插入4000000條數據(數據少了可能只落在一個分片上):

use testdb
var arr=[]
for(var i=1; i<=4000000; i++){arr.push({"_id":i,"username":"user"+i,"createdate":new Date()})}
db.person.insertMany(arr)

分別連接 分片0 和 分片1 節點,並切換到 testdb 庫。查詢 account 集合數據條數:

use testdb
db.person.count()

 

  

七、其它

1、一個集合只能有一個分片鍵

2、庫和集合默認是不分片的,對於不分片的庫或者集合,數據均會保存在 primary shard上,直到開啟分片才會在集群中分布

3、刪除所有數據和日志信息(刪除后,所有配置信息也被刪掉了):

rm -rf /usr/local/mongo/config-server/logs/*
rm -rf /usr/local/mongo/config-server/data/db/*
rm -rf /usr/local/mongo/share/data/db/*
rm -rf /usr/local/mongo/share/data/db2/*
rm -rf /usr/local/mongo/share/logs/*
rm -rf /usr/local/mongo/router/logs/*

4、刪除分片鍵命令:

use config
db.collections.remove( { _id: "testdb.person" } )
db.chunks.remove( { ns: "testdb.person" } )
db.locks.remove( { _id: "testdb.person" } )
use admin
db.adminCommand("flushRouterConfig")

5、查詢chunk大小:

use config
db.setting.find()

 

八、踩坑

1、config server復制集初始化時,報錯:

問題原因:搭建config server復制集時,不能有仲裁節點(Arbiters),否則初始化失敗

解決辦法:復制集使用一主兩從

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM