1. 程式人生 > >mongodb分散式叢集搭建手記

mongodb分散式叢集搭建手記

一、架構簡介

目標
單機搭建mongodb分散式叢集(副本集 + 分片叢集),演示mongodb分散式叢集的安裝部署、簡單操作。

說明
在同一個vm啟動由兩個分片組成的分散式叢集,每個分片都是一個PSS(Primary-Secondary-Secondary)模式的資料副本集;
Config副本集採用PSS(Primary-Secondary-Secondary)模式。

二、配置說明

  • 埠通訊
    當前叢集中存在shard、config、mongos共12個程序節點,埠矩陣編排如下:
編號 例項型別
1 mongos
2 mongos
3 mongos
4 config
5 config
6 config
7 shard1
8 shard1
9 shard1
10 shard2
11 shard2
12 shard2
  • 內部鑑權
    節點間鑑權採用keyfile方式實現鑑權,mongos與分片之間、副本集節點之間共享同一套keyfile檔案。 

    官方說明

  • 賬戶設定
    管理員賬戶:admin/[email protected],具有叢集及所有庫的管理許可權
    應用賬號:appuser/[email protected],具有appdb的owner許可權

關於初始化許可權
keyfile方式預設會開啟鑑權,而針對初始化安裝的場景,Mongodb提供了localhost-exception機制
可以在首次安裝時通過本機建立使用者、角色,以及副本集初始操作。

三、準備工作

1. 下載安裝包

官方地址:https://www.mongodb.com/download-center

wget https://fastdl.mongodb.org/linux/mongodb-linux-x86_64-rhel70-3.6.3.tgz

2. 部署目錄

解壓壓縮檔案,將bin目錄拷貝到目標路徑/opt/local/mongo-cluster,參考以下命令:

tar -xzvf mongodb-linux-x86_64-rhel70-3.6.3.tgz
mkdir -p  /opt/local/mongo-cluster
cp -r mongodb-linux-x86_64-rhel70-3.6.3/bin /opt/local/mongo-cluster

3. 建立配置檔案

cd /opt/local/mongo-cluster
mkdir conf 

A. mongod 配置檔案 mongo_node.conf
mongo_node.conf 作為mongod例項共享的配置檔案,內容如下:

storage:
    engine: wiredTiger
    directoryPerDB: true  journal:  enabled: true systemLog:  destination: file  logAppend: true operationProfiling:  slowOpThresholdMs: 10000 replication:  oplogSizeMB: 10240 processManagement:  fork: true net:  http:  enabled: false security:  authorization: "enabled"

選項說明可參考這裡

B. mongos 配置檔案 mongos.conf

systemLog:
    destination: file
    logAppend: true processManagement:  fork: true net:  http:  enabled: false

4. 建立keyfile檔案

cd /opt/local/mongo-cluster
mkdir keyfile
openssl rand -base64 756 > mongo.key
chmod 400 mongo.key mv mongo.key keyfile

mongo.key 採用隨機演算法生成,用作節點內部通訊的金鑰檔案

5. 建立節點目錄

WORK_DIR=/opt/local/mongo-cluster
mkdir -p $WORK_DIR/nodes/config/n1/data
mkdir -p $WORK_DIR/nodes/config/n2/data mkdir -p $WORK_DIR/nodes/config/n3/data mkdir -p $WORK_DIR/nodes/shard1/n1/data mkdir -p $WORK_DIR/nodes/shard1/n2/data mkdir -p $WORK_DIR/nodes/shard1/n3/data mkdir -p $WORK_DIR/nodes/shard2/n1/data mkdir -p $WORK_DIR/nodes/shard2/n2/data mkdir -p $WORK_DIR/nodes/shard2/n3/data mkdir -p $WORK_DIR/nodes/mongos/n1 mkdir -p $WORK_DIR/nodes/mongos/n2 mkdir -p $WORK_DIR/nodes/mongos/n3

以config 節點1 為例,nodes/config/n1/data是資料目錄,而pid檔案、日誌檔案都存放於n1目錄
以mongos 節點1 為例,nodes/mongos/n1 存放了pid檔案和日誌檔案

四、搭建叢集

1. Config副本集

按以下指令碼啟動3個Config例項

WORK_DIR=/opt/local/mongo-cluster
KEYFILE=$WORK_DIR/keyfile/mongo.key
CONFFILE=$WORK_DIR/conf/mongo_node.conf
MONGOD=$WORK_DIR/bin/mongod

