天天看點

02_MongoDB叢集環境搭建配置

作者:妮唯伊

MongoDB叢集環境搭建配置

li_zliang

02_MongoDB叢集環境搭建配置

1. 概述

1.1 主從複制

1.2 副本集

1.3 分片

2. 副本集叢集搭建

2.1 Primary和Secondary搭建的Replica Set

2.1.1 規劃

2.1.2 安裝

2.1.2 建立目錄

2.1.3 配置檔案

2.1.4 安全認證

2.1.5 啟動節點

2.1.6 配置

2.1.7 驗證

2.2 加入Arbiter搭建Replica Set

2.2.1 規劃

2.2.2 配置

2.3 叢集基本操作

3. 分片叢集搭建

3.1 概述

3.2 規劃

3.3 分片Shard Server

3.3.1 計劃修改(以108為例)

3.3.2 發現問題(續前節)

3.3.3 實際修改(續前節)

3.3.4 修改其他伺服器

3.4 配置Config Server

3.4.1 建立目錄

3.4.2 配置檔案

3.4.3 安全配置

3.4.4 初始配置

3.5 路由Router Server

3.5.1 建立目錄

3.5.2 配置檔案

3.5.3 安全配置

3.5.4 啟動服務

3.5.5 串聯配置和路由

3.5.6 使用者操作

3.7 測試-指定資料庫集合分片

3.8 測試-用戶端連接配接

3.8 登陸使用者說明

3.9 安全認證說明

3.10 關閉啟動說明

1. 概述

MongoDB 有三種叢集部署模式,分别為主從複制(Master-Slaver)、副本集(Replica Set)和分片(Sharding)模式。

  1. Master-Slaver 是一種主從副本的模式,目前已經不推薦使用。
  2. Replica Set 模式取代了 Master-Slaver 模式,是一種互為主從的關系。Replica Set 将資料複制多份儲存,不同伺服器儲存同一份資料,在出現故障時自動切換,實作故障轉移,在實際生産中非常實用。
  3. Sharding 模式适合處理大量資料,它将資料分開存儲,不同伺服器儲存不同的資料,所有伺服器資料的總和即為整個資料集。

Sharding 模式追求的是高性能,而且是三種叢集中最複雜的。在實際生産環境中,通常将 Replica Set 和 Sharding 兩種技術結合使用。

1.1 主從複制

副本集代替,不再贅述;

1.2 副本集

02_MongoDB叢集環境搭建配置

此叢集擁有一個主節點和多個從節點,這一點與主從複制模式類似,且主從節點所負責的工作也類似,但是副本集與主從複制的差別在于:當叢集中主節點發生故障時,副本集可以自動投票,選舉出新的主節點,并引導其餘的從節點連接配接新的主節點,而且這個過程對應用是透明的。

主節點負責資料的寫入和更新,并在更新資料的同時,将操作資訊寫入名為 oplog 的日志檔案當中。

從節點會定時輪詢讀取 oplog 日志,根據日志内容同步更新自身的資料,保持與主節點一緻。

副本集中的各節點會通過心跳資訊來檢測各自的健康狀況,當主節點出現故障時,多個從節點會觸發一次新的選舉操作,并選舉其中一個作為新的主節點。為了保證選舉票數不同,副本集的節點數保持為奇數。

當然,還可以加入仲裁者(Arbiter),該節點不存儲資料,不參與選主,隻進行選主投票。使用Arbiter可以減輕資料存儲的硬體需求,Arbiter跑起來幾乎沒什麼大的硬體資源需求,但重要的一點是,在生産環境下它和其他資料節點不要部署在同一台機器上。

是以綜上,副本集叢集搭建有兩種:

第一種: 主節點(1個) + 多個副本節點, 即奇數個資料節點構成的Replica Set;

02_MongoDB叢集環境搭建配置

第二種: 主節點(1個) + 多個副本節點 + 仲裁節點,即偶數個資料節點,加一個Arbiter節點構成的Replica Set;

02_MongoDB叢集環境搭建配置

預設情況下,副本節點不能讀寫;

若副本節點當機,不受影響;若主節點當機,則會進行選舉;

1.3 分片

當MongoDB存儲海量的資料時,一台機器可能不足以存儲資料,也可能不足以提供可接受的讀寫吞吐量。這時,我們就可以通過在多台機器上分割資料,使得資料庫系統能存儲和處理更多的資料。這就需要用到 MongoDB 的分片(Sharding)技術。

02_MongoDB叢集環境搭建配置

建構一個 MongoDB 的分片叢集,需要三個重要的元件,分别是分片伺服器(Shard Server)、配置伺服器(Config Server)和路由伺服器(Route Server)。

Shard Server

每個 Shard Server 都是一個 mongod 資料庫執行個體,用于存儲實際的資料塊。整個資料庫集合分成多個塊存儲在不同的 Shard Server 中。

在實際生産中,一個 Shard Server 可由幾台機器組成一個副本集來承擔,防止因主節點單點故障導緻整個系統崩潰。

Config Server

這是獨立的一個 mongod 程序,儲存叢集和分片的中繼資料,在叢集啟動最開始時建立,儲存各個分片包含資料的資訊。

Route Server

這是獨立的一個 mongos 程序,Route Server 在叢集中可作為路由使用,用戶端由此接入,讓整個叢集看起來像是一個單一的資料庫,提供用戶端應用程式和分片叢集之間的接口。

Route Server 本身不儲存資料,啟動時從 Config Server 加載叢集資訊到緩存中,并将用戶端的請求路由給每個 Shard Server,在各 Shard Server 傳回結果後進行聚合并傳回用戶端。

