1. 程式人生 > >搭建mongodb分片shard叢集

搭建mongodb分片shard叢集

MongoDB是一個高效能,開源,無模式的文件型資料庫,開發語言是C ++。它在許多場景下可用於替代傳統的關係型資料庫或鍵/值儲存方式。

優點:

1.面向集合儲存,易儲存物件型別的資料。

2.支援動態查詢。

3.支援完全索引,包含內部物件。

4.使用高效的二進位制資料儲存,包括大型物件(如視訊等)。

缺點:

1. mongodb不支援事務操作。

2. mongodb佔用空間過大。(在叢集分片中的資料分佈不均勻)

3.大資料量持續插入,寫入效能有較大波動

4.單機可靠性比較差

適用場景

1.適用於實時的插入,更新與查詢的需求,並具備應用程式實時資料儲存所需的複製及高度伸縮性;

2.非常適合文件化格式的儲存及查詢;

3.高伸縮性的場景:MongoDB非常適合由數十或者數百臺伺服器組成的資料庫。

4.對效能的關注超過對功能的要求。

 

搭建MongoDB的需要的瞭解的概念

我們先了解什麼是複製集

replica set(複製集)

最基礎的複製集架構是由三個成員組成的,且成員個數應該是奇數,包括一個主節點(主),一個從節點(二次),還有一個投票節點(仲裁器)。投票節點的作用僅僅是在選舉過程中參與投票,該節點中並不包含資料集,故所需資源很少,無需一個專用物理機。主節點和從節點的資料相同,用以備份資料,當主機宕機時,仲裁節點將投票,選出一個從節點做主節點。

碎片(分片)

我們再來看一張圖

從圖中可以看到有四個元件:mongos,config server,shard,replica set。

mongos,叢集請求的入口,分發讀寫請求到分片伺服器,前端應用透明訪問。

配置伺服器,儲存所有資料庫元資訊(路由,分片)的配置,mongos從配置伺服器載入配置資訊。生產環境中,為確保冗餘與安全,一般使用3臺配置伺服器,且必須部署在不同的機器上。

shard,分片是儲存了叢集一部分資料的mongod或者replica set,所有分片儲存組成了叢集的全部資料。在生產環境中,為保證高可用的分片架構,至少要保證2個分片, -個分片都應該是一個複製集

。複製集為每個分片的資料提供了冗餘和高可靠性

 

瞭解之後開始搭建,我們首先來簡單的架構,首先確定各個元件的數量,mongos 3個,配置伺服器3個,資料分3片shard server 3個,每個碎片有一個副本一個仲裁也就是3 * 2 = 6個,總共需要部署15個例項。

âmongodbåçâçå¾çæç'¢ç»æ

1,這裡準備了三個IP,分別是:172.16.2.245,172.16.2.161,172.16.7.52。

2,安裝了wget

yum -y install wget

3,在分別每臺機器上建立mongodb的分片對應測試資料夾。這裡是三臺機器都建立

  建立MongoDB的資料檔案

mkdir -p /data/mongodbtest

  進入MongoDB的資料夾 

cd  /data/mongodbtest

 下載

wget http://fastdl.mongodb.org/linux/mongodb-linux-x86_64-2.4.8.tgz

  解壓下載的壓縮包

tar xvzf mongodb-linux-x86_64-2.4.8.tgz

  建立mongos,config,shard1,shard2,shard3五個目錄

#建立mongos目錄
mkdir -p /data/mongodbtest/mongos/log

#建立config server 資料檔案存放目錄
mkdir -p /data/mongodbtest/config/data

#建立config server 日誌檔案存放目錄
mkdir -p /data/mongodbtest/config/log

#建立config server 日誌檔案存放目錄
mkdir -p /data/mongodbtest/mongos/log

#建立shard1 資料檔案存放目錄
mkdir -p /data/mongodbtest/shard1/data

#建立shard1 日誌檔案存放目錄
mkdir -p /data/mongodbtest/shard1/log

#建立shard2 資料檔案存放目錄
mkdir -p /data/mongodbtest/shard2/data

#建立shard2 日誌檔案存放目錄
mkdir -p /data/mongodbtest/shard2/log

#建立shard3 資料檔案存放目錄
mkdir -p /data/mongodbtest/shard3/data

#建立shard3 日誌檔案存放目錄
mkdir -p /data/mongodbtest/shard3/log

我們這裡使用mobaxterm給大家看一看結構

 

4,規劃5個元件對應的埠號,由於一個機器需要同時部署mongos,配置伺服器,shard1,shard2,shard3,所以需要用埠進行區分。
這個埠可以自由定義,在本文mongos為20000,配置伺服器為21000,shard1為22001,shard2為22002,shard3為22003。

5,在每一臺伺服器分別啟動配置伺服器。

/data/mongodbtest/mongodb-linux-x86_64-2.4.8/bin/mongod --configsvr --dbpath /data/mongodbtest/config/data --port 21000 --logpath /data/mongodbtest/config/log/config.log --fork

如圖6所示,在每一臺伺服器分別啟動mongos伺服器。

/data/mongodbtest/mongodb-linux-x86_64-2.4.8/bin/mongos  --configdb 172.16.2.245:21000,172.16.2.161:21000,172.16.7.52:21000  --port 20000   --logpath  /data/mongodbtest/mongos/log/mongos.log --fork

如圖7所示,配置各個分片的副本集。

在每個機器裡分別設定分片1伺服器及副本集shard1

