mongodb分布式集群搭建手記

一、架構簡介

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

img_dacd4aa5f39d7529eff13bf97a41185b.png

說明
在同一個vm啟動由兩個分片組成的分布式集群,每個分片都是一個PSS(Primary-Secondary-Secondary)模式的數據副本集;
Config副本集采用PSS(Primary-Secondary-Secondary)模式。

二、配置說明

  • 端口通訊
    當前集群中存在shard、config、mongos共12個進程節點,端口矩陣編排如下:
編號實例類型
1mongos
2mongos
3mongos
4config
5config
6config
7shard1
8shard1
9shard1
10shard2
11shard2
12shard2
  • 內部鑒權
    節點間鑒權采用keyfile方式實現鑒權,mongos與分片之間、副本集節點之間共享同一套keyfile文件。 官方說明

  • 賬戶設置
    管理員賬戶:admin/Admin@01,具有集群及所有庫的管理權限
    應用賬號:appuser/AppUser@01,具有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: wiredTigerdirectoryPerDB: truejournal:enabled: true
systemLog:destination: filelogAppend: true
operationProfiling:slowOpThresholdMs: 10000
replication:oplogSizeMB: 10240
processManagement:fork: true
net:http:enabled: false
security:authorization: "enabled"

選項說明可參考這里

B. mongos 配置文件 mongos.conf

systemLog:destination: filelogAppend: 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/datamkdir -p $WORK_DIR/nodes/shard1/n1/data
mkdir -p $WORK_DIR/nodes/shard1/n2/data
mkdir -p $WORK_DIR/nodes/shard1/n3/datamkdir -p $WORK_DIR/nodes/shard2/n1/data
mkdir -p $WORK_DIR/nodes/shard2/n2/data
mkdir -p $WORK_DIR/nodes/shard2/n3/datamkdir -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/mongodecho "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/mongosecho "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:'Admin@01',roles:[{role:'clusterAdmin',db:'admin'},{role:'userAdminAnyDatabase',db:'admin'},{role:'dbAdminAnyDatabase',db:'admin'},{role:'readWriteAnyDatabase',db:'admin'}
]})

當前admin用戶具有集群管理權限、所有數據庫的操作權限。
需要注意的是,在第一次創建用戶之后,localexception不再有效,接下來的所有操作要求先通過鑒權。

use admin
db.auth('admin','Admin@01')

檢查集群狀態

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:'AppUser@01',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" : "RichardFoo@yahoo.com","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 : 24952Shard 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 : 25047Totals
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機制,首次安裝數據庫時可以在本機直接添加用戶

原文鏈接:https://www.cnblogs.com/littleatp/p/8563273.html

img_9b09a36f6de95886f52ce82fa1e89c88.jpe

作者: zale

出處: http://www.cnblogs.com/littleatp/, 如果喜歡我的文章,請關注我的公眾號

本文版權歸作者和博客園共有,歡迎轉載,但未經作者同意必須保留此段聲明,且在文章頁面明顯位置給出 原文鏈接 ?如有問題, 可留言咨詢.

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/391026.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/391026.shtml
英文地址,請注明出處:http://en.pswp.cn/news/391026.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

歸約歸約沖突_JavaScript映射,歸約和過濾-帶有代碼示例的JS數組函數

歸約歸約沖突Map, reduce, and filter are all array methods in JavaScript. Each one will iterate over an array and perform a transformation or computation. Each will return a new array based on the result of the function. In this article, you will learn why …

為什么Java里面的靜態方法不能是抽象的

為什么Java里面的靜態方法不能是抽象的&#xff1f; 問題是為什么Java里面不能定義一個抽象的靜態方法&#xff1f;例如&#xff1a; abstract class foo {abstract void bar( ); // <-- this is okabstract static void bar2(); //<-- this isnt why? }回答一 因為抽…

python16_day37【爬蟲2】

一、異步非阻塞 1.自定義異步非阻塞 1 import socket2 import select3 4 class Request(object):5 def __init__(self,sock,func,url):6 self.sock sock7 self.func func8 self.url url9 10 def fileno(self): 11 return self.soc…

樸素貝葉斯實現分類_關于樸素貝葉斯分類及其實現的簡短教程

樸素貝葉斯實現分類Naive Bayes classification is one of the most simple and popular algorithms in data mining or machine learning (Listed in the top 10 popular algorithms by CRC Press Reference [1]). The basic idea of the Naive Bayes classification is very …

python:改良廖雪峰的使用元類自定義ORM

概要本文僅僅是對廖雪峰老師的使用元類自定義ORM進行改進&#xff0c;并不是要創建一個ORM框架 編寫fieldclass Field(object):def __init__(self, column_type,max_length,**kwargs):1&#xff0c;刪除了參數name&#xff0c;field參數全部為定義字段類型相關參數&#xff0c;…

2019年度年中回顧總結_我的2019年回顧和我的2020年目標(包括數量和收入)

2019年度年中回顧總結In this post were going to take a look at how 2019 was for me (mostly professionally) and were also going to set some goals for 2020! &#x1f929; 在這篇文章中&#xff0c;我們將了解2019年對我來說(主要是職業)如何&#xff0c;我們還將為20…