$MONGOD --port 26001 --configsvr --replSet configReplSet --keyFile $KEYFILE --dbpath $WORK_DIR/nodes/config/n1/data --pidfilepath $WORK_DIR/nodes/config/n1/db.pid --logpath $WORK_DIR/nodes/config/n1/db.log --config $CONFFILE $MONGOD --port 26002 --configsvr --replSet configReplSet --keyFile $KEYFILE --dbpath $WORK_DIR/nodes/config/n2/data --pidfilepath $WORK_DIR/nodes/config/n2/db.pid --logpath $WORK_DIR/nodes/config/n2/db.log --config $CONFFILE $MONGOD --port 26003 --configsvr --replSet configReplSet --keyFile $KEYFILE --dbpath $WORK_DIR/nodes/config/n3/data --pidfilepath $WORK_DIR/nodes/config/n3/db.pid --logpath $WORK_DIR/nodes/config/n3/db.log --config $CONFFILE

待成功啟動後,輸出日誌如下:

about to fork child process, waiting until server is ready for connections. forked process: 4976 child process started successfully, parent exiting

此時通過ps 命令也可以看到3個啟動的程序例項。

連線其中一個Config程序,執行副本集初始化

./bin/mongo --port 26001 --host 127.0.0.1 > MongoDB server version: 3.4.7 > cfg={  _id:"configReplSet",  configsvr: true,  members:[ {_id:0, host:'127.0.0.1:26001'}, {_id:1, host:'127.0.0.1:26002'}, {_id:2, host:'127.0.0.1:26003'} ]}; rs.initiate(cfg);

其中configsvr:true指明這是一個用於分片叢集的Config副本集。
關於副本集配置可參考這裡

2. 建立分片

按以下指令碼啟動Shard1的3個例項

WORK_DIR=/opt/local/mongo-cluster
KEYFILE=$WORK_DIR/keyfile/mongo.key
CONFFILE=$WORK_DIR/conf/mongo_node.conf
MONGOD=$WORK_DIR/bin/mongod

echo "start shard1 replicaset"

$MONGOD --port 27001 --shardsvr --replSet shard1 --keyFile $KEYFILE --dbpath $WORK_DIR/nodes/shard1/n1/data --pidfilepath $WORK_DIR/nodes/shard1/n1/db.pid --logpath $WORK_DIR/nodes/shard1/n1/db.log --config $CONFFILE $MONGOD --port 27002 --shardsvr --replSet shard1 --keyFile $KEYFILE --dbpath $WORK_DIR/nodes/shard1/n2/data --pidfilepath $WORK_DIR/nodes/shard1/n2/db.pid --logpath $WORK_DIR/nodes/shard1/n2/db.log --config $CONFFILE $MONGOD --port 27003 --shardsvr --replSet shard1 --keyFile $KEYFILE --dbpath $WORK_DIR/nodes/shard1/n3/data --pidfilepath $WORK_DIR/nodes/shard1/n3/db.pid --logpath $WORK_DIR/nodes/shard1/n3/db.log --config $CONFFILE

待成功啟動後,輸出日誌如下:

about to fork child process, waiting until server is ready for connections. forked process: 5976 child process started successfully, parent exiting

此時通過ps 命令也可以看到3個啟動的Shard程序例項。

連線其中一個Shard程序,執行副本集初始化

./bin/mongo --port 27001 --host 127.0.0.1 > MongoDB server version: 3.4.7 > cfg={  _id:"shard1",  members:[ {_id:0, host:'127.0.0.1:27001'}, {_id:1, host:'127.0.0.1:27002'}, {_id:2, host:'127.0.0.1:27003'} ]}; rs.initiate(cfg);

參考以上步驟,啟動Shard2的3個例項程序,並初始化副本集。

3. 啟動mongos路由

執行以下指令碼啟動3個mongos程序

WORK_DIR=/opt/local/mongo-cluster
KEYFILE=$WORK_DIR/keyfile/mongo.key
CONFFILE=$WORK_DIR/conf/mongos.conf
MONGOS=$WORK_DIR/bin/mongos