2. 副本集叢集搭建

為了後續章節(分片叢集搭建),我這裡就采用1台伺服器模拟副本集搭建,就是在一台伺服器上啟動3個mongod執行個體;

2.1 Primary和Secondary搭建的Replica Set

2.1.1 規劃

計算機名 IP 節點 端口 目錄 名稱
mongodb1 192.168.25.107 主節點Primary 27017

2.1.2 安裝

按照<01_MongoDB安裝配置>,先安裝好MongoDB并配置環境變量;

2.1.2 建立目錄

# mkdir -p /usr/local/mongodb/shard1/data

# mkdir -p /usr/local/mongodb/shard1/logs

# mkdir -p /usr/local/mongodb/shard1/etc

# mkdir -p /usr/local/mongodb/shard1/tmp

# mkdir -p /usr/local/mongodb/shard2/data

# mkdir -p /usr/local/mongodb/shard2/logs

# mkdir -p /usr/local/mongodb/shard2/etc

# mkdir -p /usr/local/mongodb/shard2/tmp

# mkdir -p /usr/local/mongodb/shard3/data

# mkdir -p /usr/local/mongodb/shard3/logs

# mkdir -p /usr/local/mongodb/shard3/etc

# mkdir -p /usr/local/mongodb/shard3/tmp

# chown -R mongod:mongod /usr/local/mongodb/shard1 # root使用者時不執行

# chown -R mongod:mongod /usr/local/mongodb/shard2 # root使用者時不執行

# chown -R mongod:mongod /usr/local/mongodb/shard3 # root使用者時不執行

2.1.3 配置檔案

vim /usr/local/mongodb/shard1/etc/mongod.conf

vim /usr/local/mongodb/shard2/etc/mongod.conf

vim /usr/local/mongodb/shard3/etc/mongod.conf

編制3個配置檔案,注意:

  1. dbpath屬性分别配置為shard1、shard2、shard3的data路徑;
  2. logpath屬性分别配置為shard1、shard2、shard3的log檔案;
  3. port屬性分别配置為27017、27018、27019;
  4. pidFilePath屬性分别配置shard1 mongo_27017.pid、、shard2 mongo_27018.pid、shard3 mongo_27019.pid;
  5. 配置security.keyFile分别配置shard1、shard2、shard3的keyFile檔案;
  6. 配置replication;

其中node1的配置檔案如下:

實際配置時建議删除不需要的配置;删除中文注釋,行内不注釋,僅保留必須的注釋;

# 日志配置

systemLog:

destination: file

path: /usr/local/mongodb/shard1/logs/mongodb.log

logAppend: true

# 網絡配置

net:

maxIncomingConnections: 5000

port: 27017

bindIp: 0.0.0.0

serviceExecutor : adaptive

# 存儲配置

storage:

dbPath: /usr/local/mongodb/shard1/data

journal:

enabled: true

commitIntervalMs: 100

# 啟動配置

processManagement:

fork: true

pidFilePath: /usr/local/mongodb/shard1/tmp/mongo_27017.pid

# 安全配置

security:

authorization: 'enabled' # 啟用驗證

keyFile: /usr/local/mongodb/shard1/etc/replica_set.key # 指定分片或副本內建員之間身份驗證的key檔案存儲位置

clusterAuthMode: "keyFile" # 指定分片或副本內建員之間身份驗證模式

# 副本集叢集配置

replication:

oplogSizeMB: 65536 #64GB # 預設硬碟的5%,指定oplog的最大尺寸

replSetName: rs1 # 指定副本集的名稱

# secondaryIndexPrefetch: 'all' # 指定副本內建員在接收oplog之前是否加載索引到記憶體,all加載所有(預設),none不加載,_id_only僅加載_id

# 分片叢集配置

#sharding:

# clusterRole: shardsvr # 指定目前分片在叢集中的角色,shardsvr是shard節點,configsvr是config server節點

# archiveMovedChunks: false

# configDB: configReplSet/ip:port,ip:port,ip:port # 告訴mongos節點config server的位址資訊

2.1.4 安全認證

如果沒有配置安全認證(security.keyFile)的話,在啟動節點時會出現:

security.keyFile is required when authorization is enabled with replica sets

因為副本集的各個節點成員之間通信要内部身份驗證; 啟用節點間身份驗證可以使用密鑰檔案或x.509證書,本文使用密鑰檔案;

安全認證在mongod.conf中配置如下:

# 安全配置

security:

authorization: 'enabled' # 啟用驗證

keyFile: /usr/local/mongodb/shard1/etc/replica_set.key # 指定分片或副本內建員之間身份驗證的key檔案存儲位置

clusterAuthMode: "keyFile" # 指定分片或副本內建員之間身份驗證模式

在keyfile身份驗證中,副本集中的每個mongod執行個體都使用keyfile的内容作為共享密碼,隻有具有正确密鑰檔案的mongod或者mongos執行個體可以連接配接到副本集。密鑰檔案的内容必須在6到1024個字元之間,并且在unix/linux系統中檔案所有者必須有對檔案至少有讀的權限;

所有副本集節點都必須要用同一份keyfile,一般是在一台機器上生成,然後拷貝到其他機器上,且必須有讀的權限;

首先在第一個節點上生成keyFile:

# 進入第一個節點

# cd /usr/local/mongodb/shard1/etc

//生成keyFile

# openssl rand -base64 756 > replica_set.key

//設定權限

# chmod 600 replica_set.key

然後将生成的keyFile複制到其他節點目錄,如果節點是不同伺服器,則需要下載下傳上傳複制;

