MongoDB 分片叢集搭建

賀子_DBA時代發表於2019-12-19

一、概述

分片是一種在多臺機器上分配資料的方法。MongoDB使用分片來支援具有非常大的資料集和高吞吐量操作。有兩種解決系統增長的方法:垂直擴充套件和水平擴充套件。

垂直擴充套件涉及增加單個伺服器的容量,例如使用更強大的CPU,增加更多RAM或增加儲存空間量等。介於硬體成本和硬體效能單機器能支援的併發訪問和儲存容量是有限的因此,垂直擴充套件是存在最大上限的。

水平擴充套件包括將系統資料集和負載分配到多個伺服器上,新增額外的伺服器以根據需要增加容量。儘管單臺機器的整體速度或容量可能並不高,但每臺機器可處理整個工作負載的一部分,效率可能會高於單臺高速大容量伺服器。而且很多時候可以選擇成本很低的普通PC電腦;與單臺機器的高階硬體相比,總成本可能會更低,但是增加了維護的複雜性。

 

MongoDB版本:3.6 

二、分片叢集架構

1).分片

分片的含義是指將資料拆分,將其分散存放在不同的機器上的過程,MongoDB的分片機制允許你建立一個包含許多臺機器的叢集,將資料子集分散在叢集中,每一個分片維護著一個資料集合的子集。與單機伺服器和副本集相比,使用分片叢集架構可以使應用程式具有更大的資料處理能力。

備註:每一個分片都是由一個副本集組成。從MongoDB 3.6版本之後,分片必須是副本集。

2).配置伺服器

配置伺服器是整個叢集的大腦,儲存著叢集和分片的後設資料庫,比如:分片資訊、群集資料庫資訊、分片集合資訊、塊資訊、平衡器資訊、版本資訊、群集操作日誌、相關設定資訊等。因此配置伺服器資料必須儲存在非易失性驅動器上。每個配置伺服器都應該位於單獨的物理機器上,最好是異地分佈,同時還需要啟用日誌功能。

備註:在Mongos3.4版本之後,配置伺服器也必須是副本集。

3).Mongos程式

Mongos提供客戶端應用程式和分片群集之間的介面。

部署多個mongos支援高可用性和可伸縮性;常見的模式是mongos在每個應用程式伺服器上部署一個 ,在每個應用程式伺服器上部署一個 可減少應用程式和之間的網路延遲。或者您可以專用的伺服器上部署mongos。大型部署一般使用此方法,因為它將客戶端應用程式伺服器與mongos分離 這可以更好地控制mongod例項的連線數量。

可以在主分片上部署mongos,mongos不會與mongod例項共享記憶體。需要注意記憶體爭用可能導致的問題。

理論上可以部署無數個mongos路由。但是由於mongos路由經常與配置伺服器進行通訊,所以在增加mongos數量時應該密切監視配置伺服器的效能。如果您看到效能下降,應該現在mongos的數量

三、部署分片 

1).環境

192.168.137.10:rs-a-1:27010;rs-a-2:27011;rs-a-3:27012

192.168.137.20:rs-b-1:28010;rs-b-2:28011;rs-b-3:28012

192.168.137.30:config-1:29010,config-2:29011;config-3:29012;mongos:30000

rs-a分片副本集配置

--------------rs-a-1配置-------------------------
pidfilepath = /rs-a-1/mongod.pid
logpath = /rs-a-1/data/log/mongod.log
dbpath = /rs-a-1/data/db
logappend = true
port = 27010
fork = true
auth = true
replSet = rs-a
shardsvr = true
keyFile = /rs-a-1/autokey

--------------rs-a-2配置-------------------------
pidfilepath = /rs-a-2/mongod.pid
logpath = /rs-a-2/data/log/mongod.log
dbpath = /rs-a-2/data/db
logappend = true
port = 27011
fork = true
auth = true
replSet = rs-a
shardsvr = true
keyFile = /rs-a-2/autokey

--------------rs-a-3配置-------------------------
logpath = /rs-a-3/data/log/mongod.log
dbpath = /rs-a-3/data/db
logappend = true
port = 27012
fork = true
auth = true
replSet = rs-a
shardsvr = true
keyFile = /rs-a-3/autokey

rs-b分片副本集配置

--------------rs-b-1配置-------------------------
pidfilepath = /rs-b-1/mongod.pid
logpath = /rs-b-1/data/log/mongod.log
dbpath = /rs-b-1/data/db
logappend = true
port = 28010
fork = true
auth = true
replSet = rs-b
shardsvr = true
keyFile = /rs-b-1/autokey