/data/mongodbtest/mongodb-linux-x86_64-2.4.8/bin/mongod --shardsvr --replSet shard1 --port 22001 --dbpath /data/mongodbtest/shard1/data  --logpath /data/mongodbtest/shard1/log/shard1.log --fork --nojournal  --oplogSize 10

在每個機器裡分別設定分片2伺服器及副本集shard2

/data/mongodbtest/mongodb-linux-x86_64-2.4.8/bin/mongod --shardsvr --replSet shard2 --port 22002 --dbpath /data/mongodbtest/shard2/data  --logpath /data/mongodbtest/shard2/log/shard2.log --fork --nojournal  --oplogSize 10

在每個機器裡分別設定分片3伺服器及副本集shard3

/data/mongodbtest/mongodb-linux-x86_64-2.4.8/bin/mongod --shardsvr --replSet shard3 --port 22003 --dbpath /data/mongodbtest/shard3/data  --logpath /data/mongodbtest/shard3/log/shard3.log --fork --nojournal  --oplogSize 10

如圖8所示,分別對每個分片配置副本集

登入某一個IP,注意不要登入用來投票的仲裁伺服器,因為仲裁伺服器不能設定副本集。

我們這裡登入的是172.16.2.245

#設定第一個分片副本集
/data/mongodbtest/mongodb-linux-x86_64-2.4.8/bin/mongo  127.0.0.1:22001

#使用admin資料庫
use admin

#定義副本集配置
config = { _id:"shard1", members:[
                     {_id:0,host:"172.16.2.245:22001"},
                     {_id:1,host:"172.16.2.161:22001"},
                     {_id:2,host:"172.16.7.52:22001",arbiterOnly:true}
                ]
         }

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

#退出
exit

#設定第二個分片副本集
/data/mongodbtest/mongodb-linux-x86_64-2.4.8/bin/mongo  127.0.0.1:22002

#使用admin資料庫
use admin

#定義副本集配置
config = { _id:"shard2", members:[
                     {_id:0,host:"172.16.2.245:22002"},
                     {_id:1,host:"172.16.2.161:22002"},
                     {_id:2,host:"172.16.7.52:22002",arbiterOnly:true}
                ]
         }

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

#退出
exit

#設定第三個分片副本集
/data/mongodbtest/mongodb-linux-x86_64-2.4.8/bin/mongo    127.0.0.1:22003

#使用admin資料庫
use admin

#定義副本集配置
config = { _id:"shard3", members:[
                     {_id:0,host:"172.16.2.245:22003"},
                     {_id:1,host:"172.16.2.161:22003"},
                     {_id:2,host:"172.16.7.52:22003",arbiterOnly:true}
                ]
         }

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

以上的操作都在172.16.2.245機器上完成,將172.16.7.52設定為投票節點。

注意:本機配置的碎片時,不能把本機設定為“仲裁者”,否則會報錯,要去必須節點其他設定
在配置shard1,shard2時都是在節點1上配置的,因為仲裁節點分別是節點3,節點2。當節點1為仲裁節點時,必須
要去節點2或者是節點3上去配置
 

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

#連線到mongos
/data/mongodbtest/mongodb-linux-x86_64-2.4.8/bin/mongo  127.0.0.1:20000

#使用admin資料庫
use  admin

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

db.runCommand( { addshard : "shard1/172.16.2.245:22001,172.16.2.161:22001,172.16.7.52:22001"});

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

db.runCommand( { addshard : "shard2/172.16.2.245:22002,172.16.2.161:22002,172.16.7.52:22002"});

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

db.runCommand( { addshard : "shard3/172.16.2.245:22003,172.16.2.161:22003,172.16.7.52:22003"});

檢視分片伺服器的配置

db.runCommand( { listshards : 1 } );

 可以看到

因為172.16.7.52是每個分片副本集的仲裁節點,所以在上面結果沒有列出來。

10,目前配置服務,路由服務,分片服務,副本集服務都已經串聯起來了,但我們的目的是希望插入資料,資料能夠自動分片,我們新增分片鍵

首先指定一個數據庫,我們假設是mongotest資料庫,集合為使用者。

指定mongotest分片生效

db.runCommand( { enablesharding :"mongotest"});

指定資料庫裡需要分片的集合和片鍵

db.runCommand( { shardcollection : "mongotest.user",key : {id: 1} } )

效果是

 我們首先退出退出,如果你沒有令三臺機器的時間同步的話,那麼你插入假設10萬條資料,你會發現全部插入到了一個shard裡面。

就像這樣

我們還要做一步的是使三臺機器的時間同步。

安裝ntpdate
 # yum install -y ntpdate

時間同步
 # ntpdate pool.ntp.org

這裡為了展示結果,給大家展示一下之前成功過的分片

/data/mongodbtest/mongodb-linux-x86_64-2.4.8/bin/mongo  127.0.0.1:20000
use admin
db.runCommand( { enablesharding :"testdb"});
db.runCommand( { shardcollection : "testdb.table1",key : {id: 1} } )

再使用

#連線mongos伺服器
/data/mongodbtest/mongodb-linux-x86_64-2.4.8/bin/mongo  127.0.0.1:20000

#使用testdb
use  testdb;

#插入資料
for (var i = 1; i <= 100000; i++){db.table1.save({id:i,"test1":"testval1"})}

最後通過

db.user.stats();

可以檢視成功的分片。

sh.status()