這裡采用同一個伺服器模拟三個節點,直接cp複制了;

# cp /usr/local/mongodb/shard1/etc/replica_set.key /usr/local/mongodb/shard2/etc/

# chmod 600 /usr/local/mongodb/shard2/etc/replica_set.key

# cp /usr/local/mongodb/shard1/etc/replica_set.key /usr/local/mongodb/shard3/etc/

# chmod 600 /usr/local/mongodb/shard3/etc/replica_set.key

2.1.5 啟動節點

依次啟動三個節點:

# mongod -f /usr/local/mongodb/shard1/etc/mongod.conf

# mongod -f /usr/local/mongodb/shard2/etc/mongod.conf

# mongod -f /usr/local/mongodb/shard3/etc/mongod.conf

# ps -ef | grep mongod

02_MongoDB叢集環境搭建配置

2.1.6 配置

輸入mongo -port 27017,連接配接到第一個節點,執行以下内容;權重priority(有效取值是0~1000,可為小數,預設為1)高的節點會被選為Primary;

# mongo -port 27017

> use admin

> config = {

_id: "rs1",

members: [

{_id: 0, host: "192.168.25.107:27017", priority:3},

{_id: 1, host: "192.168.25.107:27018", priority:2},

{_id: 2, host: "192.168.25.107:27019", priority:1}

]

}

> rs.initiate(config)

02_MongoDB叢集環境搭建配置

檢視:

//檢視配置

> rs.config()

//檢視狀态

> rs.status()

注意,我們在配置檔案中開啟了認證模式authorization: 'enabled', 在初始化時、檢視配置rs.config()、檢視狀态rs.status()可能會提示權限問題;

詳見<2.1.7驗證>章節,可以先建立管理使用者,登陸 >use admin >db.auth('user','pwd')後再操作;

如果初始化時提示權限,先在配置檔案中關閉認證authorization: 'disabled',添加配置并初始化後再啟用認證;

02_MongoDB叢集環境搭建配置

//進入primary節點

# mongo -port 27017

//建立管理使用者,使用者必須具備clusterAdmin角色(進行複制集的管理(添加成員、檢視狀态等等))

> use admin

> db.createUser({user:"lizl", pwd:"123456", roles:[

{"role":"readWrite", db:"admin"},

{"role":"dbAdmin", db:"admin"},

{"role":"userAdminAnyDatabase", db:"admin"},

{"role":"readWriteAnyDatabase", db:"admin"},

{"role":"dbAdminAnyDatabase", db:"admin"},

{"role":"clusterAdmin", db:"admin"}

]});

> use admin

> db.auth('lizl','123456')

至此,mongodb副本集叢集搭建完畢;

2.1.7 驗證

//進入primary節點,建立使用者,如已建立可忽略

# mongo -port 27017

//建立管理使用者,使用者必須具備clusterAdmin角色(進行複制集的管理(添加成員、檢視狀态等等))

> use admin

> db.createUser({user:"lizl", pwd:"123456", roles:[

{"role":"readWrite", db:"admin"},

{"role":"dbAdmin", db:"admin"},

{"role":"userAdminAnyDatabase", db:"admin"},

{"role":"readWriteAnyDatabase", db:"admin"},

{"role":"dbAdminAnyDatabase", db:"admin"},

{"role":"clusterAdmin", db:"admin"}

]});

> use admin

> db.auth('lizl','123456')

> rs.status()

//在主節點建立elsa資料庫,建立test集合,并插入資料name="張三"

> use elsa

> db.test.insert({name:"張三"})

02_MongoDB叢集環境搭建配置

//進入secondary節點

# mongo -port 27018

//副本集之前會同步使用者及資料

> use admin

> db.auth('lizl','123456')

> rs.status()

> use elsa

> db.test.find()

//會出現"errmsg" : "not master and slaveOk=false",是因為預設情況下secondary節點不能讀寫;

02_MongoDB叢集環境搭建配置

預設情況下secondary節點不能讀寫;可以通過以下指令設定副本節點允許查詢;

> db.getMongo().setSlaveOk()

//關閉primary節點

# mongod -f /usr/local/mongodb/shard1/etc/mongod.conf --shutdown

# mongo -port 27018

//可以發現原來的secondary節點變成了primary節點;

//并可以登入使用者查詢資料了;

02_MongoDB叢集環境搭建配置

2.2 加入Arbiter搭建Replica Set

2.2.1 規劃

計算機名 IP 節點 端口 目錄 名稱
mongodb1 192.168.25.107 主節點Primary 27017

2.2.2 配置

采用Arbiter搭建Replica Set,根據上述章節,将第三個節點調整為仲裁節點Arbiter;

總體搭建過程與上述章節内容基本一緻,差異的地方如下:

在配置配置部分第三個節點添加 arbiterOnly:true;必須的;

輸入mongo -port 27017,連接配接到第一個節點,執行以下内容;

# mongo -port 27017

> config = {

_id: "rs1",

members: [

{_id: 0, host: "192.168.25.107:27017", priority:2},

{_id: 1, host: "192.168.25.107:27018", priority:1},

{_id: 2, host: "192.168.25.107:27019", arbiterOnly:true}

]

}

> rs.initiate(config)

前述章節已經對目前伺服器進行了rs.initiate(config),無法重複加載了; 故這裡采用移除節點增加節點的方式進行操作:

在上述章節基礎上修改,删除第三個節點,然後添加第三個節點為仲裁節點;

移除操作會使被移除節點服務停止,注意檢查,需要啟動;

如果啟動失敗背景日志出現:/usr/local/mongodb/shard3/data/mongod.lock;