--------------rs-b-2配置-------------------------
pidfilepath = /rs-b-2/mongod.pid
logpath = /rs-b-2/data/log/mongod.log
dbpath = /rs-b-2/data/db
logappend = true
port = 28011
fork = true
auth = true
replSet = rs-b
shardsvr = true
keyFile = /rs-b-2/autokey

--------------rs-b-3配置-------------------------
pidfilepath = /rs-b-3/mongod.pid
logpath = /rs-b-3/data/log/mongod.log
dbpath = /rs-b-3/data/db
logappend = true
port = 28012
fork = true
auth = true
replSet = rs-b
shardsvr = true
keyFile = /rs-b-3/autokey

config配置伺服器配置

--------------config-1配置-------------------------
pidfilepath = /config-1/mongod.pid
logpath = /config-1/data/log/mongod.log
dbpath = /config-1/data/db
logappend = true
port = 29010
fork = true
auth = true
configsvr = true
replSet = config
keyFile = /config-1/autokey

--------------config-2配置-------------------------
pidfilepath = /config-2/mongod.pid
logpath = /config-2/data/log/mongod.log
dbpath = /config-2/data/db
logappend = true
port = 29011
fork = true
auth = true
configsvr = true
replSet = config
keyFile = /config-2/autokey

--------------config-3配置-------------------------
logpath = /config-3/data/log/mongod.log
dbpath = /config-3/data/db
logappend = true
port = 29012
fork = true
auth = true
configsvr = true
replSet = config
keyFile = /config-3/autokey

Mongos路由配置

configdb = config/192.168.137.30:29010,192.168.137.30:29011,192.168.137.30:29012
port = 30000
logpath = /mongos/log/route.log
bind_ip = 192.168.137.30,127.0.0.1
logappend = true
fork = true
keyFile = /mongos/autokey
maxConns=20000

備註:

1.當前為了便於理解所以節點的分佈不合理,如果是真實的生成環境每個資料節點都應該分開。

2.注意分片的分片節點的配置檔案中需要增加“shardsvr = true”,conf節點需要增加"configsvr = true"的啟動配置引數;可以參考yaml格式:https://www.cnblogs.com/chenmh/p/9544346.html

 

2).分片配置

1.啟動所有分片副本集(rs-a,rs-b)和配置伺服器(config)

具體方法可以參考我前面寫的搭建副本集的文章。

MongoDB 搭建可複製群集:http://www.cnblogs.com/chenmh/p/8484049.html

2.啟動mongos路由

mongos --config /mongos/mongos.conf

3.分片配置

登入驗證

mongo --port 30000
use admin
db.auth("dba","dba")

新增分片

sh.addShard("rs-a/192.168.137.10:27010,192.168.137.10:27011,192.168.137.10:27012");
sh.addShard("rs-b/192.168.137.20:28010,192.168.137.20:28011,192.168.137.20:28012");

文件分片

use admin
sh.enableSharding("test");
sh.shardCollection("test.person",{_id:1});
sh.enableSharding("news");
sh.shardCollection("news.person",{"username":"hashed"});

備註:這裡的分片方式有1,-1,hashed三種;

1.如果分片集合是空集合那麼可以不需要提前建立索引,對集合分片預設會對分片欄位建立索引。

2.如果分片集合是非空集合那麼需要手動建立索引。

3.如果分片集合存在唯一索引,那麼分片必須是唯一索引上的鍵。

具體參考:https://docs.mongodb.com/manual/reference/method/sh.shardCollection/index.html

插入測試資料

use test;
for(var i=0;i<100000;i++){ db.person.insert({"_id":i,"username":"user"+i,"createdate":new Date()})}
use news;
for(var i=0;i<100000;i++){ db.person.insert({"_id":i,"username":"user"+i,"createdate":new Date()})}

3).查詢

sh.status();

備註:可以看到rs-a;rs-b兩個分片上的資料庫塊都是一樣的,分佈的很均勻,接下來看一下增加一個新分片之後資料庫塊的分佈情況。

4).新增新分片

 備註:新增新的分片之後,mongos再一次移動了資料塊,保證資料塊在每一個分片上都均勻的分佈。資料庫的移動是非同步的。

 四、總結

Mongos採取非同步的方式將資料塊移動到其它的分片,資料塊不能設的太小否則對於密集寫的系統所有的寫操作會集中到一個分片上,最後非同步移動資料塊到其它的分片。

 

 

 

 

 

 

備註:

    作者:pursuer.chen

    部落格:http://www.cnblogs.com/chenmh

本站點所有隨筆都是原創,歡迎大家轉載;但轉載時必須註明文章來源,且在文章開頭明顯處給明連結,否則保留追究責任的權利。

《歡迎交流討論》

 

相關文章