在Java里重寫equals和hashCode要注意什么問題

問題&#xff1a;在Java里重寫equals和hashCode要注意什么問題 重寫equals和hashCode有哪些問題或者陷阱需要注意&#xff1f; 回答一 理論&#xff08;對于語言律師或比較傾向于數學的人&#xff09;&#xff1a; equals() (javadoc) 必須定義為一個相等關系&#xff08;它…

vray陰天室內_陰天有話:第1部分

vray陰天室內When working with text data and NLP projects, word-frequency is often a useful feature to identify and look into. However, creating good visuals is often difficult because you don’t have a lot of options outside of bar charts. Lets face it; ba…

【codevs2497】 Acting Cute

這個題個人認為是我目前所做的最難的區間dp了&#xff0c;以前把環變成鏈的方法在這個題上并不能使用&#xff0c;因為那樣可能存在重復計算 我第一遍想的時候就是直接把環變成鏈了&#xff0c;wa了5個點&#xff0c;然后仔細思考一下就發現了問題 比如這個樣例 5 4 1 2 4 1 1 …

漸進式web應用程序_漸進式Web應用程序與加速的移動頁面:有什么區別,哪種最適合您?

漸進式web應用程序Do you understand what PWAs and AMPs are, and which might be better for you? Lets have a look and find out.您了解什么是PWA和AMP&#xff0c;哪一種可能更適合您&#xff1f; 讓我們看看并找出答案。 So many people own smartphones these days. T…

高光譜圖像分類_高光譜圖像分析-分類

高光譜圖像分類初學者指南 (Beginner’s Guide) This article provides detailed implementation of different classification algorithms on Hyperspectral Images(HSI).本文提供了在高光譜圖像(HSI)上不同分類算法的詳細實現。 目錄 (Table of Contents) Introduction to H…

在Java里如何給一個日期增加一天

在Java里如何給一個日期增加一天 我正在使用如下格式的日期: yyyy-mm-dd. 我怎么樣可以給一個日期增加一天&#xff1f; 回答一 這樣應該可以解決問題 String dt "2008-01-01"; // Start date SimpleDateFormat sdf new SimpleDateFormat("yyyy-MM-dd&q…

CentOS 7安裝和部署Docker

版權聲明&#xff1a;本文為博主原創文章&#xff0c;未經博主允許不得轉載。 https://blog.csdn.net/u010046908/article/details/79553227 Docker 要求 CentOS 系統的內核版本高于 3.10 &#xff0c;查看本頁面的前提條件來驗證你的CentOS 版本是否支持 Docker 。通過 uname …

JavaScript字符串方法終極指南-拆分

The split() method separates an original string into an array of substrings, based on a separator string that you pass as input. The original string is not altered by split().split()方法根據您作為輸入傳遞的separator字符串&#xff0c;將原始字符串分成子字符串…

機器人的動力學和動力學聯系_通過機器學習了解幸福動力學(第2部分)

機器人的動力學和動力學聯系Happiness is something we all aspire to, yet its key factors are still unclear.幸福是我們所有人都渴望的東西&#xff0c;但其關鍵因素仍不清楚。 Some would argue that wealth is the most important condition as it determines one’s li…

在Java里怎將字節數轉換為我們可以讀懂的格式?

問題&#xff1a;在Java里怎將字節數轉換為我們可以讀懂的格式&#xff1f; 在Java里怎將字節數轉換為我們可以讀懂的格式 像1024應該變成"1 Kb"&#xff0c;而1024*1024應該變成"1 Mb". 我很討厭為每個項目都寫一個工具方法。在Apache Commons有沒有這…

ubuntu 16.04 安裝mysql

2019獨角獸企業重金招聘Python工程師標準>>> 1) 安裝 sudo apt-get install mysql-server apt-get isntall mysql-client apt-get install libmysqlclient-dev 2) 驗證 sudo netstat -tap | grep mysql 如果有 就代表已經安裝成功。 3&#xff09;開啟遠程訪問 1、 …

shell:多個文件按行合并

paste file1 file2 file3 > file4 file1內容為&#xff1a; 1 2 3 file2內容為&#xff1a; a b c file3內容為&#xff1a; read write add file4內容為&#xff1a; 1 a read 2 b write 3 c add 轉載于:https://www.cnblogs.com/seaBiscuit0922/p/7728444.html

form子句語法錯誤_用示例語法解釋SQL的子句

form子句語法錯誤HAVING gives the DBA or SQL-using programmer a way to filter the data aggregated by the GROUP BY clause so that the user gets a limited set of records to view.HAVING為DBA或使用SQL的程序員提供了一種過濾由GROUP BY子句聚合的數據的方法&#xff…

leetcode 1310. 子數組異或查詢(位運算)

有一個正整數數組 arr&#xff0c;現給你一個對應的查詢數組 queries&#xff0c;其中 queries[i] [Li, Ri]。 對于每個查詢 i&#xff0c;請你計算從 Li 到 Ri 的 XOR 值&#xff08;即 arr[Li] xor arr[Li1] xor … xor arr[Ri]&#xff09;作為本次查詢的結果。 并返回一…