echo "start mongos instances" $MONGOS --port=25001 --configdb configReplSet/127.0.0.1:26001,127.0.0.1:26002,127.0.0.1:26003 --keyFile $KEYFILE --pidfilepath $WORK_DIR/nodes/mongos/n1/db.pid --logpath $WORK_DIR/nodes/mongos/n1/db.log --config $CONFFILE $MONGOS --port 25002 --configdb configReplSet/127.0.0.1:26001,127.0.0.1:26002,127.0.0.1:26003 --keyFile $KEYFILE --pidfilepath $WORK_DIR/nodes/mongos/n2/db.pid --logpath $WORK_DIR/nodes/mongos/n2/db.log --config $CONFFILE $MONGOS --port 25003 --configdb configReplSet/127.0.0.1:26001,127.0.0.1:26002,127.0.0.1:26003 --keyFile $KEYFILE --pidfilepath $WORK_DIR/nodes/mongos/n3/db.pid --logpath $WORK_DIR/nodes/mongos/n3/db.log --config $CONFFILE

待成功啟動後,通過ps命令看到mongos程序:

dbuser      7903    1  0 17:49 ? 00:00:00 /opt/local/mongo-cluster/bin/mongos --port=25001 --configdb configReplSet/127.0.0.1:26001,127.0.0.1:26002,127.0.0.1:26003 --keyFile /opt/local/mongo-cluster/keyfile/mongo.key --pidfilepath /opt/local/mongo-cluster/nodes/mongos/n1/db.pid --logpath /opt/local/mongo-cluster/nodes/mongos/n1/db.log --config /opt/local/mongo-cluster/conf/mongos.conf dbuser 7928 1 0 17:49 ? 00:00:00 /opt/local/mongo-cluster/bin/mongos --port 25002 --configdb configReplSet/127.0.0.1:26001,127.0.0.1:26002,127.0.0.1:26003 --keyFile /opt/local/mongo-cluster/keyfile/mongo.key --pidfilepath /opt/local/mongo-cluster/nodes/mongos/n2/db.pid --logpath /opt/local/mongo-cluster/nodes/mongos/n2/db.log --config /opt/local/mongo-cluster/conf/mongos.conf dbuser 7954 1 0 17:49 ? 00:00:00 /opt/local/mongo-cluster/bin/mongos --port 25003 --configdb configReplSet/127.0.0.1:26001,127.0.0.1:26002,127.0.0.1:26003 --keyFile /opt/local/mongo-cluster/keyfile/mongo.key --pidfilepath /opt/local/mongo-cluster/nodes/mongos/n3/db.pid --logpath /opt/local/mongo-cluster/nodes/mongos/n3/db.log --config /opt/local/mongo-cluster/conf/mongos.conf

接入其中一個mongos例項,執行新增分片操作:

./bin/mongo --port 25001 --host 127.0.0.1 mongos> MongoDB server version: 3.4.7 mongos> sh.addShard("shard1/127.0.0.1:27001") { "shardAdded" : "shard1", "ok" : 1 } mongos> sh.addShard("shard2/127.0.0.1:27004") { "shardAdded" : "shard2", "ok" : 1 }

至此,分散式叢集架構啟動完畢,但進一步操作需要先新增使用者。

4. 初始化使用者

接入其中一個mongos例項,新增管理員使用者

use admin
db.createUser({
    user:'admin',pwd:'[email protected]', roles:[ {role:'clusterAdmin',db:'admin'}, {role:'userAdminAnyDatabase',db:'admin'}, {role:'dbAdminAnyDatabase',db:'admin'}, {role:'readWriteAnyDatabase',db:'admin'} ]})

當前admin使用者具有叢集管理許可權、所有資料庫的操作許可權。
需要注意的是,在第一次建立使用者之後,localexception不再有效,接下來的所有操作要求先通過鑑權。

use admin
db.auth('admin','[email protected]')

檢查叢集狀態

mongos> sh.status()
--- Sharding Status --- 
  sharding version: {
    "_id" : 1,
    "minCompatibleVersion" : 5, "currentVersion" : 6, "clusterId" : ObjectId("5aa39c3e915210dc501a1dc8") }  shards: { "_id" : "shard1", "host" : "shard1/127.0.0.1:27001,127.0.0.1:27002,127.0.0.1:27003", "state" : 1 } { "_id" : "shard2", "host" : "shard2/127.0.0.1:27004,127.0.0.1:27005,127.0.0.1:27006", "state" : 1 } active mongoses: "3.4.7" : 3 autosplit: Currently enabled: yes