則需要删除data/*.lock、tmp/mongod-27019.pid檔案後啟動;

其實搗鼓過一番,我是最終清空了data、tmp、logs目錄後啟動成功的;

//移除節點

> rs.remove("192.168.25.107:27019")

//添加仲裁節點

> rs.add({host:"192.168.25.107:27019",arbiterOnly:true})

或者

> rs.addArb("192.168.25.107:27019")

//移除操作會使第三個節點服務停止,注意檢查,需要啟動;

> rs.config()

> rs.status()

02_MongoDB叢集環境搭建配置

驗證如下:

02_MongoDB叢集環境搭建配置

2.3 叢集基本操作

注意操作如下内容,需要建立使用者且使用者必須具備clusterAdmin角色,并登入admin庫;

# mongo -port xxxxx

# use admin

# db.auth('lizl','123456')

//初始化

> rs.initiate()

//添加節點成員

> rs.add("192.168.25.107:27018")

> rs.add("192.168.25.107:27019")

//檢視狀态

> rs.status()

//添加仲裁節點

> rs.add({host:"192.168.25.107:27019",arbiterOnly:true})

或者

> rs.addArb("192.168.25.107:27019")

//移除節點

> rs.remove("192.168.25.107:27019")

//節點降級從primary将為secondary

> rs.stepDown()

//檢視配置

> rs.config()

//更新配置

> var config = rs.config()

//更新配置-設定優先級

> config.members[2].priority=2

//更新配置-更新節點

> conf.members[0].host="IP:PORT";

> rs.reconfig(config,{"force":true})

//停止服務

> db.shutdownServer()

3. 分片叢集搭建

先參考<2. 副本集叢集搭建>學會副本集叢集搭建;

3.1 概述

在實際生産環境中,叢集會結合副本集和分片機制保證生産過程的高可靠性和高可擴充性。

本章節即采用 副本集+切片 建構高可用叢集;

02_MongoDB叢集環境搭建配置

每一個切片伺服器(Shard Server)由一個包含三個 mongod 執行個體的副本集組成,避免了單一的 mongod 執行個體出現故障造成資料的丢失。

配置伺服器(Config Server) 也可由多個 mongod 執行個體叢集組成,保證叢集中配置資訊的可用性。

路由伺服器(Router Server)也可使用多個 mongos 執行個體,來保證用戶端的請求能得到及時的響應。

分片伺服器(Shard Server)存儲具體的分片資料。

配置伺服器(Config Server)是普通的 mongod 伺服器,儲存着叢集的配置資訊:叢集中有哪些分片、分片的是哪些集合,以及資料塊的分布。

啟動叢集後,路由伺服器(Route Server)加載 Config Server 中的分片資訊, 用戶端通過連接配接 Route Server 來擷取叢集中的資料資訊。

3.2 規劃

  1. 1. 準備三台伺服器107、108、109進行模拟;
  2. 2. 每個伺服器按照上述步驟模拟建構好三個成員的副本集叢集,以保證資料的容錯和備援;

(基于192.168.25.107建構好副本集叢集後,将107虛拟機複制2份,形成108和109;)

  1. 3. 每個副本集作為整體建構一個分片(Shard Server);
  2. 4. 每個伺服器啟動一個mongod執行個體建構Config Server,這裡配置伺服器也構成個副本集,在此副本集名稱:rs-conf;
  3. 5. 每個伺服器啟動一個mongos執行個體建構Route Server;
計算機名 IP mongos config server Shard Server
shard 端口 名稱
mongodb1 192.168.25.107 27000 27001(rs-conf) 主節點Primary 27017 rs1副本集
副本節點Secondary 27018
副本節點Secondary 27019
mongodb2 192.168.25.108 27000 27001(rs-conf) 主節點Primary 27017 rs2副本集
副本節點Secondary 27018
副本節點Secondary 27019
mongodb3 192.168.25.109 27000 27001(rs-conf) 主節點Primary 27017 rs3副本集
副本節點Secondary 27018
副本節點Secondary 27019

3.3 分片Shard Server

基于192.168.25.107建構好副本集叢集後,将107虛拟機複制2份,形成108和109;然後分别修改配置:

  1. 修改每個節點配置檔案中sharding.clusterRole改為shardsvr(注意 107 108 109 都修改);
  2. 修改每個節點配置檔案中replSetName改為rs1(107)、rs2(108)、rs3(109)(這裡隻改108 109即可);
  3. 重新配置下叢集,因為rs.config()都是配置的IP;涉及的IP改為107、108、109(這裡隻改108 109即可);

這裡重新配置叢集做了很多嘗試,終于成功修改了配置,詳見下述章節:

<3.3.1計劃修改>是做的嘗試,但出現了<3.3.2發現問題>,最終按照<3.3.3實際修改>執行;

3.3.1 計劃修改(以108為例)

  1. 修改每個節點配置檔案中replSetName改為rs2;

# vim /usr/local/mongodb/shard1/etc/mongod.conf

# vim /usr/local/mongodb/shard2/etc/mongod.conf

# vim /usr/local/mongodb/shard3/etc/mongod.conf

# 副本集叢集配置

replication:

replSetName: rs1

  1. 修改每個節點配置檔案中sharding.clusterRole改為shardsvr;

# 分片叢集配置

sharding:

clusterRole: shardsvr

  1. 啟動三個節點服務;

# mongod -f /usr/local/mongodb/shard1/etc/mongod.conf

# mongod -f /usr/local/mongodb/shard2/etc/mongod.conf

# mongod -f /usr/local/mongodb/shard3/etc/mongod.conf

  1. 通路第一個節點服務并使用管理賬号登入admin庫;

# mongo -port 27017

> use admin

> db.auth('lizl','123456')

  1. 采用移除節點添加節點方式重新配置下叢集,因為rs.config()都是配置的IP;涉及的IP改為108;

# mongo -port 27017

//更新配置

> var config = rs.config()

//更新配置-更新節點

> config.members[0].host="192.168.25.108:27017"

> config.members[1].host="192.168.25.108:27018"

> config.members[2].host="192.168.25.108:27019"

> rs.reconfig(config,{"force":true})

  1. 重新開機各個節點并驗證;

3.3.2 發現問題(續前節)

這個時候發現了問題:rs.config()._id應該是rs2,但始終是rs1;怎麼搗鼓都不行;

02_MongoDB叢集環境搭建配置

采用下述方式更新不起作用:

> var config = rs.config()

//更新配置-更新節點

> config._id = "rs2"

> rs.reconfig(config,{"force":true})

采用下述方式提示不能重複加載:

> config = {

_id: "rs2",

members: [

{_id: 0, host: "192.168.25.108:27017", priority:3},

{_id: 1, host: "192.168.25.108:27018", priority:2},

{_id: 2, host: "192.168.25.108:27019", priority:1}

]

}

> rs.initiate(config)

後研究發現,配置資訊是在local庫,system.replset集合内;

02_MongoDB叢集環境搭建配置

嘗試更新這個集合的資料,提示管理賬号無權限; 後來想了想,關閉認證可能就不提示無權限了;

> db.system.replset.find()

> db.system.replset.update({'_id':'rs1'},{$set:{'_id':'rs2'}})

且研究發現,無法在local庫添加使用者;

無奈...;

然後繼續,經查,按照下述章節執行成功;

3.3.3 實際修改(續前節)

  1. 采用非配置檔案方式啟動三個節點服務(重要)

# mongod --dbpath /usr/local/mongodb/shard1/data --logpath /usr/local/mongodb/shard1/logs/mongodb.log --port 27017 --logappend --bind_ip 0.0.0.0 --fork

# mongod --dbpath /usr/local/mongodb/shard2/data --logpath /usr/local/mongodb/shard2/logs/mongodb.log --port 27018 --logappend --bind_ip 0.0.0.0 --fork

# mongod --dbpath /usr/local/mongodb/shard3/data --logpath /usr/local/mongodb/shard3/logs/mongodb.log --port 27019 --logappend --bind_ip 0.0.0.0 --fork

  1. 通路節點服務并使用管理賬号登入admin庫;

# mongo -port 27017

> use admin

> db.auth('lizl','123456')

//進入local庫

> use local

> db.system.replset.find()

  1. 嘗試更新_id=rs2無果

> db.system.replset.update({'_id':'rs1'},{$set:{'_id':'rs2'}})

02_MongoDB叢集環境搭建配置
  1. 幹脆删除system.replset的資料,竟然成功了!

> db.system.replset.remove({'_id':'rs1'})

02_MongoDB叢集環境搭建配置
  1. 其他兩個節點按照同樣方式删除system.replset的資料;

# mongo -port 27018 //節點2

> use admin

> db.auth('lizl','123456')

//進入local庫

> use local

> db.system.replset.remove({'_id':'rs1'})

# mongo -port 27019 //節點3

> use admin

> db.auth('lizl','123456')

//進入local庫

> use local

> db.system.replset.remove({'_id':'rs1'})

  1. 關閉三個節點服務

# mongod --dbpath /usr/local/mongodb/shard1/data --logpath /usr/local/mongodb/shard1/logs/mongodb.log --port 27017 --logappend --bind_ip 0.0.0.0 --fork --shutdown

# mongod --dbpath /usr/local/mongodb/shard2/data --logpath /usr/local/mongodb/shard2/logs/mongodb.log --port 27018 --logappend --bind_ip 0.0.0.0 --fork --shutdown

# mongod --dbpath /usr/local/mongodb/shard3/data --logpath /usr/local/mongodb/shard3/logs/mongodb.log --port 27019 --logappend --bind_ip 0.0.0.0 --fork --shutdown

  1. 修改每個節點配置檔案中replSetName改為rs2;

# vim /usr/local/mongodb/shard1/etc/mongod.conf

# vim /usr/local/mongodb/shard2/etc/mongod.conf

# vim /usr/local/mongodb/shard3/etc/mongod.conf

# 副本集叢集配置

replication:

replSetName: rs2

  1. 修改每個節點配置檔案中sharding.clusterRole改為shardsvr;

# 分片叢集配置

sharding:

clusterRole: shardsvr

  1. 啟動三個節點服務;

# mongod -f /usr/local/mongodb/shard1/etc/mongod.conf

# mongod -f /usr/local/mongodb/shard2/etc/mongod.conf

# mongod -f /usr/local/mongodb/shard3/etc/mongod.conf

  1. 通路第一個節點服務并使用管理賬号登入admin庫;

# mongo -port 27017

> use admin

> db.auth('lizl','123456')

> rs.config() //會提示"NotYetInitialized"

  1. 重新加載叢集配置;

> config = {

_id: "rs2",

members: [

{_id: 0, host: "192.168.25.108:27017", priority:3},

{_id: 1, host: "192.168.25.108:27018", priority:2},

{_id: 2, host: "192.168.25.108:27019", priority:1}

]

}

> rs.initiate(config)

  1. 成功搞定!
02_MongoDB叢集環境搭建配置

3.3.4 修改其他伺服器

按照上述章節修改其他伺服器109,注意兩個地方别改錯了:

  1. 修改每個節點配置檔案中sharding.clusterRole改為shardsvr;---107 109;
  2. 修改每個節點配置檔案中replSetName改為rs3;
  3. 重新加載叢集配置;

> config = {

_id: "rs3",

members: [

{_id: 0, host: "192.168.25.109:27017", priority:3},

{_id: 1, host: "192.168.25.109:27018", priority:2},

{_id: 2, host: "192.168.25.109:27019", priority:1}

]

}

> rs.initiate(config)

至此,三個分片Shard Server(每個為三個節點的副本集叢集)搭建好了!

3.4 配置Config Server

3.4.1 建立目錄

在叢集中,Config Server 也通常配置成副本集模式來保證資料的可靠性(mongodb3.4以後要求配置伺服器也建立副本集),在此副本集名稱:rs-conf;

在三台伺服器上分别建立配置服務的目錄(同副本集建立方式):

mkdir -p /usr/local/mongodb/mongoconf/data

mkdir -p /usr/local/mongodb/mongoconf/logs

mkdir -p /usr/local/mongodb/mongoconf/etc

mkdir -p /usr/local/mongodb/mongoconf/tmp

# chown -R mongod:mongod /usr/local/mongodb/mongoconf # root使用者時不執行

3.4.2 配置檔案

在三台伺服器上/usr/local/mongodb/mongoconf/etc目錄,分别建立配置檔案:mongod-conf.conf

注意幾點:

  1. systemLog.path:路徑及檔案名
  2. storage.dbPath:路徑
  3. net.port:端口
  4. security.keyFile:key檔案目錄及檔案名,這裡要和分片Shard Server的keyFile一樣
  5. replication.replSetName:副本集名
  6. sharding.clusterRole:配置角色

實際配置時建議删除不需要的配置;删除中文注釋,行内不注釋,僅保留必須的注釋;

# cd /usr/local/mongodb/mongoconf/etc

# vim mongod-conf.conf

# 日志配置

systemLog:

destination: file

path: /usr/local/mongodb/mongoconf/logs/mongodb-conf.log

logAppend: true

# 網絡配置

net:

maxIncomingConnections: 5000

port: 27001

bindIp: 0.0.0.0

serviceExecutor : adaptive

# 存儲配置

storage:

dbPath: /usr/local/mongodb/mongoconf/data

journal:

enabled: true

commitIntervalMs: 100

# 啟動配置

processManagement:

fork: true

pidFilePath: /usr/local/mongodb/mongoconf/tmp/mongo-conf_27001.pid

# 安全配置

security:

authorization: 'enabled' # 啟用驗證

keyFile: /usr/local/mongodb/mongoconf/etc/replica_set.key # 指定分片或副本內建員之間身份驗證的key檔案存儲位置

clusterAuthMode: "keyFile" # 指定分片或副本內建員之間身份驗證模式

# 副本集叢集配置

replication:

oplogSizeMB: 1000 # 預設硬碟的5%,指定oplog的最大尺寸

replSetName: rs-conf # 指定副本集的名稱

# secondaryIndexPrefetch: 'all' # 指定副本內建員在接收oplog之前是否加載索引到記憶體,all加載所有(預設),none不加載,_id_only僅加載_id

# 分片叢集配置

sharding:

clusterRole: configsvr # 指定目前分片在叢集中的角色,shardsvr是shard節點,configsvr是config server節點

# archiveMovedChunks: false

# configDB: rs-conf/192.168.25.107:27001,192.168.25.108:27001,192.168.25.109:27001 # 告訴mongos節點config server的位址資訊

3.4.3 安全配置

所有副本集節點都必須要用同一份keyfile,一般是在一台機器上生成,然後拷貝到其他機器上,且必須有讀的權限;

這裡的配置服務的keyFile也要和Shard Server的keyFile一樣;

然後将Shard Server的/shard1/etc/keyFile複制到107、108、109的/usr/local/mongodb/mongoconf/etc目錄;

//107

# cp /usr/local/mongodb/shard1/etc/replica_set.key /usr/local/mongodb/mongoconf/etc/

//108

# cp /usr/local/mongodb/shard1/etc/replica_set.key /usr/local/mongodb/mongoconf/etc/

//109

# cp /usr/local/mongodb/shard1/etc/replica_set.key /usr/local/mongodb/mongoconf/etc/

3.4.4 初始配置

首先啟動三個伺服器的配置服務:

配置伺服器是獨立的 mongod 程序,是以可以像啟動“普通的”mongod 程序一樣啟動配置伺服器:

mongod -f /usr/local/mongodb/mongoconf/etc/mongod-conf.conf

然後通路配置服務27001,登陸mongo,進行配置伺服器副本集初始化:

# mongo -port 27001

> use admin

> config = {_id:"rs-conf",members:[

{_id:0,host:"192.168.25.107:27001"},

{_id:1,host:"192.168.25.108:27001"},

{_id:2,host:"192.168.25.109:27001"}]

}

> rs.initiate(config);

> rs.config()

> rs.status()

如果提示"replSetInitiate quorum check failed because not all proposed set members responded affirmatively: 192.168.25.108:27001 failed with Error connecting to 192.168.25.108:27001",關閉防火牆即可;

# systemctl stop firewalld.service

至此,三個配置config Server搭建好了!

3.5 路由Router Server

由于 mongos 需從配置伺服器擷取配置資訊,是以配置伺服器應先于任何 mongos 程序啟動。

目前三台伺服器的配置伺服器和分片伺服器均已啟動,現在配置三台mongos伺服器;

3.5.1 建立目錄

在三台伺服器上分别建立路由服務的目錄:

mkdir -p /usr/local/mongodb/mongos/logs

mkdir -p /usr/local/mongodb/mongos/etc

mkdir -p /usr/local/mongodb/mongos/tmp

# chown -R mongod:mongod /usr/local/mongodb/mongos # root使用者時不執行

3.5.2 配置檔案

在三台伺服器上/usr/local/mongodb/mongos/etc目錄,分别建立配置檔案:mongos.conf

注意幾點:

  1. systemLog.path:路徑及檔案名
  2. storage:不需要配置,mongos 自身并不儲存資料,它會在啟動時從配置伺服器加載叢集資料
  3. net.port:端口
  4. security.keyFile:key檔案目錄及檔案名
  5. security.authorization:不需要開啟
  6. replication:不需要配置
  7. sharding.clusterRole:不需要配置
  8. sharding.configDB:配置配置伺服器

實際配置時建議删除不需要的配置;删除中文注釋,行内不注釋,僅保留必須的注釋;

# cd /usr/local/mongodb/mongos/etc

# vim mongos.conf

# 日志配置

systemLog:

destination: file

path: /usr/local/mongodb/mongos/logs/mongos.log

logAppend: true

# 網絡配置

net:

maxIncomingConnections: 5000

port: 27000

bindIp: 0.0.0.0

serviceExecutor : adaptive

# 存儲配置

#storage:

# dbPath: /usr/local/mongodb/mongos/data

# journal:

# enabled: true

# commitIntervalMs: 100

# 啟動配置

processManagement:

fork: true

pidFilePath: /usr/local/mongodb/mongos/tmp/mongos_27000.pid

# 安全配置

security:

# authorization: 'enabled' # 啟用驗證

keyFile: /usr/local/mongodb/mongos/etc/replica_set.key # 指定分片或副本內建員之間身份驗證的key檔案存儲位置

clusterAuthMode: "keyFile" # 指定分片或副本內建員之間身份驗證模式

# 副本集叢集配置

#replication:

# oplogSizeMB: 1000 # 預設硬碟的5%,指定oplog的最大尺寸

# replSetName: rs-conf # 指定副本集的名稱

# secondaryIndexPrefetch: 'all' # 指定副本內建員在接收oplog之前是否加載索引到記憶體,all加載所有(預設),none不加載,_id_only僅加載_id

# 分片叢集配置

sharding:

# clusterRole: configsvr # 指定目前分片在叢集中的角色,shardsvr是shard節點,configsvr是config server節點

# archiveMovedChunks: false

configDB: rs-conf/192.168.25.107:27001,192.168.25.108:27001,192.168.25.109:27001 # 告訴mongos節點config server的位址資訊

3.5.3 安全配置

然後将Shard Server的/shard1/etc/keyFile複制到107、108、109的/usr/local/mongodb/mongos/etc目錄;

//107

# cp /usr/local/mongodb/shard1/etc/replica_set.key /usr/local/mongodb/mongos/etc/

//108

# cp /usr/local/mongodb/shard1/etc/replica_set.key /usr/local/mongodb/mongos/etc/

//109

# cp /usr/local/mongodb/shard1/etc/replica_set.key /usr/local/mongodb/mongos/etc/

3.5.4 啟動服務

為了保障操作,此時要把相關服務啟動起來:

首先啟動三台伺服器的配置服務config server,前述章節已經啟動過,如啟動不需要再啟動:

mongod -f /usr/local/mongodb/mongoconf/etc/mongod-conf.conf

然後啟動三台伺服器的切片服務Shard Server(三個節點副本集),每個伺服器有三個節點,都要啟動,前述章節已經啟動過,如啟動不需要再啟動;

mongod -f /usr/local/mongodb/shard1/etc/mongod.conf

mongod -f /usr/local/mongodb/shard2/etc/mongod.conf

mongod -f /usr/local/mongodb/shard3/etc/mongod.conf

最後啟動三台伺服器上的mongos服務:

# mongos -f /usr/local/mongodb/mongos/etc/mongos.conf

3.5.5 串聯配置和路由

目前搭建了mongodb配置伺服器、路由伺服器,各個分片伺服器,但此時還不能使用分片功能,需要登入mongos啟用分片;

登陸任意一台伺服器mongos服務,進行串聯:

# mongo --port 27000

> use admin

//串聯路由伺服器與配置設定副本集

> sh.addShard("rs1/192.168.25.107:27017,192.168.25.107:27018,192.168.25.107:27019")

> sh.addShard("rs2/192.168.25.108:27017,192.168.25.108:27018,192.168.25.108:27019")

> sh.addShard("rs3/192.168.25.109:27017,192.168.25.109:27018,192.168.25.109:27019")

//還可以寫成

//> db.runCommand({addShard:"rs1/192.168.25.107:27017,192.168.25.107:27018,192.168.25.107:27019"})

//檢視狀态,要先參考<3.5.6使用者操作>登陸mongos才可檢視

sh.status()

--- Sharding Status ---

sharding version: {

"_id" : 1,

"minCompatibleVersion" : 5,

"currentVersion" : 6,

"clusterId" : ObjectId("61c046d4c8ff229e63a010c2")

}

shards:

{ "_id" : "rs1", "host" : "rs1/192.168.25.107:27017,192.168.25.107:27018,192.168.25.107:27019", "state" : 1 }

{ "_id" : "rs2", "host" : "rs2/192.168.25.108:27017,192.168.25.108:27018,192.168.25.108:27019", "state" : 1 }

{ "_id" : "rs3", "host" : "rs3/192.168.25.109:27017,192.168.25.109:27018,192.168.25.109:27019", "state" : 1 }

active mongoses:

"4.4.10" : 1

autosplit:

Currently enabled: yes

balancer:

Currently enabled: yes

Currently running: no

Failed balancer rounds in last 5 attempts: 4

Last reported error: Could not find host matching read preference { mode: "primary" } for set rs2

Time of Reported error: Tue Dec 21 2021 09:57:20 GMT+0800 (CST)

Migration Results for the last 24 hours:

682 : Success

1 : Failed with error 'aborted', from rs1 to rs3

databases:

{ "_id" : "config", "primary" : "config", "partitioned" : true }

config.system.sessions

shard key: { "_id" : 1 }

unique: false

balancing: true

chunks:

rs1 342

rs2 341

rs3 341

too many chunks to print, use verbose if you want to force print

{ "_id" : "elsa", "primary" : "rs1", "partitioned" : false, "version" : { "uuid" : UUID("dd777ca9-0843-4f8b-b28c-fe492590664d"), "lastMod" : 1 } }

3.5.6 使用者操作

通路路由服務mongs 27000,用前面建立的管理賬号lizl登陸時,發現認證不了:

02_MongoDB叢集環境搭建配置

通路配置服務mongod-conf 27001,用前面建立的管理賬号lizl登陸時,也發現認證不了;

02_MongoDB叢集環境搭建配置

通路切片節點服務mongod 270017,用前面建立的管理賬号lizl登陸時,可以登入;

02_MongoDB叢集環境搭建配置

管理賬号lizl是在節點服務mongod 270017建立的;

看來在 在切片節點服務mongod 270017建立的賬号,在配置服務mongod-conf 27001和路由服務mongs 27000都不能通路;

但是切片叢集,用戶端通路的路由服務mongs 27000;是以我們要在路由服務mongs 27000下建立賬号;

首先路由服務mongs 27000下建立賬号:

//通路任意伺服器mongos

# mongo -port 27000

//建立管理使用者

> use admin

> db.createUser({user:"mongos1", pwd:"123456", roles:[

{"role":"readWrite", db:"admin"},

{"role":"dbAdmin", db:"admin"},

{"role":"userAdminAnyDatabase", db:"admin"},

{"role":"readWriteAnyDatabase", db:"admin"},

{"role":"dbAdminAnyDatabase", db:"admin"},

{"role":"clusterAdmin", db:"admin"}

]});

> db.auth('mongos1','123456');

> 登陸OK

然後删除原來的在節點建立的管理賬号lizl:(三個伺服器切片節都删除,僅在其中一個節點删除即可)

//通路任意伺服器mongos

# mongo -port 27017

//建立管理使用者

> use admin

> db.auth('lizl','123456');

> show users

> db.dropUser("lizl")

02_MongoDB叢集環境搭建配置

3.7 測試-指定資料庫集合分片

不過應用程式連接配接到mongos路由伺服器并不能自動使用分片機制,還需要設定分片配置,讓讓指定的資料庫、指定的集合分片生效。

設定分片需要在admin資料庫進行;

//登陸mongos

# mongo --port 27000

//必須在admin庫進行

> use admin

> db.auth('mongos1','123456')

//指定testdb資料庫分片生效

> db.runCommand({enablesharding:"testdb"})

//指定testdb資料庫的collection1集合分片,根據id自動分片到shard1、shard2、...上面去

> db.runCommand({shardcollection:"testdb.collection1", key:{id:"hashed"}})

//檢視collection1集合分片狀态

> db.collection1.stats()

02_MongoDB叢集環境搭建配置

//登陸mongos

# mongo 192.168.25.107:27000

> use admin

> db.auth('mongos1','123456')

//使用測試庫testdb

> use testdb

//插入資料

> for(var i = 1; i <= 100; i++) db.collection1.save({id:i, "test":"value"})

//檢視分片

> db.collection1.stats();

02_MongoDB叢集環境搭建配置
02_MongoDB叢集環境搭建配置
02_MongoDB叢集環境搭建配置

3.8 測試-用戶端連接配接

02_MongoDB叢集環境搭建配置
02_MongoDB叢集環境搭建配置

3.8 登陸使用者說明

在本文中,我們在Shard Server分片節點建立了管理賬号lizl,配置好切片叢集後,發現用lizl無法登陸通路mongos!

後來發現叢集不建議在每個單節點添加使用者,并且建議單節點關閉初始添加賬号的權限;

詳見<3.5.6 使用者調整>章節;

3.9 安全認證說明

關于内部身份認證+通路授權的說明:

副本集各個節點之間使用内部身份驗證,用于内部各個執行個體的通信,隻有相同keyfile才能互相通路,是以涉及副本集的節點都需要開啟keyFile且必須一緻;

配置服務config server、切片服務Shard Server、路由服務Router Server都是一樣的,是以都要配置keyFile且必須相同;

mongos隻做路由不儲存資料,是以不需要開啟開啟通路資料的授權authorization:enabled;

所有的mongod(配置服務config server、切片服務Shard Server)才是真正的儲存資料的分片,是以要開啟通路資料的授權authorization:enabled;

配置服務config server、切片服務Shard Server的配置檔案:

security:

keyFile: /path/xxxkeyFile.file

authorization: enabled

路由服務router server的配置檔案

security:

keyFile: /path/xxxkeyFile.file

3.10 關閉啟動說明

首先别忘了關閉防火牆!!!!!!

mongodb的啟動順序是,先啟動配置伺服器,在啟動分片,最後啟動mongos;

繼續閱讀