叢集使用者
分片叢集中的訪問都會通過mongos入口,而鑑權資料是儲存在config副本集中的,即config例項中system.users資料庫儲存了叢集使用者及角色許可權配置。mongos與shard例項則通過內部鑑權(keyfile機制)完成,因此shard例項上可以通過新增本地使用者以方便操作管理。在一個副本集上,只需要在Primary節點上新增使用者及許可權,相關資料會自動同步到Secondary節點。
關於叢集鑑權
在本案例中,我們為兩個分片副本集都添加了本地admin使用者。

通過mongostat工具可以顯示叢集所有角色:

          host insert query update delete getmore command dirty used flushes mapped vsize res faults qrw arw net_in net_out conn set repl time 127.0.0.1:27001 *0 *0 *0 *0 0 6|0 0.1% 0.1% 0 1.49G 44.0M n/a 0|0 0|0 429b 56.1k 25 shard1 PRI Mar 10 19:05:13.928 127.0.0.1:27002 *0 *0 *0 *0 0 7|0 0.1% 0.1% 0 1.43G 43.0M n/a 0|0 0|0 605b 55.9k 15 shard1 SEC Mar 10 19:05:13.942 127.0.0.1:27003 *0 *0 *0 *0 0 7|0 0.1% 0.1% 0 1.43G 43.0M n/a 0|0 0|0 605b 55.9k 15 shard1 SEC Mar 10 19:05:13.946 127.0.0.1:27004 *0 *0 *0 *0 0 6|0 0.1% 0.1% 0 1.48G 43.0M n/a 0|0 0|0 546b 55.8k 18 shard2 PRI Mar 10 19:05:13.939 127.0.0.1:27005 *0 *0 *0 *0 0 6|0 0.1% 0.1% 0 1.43G 42.0M n/a 0|0 0|0 540b 54.9k 15 shard2 SEC Mar 10 19:05:13.944 127.0.0.1:27006 *0 *0 *0 *0 0 6|0 0.1% 0.1% 0 1.46G 44.0M n/a 0|0 0|0 540b 54.9k 17 shard2 SEC Mar 10 19:05:13.936

五、資料操作

在案例中,建立appuser使用者、為資料庫例項appdb啟動分片。

use appdb
db.createUser({user:'appuser',pwd:'[email protected]',roles:[{role:'dbOwner',db:'appdb'}]}) sh.enableSharding("appdb")

建立集合book,為其執行分片初始化。

use appdb
db.createCollection("book") db.device.ensureIndex({createTime:1}) sh.shardCollection("appdb.book", {bookId:"hashed"}, false, { numInitialChunks: 4} )

繼續往device集合寫入1000W條記錄,觀察chunks的分佈情況

use appdb
var cnt = 0;
for(var i=0; i<1000; i++){ var dl = []; for(var j=0; j<100; j++){ dl.push({ "bookId" : "BBK-" + i + "-" + j, "type" : "Revision", "version" : "IricSoneVB0001", "title" : "Jackson's Life", "subCount" : 10, "location" : "China CN Shenzhen Futian District", "author" : { "name" : 50, "email" : "[email protected]", "gender" : "female" }, "createTime" : new Date() }); } cnt += dl.length; db.book.insertMany(dl); print("insert ", cnt); }

執行db.book.getShardDistribution(),輸出如下:

Shard shard1 at shard1/127.0.0.1:27001,127.0.0.1:27002,127.0.0.1:27003 data : 13.41MiB docs : 49905 chunks : 2 estimated data per chunk : 6.7MiB estimated docs per chunk : 24952 Shard shard2 at shard2/127.0.0.1:27004,127.0.0.1:27005,127.0.0.1:27006 data : 13.46MiB docs : 50095 chunks : 2 estimated data per chunk : 6.73MiB estimated docs per chunk : 25047 Totals data : 26.87MiB docs : 100000 chunks : 4 Shard shard1 contains 49.9% data, 49.9% docs in cluster, avg obj size on shard : 281B Shard shard2 contains 50.09% data, 50.09% docs in cluster, avg obj size on shard : 281B

總結

    • Mongodb叢集架構由Mongos、Config副本集和多個分片組成;
      安裝過程中先初始化Config副本集、分片副本集,最後通過Mongos新增分片
    • Config副本集儲存了叢集訪問的使用者及角色許可權,為了方便管理,可以給分片副本集新增本地使用者
    • Mongodb提供了LocalException機制,首次安裝資料庫時可以在本機直接新增使用者
      • from: https://www.cnblogs.com/littleatp/p/8563273.html