【從零開始搭建後端微服務架構】-04-mongodb4.2生產環境集羣方案部署

前言

相較於mysql,mongodb的集羣方案要明朗的很多(現在無法直視mysql了),目前只有兩種成熟的集羣方式,都是由官方提供的:

高可用方案-複製集

高性能方案-分片集

下面我們就介紹下這兩種集羣方案並根據項目需求進行選型。

集羣方案介紹

高可用方案-複製集

它與mysql的主從差不多,但是增加了故障遷移,自動選舉的機制。

primary就是我們平常意義上的主節點,可以接受讀和寫請求;

secondary是從節點,默認情況下只提供數據備份的功能(也可以設置爲可讀用來接收讀請求,做讀寫分離),一個集羣可以擁有一個或多個secondary節點;

arbiter是仲裁節點,其內部沒有數據,只是參與primary的選舉。當你受制於其他原因,集羣只有偶數個節點的時候,就可以引入一個arbiter節點,它很輕量級。

 

高性能方案-分片集

由於在複製集中,primary只能有一個也就是寫請求還是處於單點的狀態,雖然可以故障遷移,但整個集羣僅僅是高可用狀態,受制於單primary不能橫向擴展。mongodb爲了解決橫向擴展的問題,提供了一套分片集羣方式。

每個shard都包含了分片集羣中的一部分數據,每一個shard都是以一個複製集的形式存在的。

mongos提供了客戶端與mongodb集羣之間交互的接口,客戶端通過操作mongos來與mongodb分片集羣交互。

config server裏面包含了整個集羣的元數據和配置信息,config server地位非常重要,所以需要使用複製集方式部署。

本系統落地方案分析

我對於mongodb的理解是它是一個對傳統mysql的補充,它存儲結構更加靈活,在海量數據的存儲,處理方面比mysql更有優勢。即使官方一直希望mongodb可以代替傳統mysql,特別在4.0支持了跨集合的事務之後其功能與傳統關係型數據庫相差無幾,但我還是對mongodb代替mysql持懷疑意見,因爲沒有聽說mongodb在互聯網行業的傳統數據庫領域有大規模成功案例。對於一個架構來說穩定性是非常重要的一環,對於強關聯數據和強事務數據我還是選擇使用mysql,引入mongodb主要是想用來存儲物聯網設備產生的監控數據和系統產生的日誌數據,其他數據可以供開發時自由發揮。

由於mongodb官網提供了完善的高可用,可擴展集羣方案,所以我們就不用像mysql那樣,將數據庫進行物理拆分。這邊選擇使用分片集羣,我們將其打造成爲一個大集羣,供整個系統使用。

1.分片集羣部署結構

這裏使用11臺機器部署一個生產環境sharding集羣,網上清一色都是三臺機器的部署方案,每臺機器上都部署一個shard1實例,一個shard2實例,一個shard3實例,一個config server實例和一個mongos實例,這樣做確實可以做到高可用,哪臺機器掛了都可以保證集羣正常運行,因爲三臺機器每一臺都有一套完整的sharding運行環境。這樣做的好處就行可以節省服務器,但我並不推薦這樣部署,不管是生產還是測試,如果真的缺乏服務器可以使用副本集來代替分片集。原因是每一臺機器都擁有集羣全量的數據,並沒有做到數據的分片存儲,雖然可以部署多個mongos實例增加寫節點個數,但在百分之80的場景下還不如三個節點的副本集來的實際。希望大家還是不要被其他帖子誤導。

地址 描述 端口
192.168.43.130 mongos節點-1 27017
192.168.43.131 mongos節點-2 27017
192.168.43.132 config server節點-1 27017
192.168.43.133 config server節點-2 27017
192.168.43.134 config server節點-3 27017
192.168.43.135 shard1節點-1 27017
192.168.43.136 shard1節點-2 27017
192.168.43.137 shard1節點-3 27017
192.168.43.138 shard2節點-1 27017
192.168.43.139 shard2節點-2 27017
192.168.43.140 shard2節點-3 27017

2.部署前的準備

下載mongodb4.2的tar包(推薦官網下載,但官網有時打不開,可以使用百度雲:),並上傳到11臺機器上,每臺機器只需上傳一份即可。在每臺機器上都解壓mongodb-linux-x86_64-rhel70-4.2.7.tgz,在解壓出來的文件夾下面創建data目錄,conf目錄和log目錄,用於存放數據文件,配置文件和日誌文件。創建完成後本目錄結構如下:

*:別忘記將每臺機器上的27017端口都開放出來

3.生成keyfile

在192.168.43.130機器上使用如下命令生成keyfile文件

sudo openssl rand -base64 741 >> /root/software/mongodb/keyfile.key --生成keyfile文件,/root/software/mongodb/keyfile.key爲生成keyfile文件的路徑和文件名。
sudo chmod 600 /root/software/mongodb/keyfile.key --爲生成的keyfile文件賦予600權限,如果不賦予600權限在集羣啓動的時候會提示keyfile文件權限過大。
然後將此文件拷貝到所有機器上,每臺機器都需要使用這個文件。一定要複製到每臺機器上,保證11臺機器上的keyfile文件是一模一樣的。keyfile文件在每臺機器上的路徑不要求相同,只要自己知道在哪就可以,但強烈建議放到mongodb的根目錄下。

4.部署config server

mongodb在3.4之後要求config server必須以副本集的形式存在,所以先我們在三臺機器上搭建一個config server副本集。

在192.168.43.132;192.168.43.133;192.168.43.134三臺機器上都做如下操作:

進入mongodb安裝目錄的conf文件夾,創建config.conf文件,文件內容如下:

systemLog:
  destination: file
  #日誌文件的存儲路徑,這裏要指定要一個具體的文件,mongodb在啓動時會自動創建這個文件
  path: /root/mongodb-cluster/log/config-server.log
  logAppend: true
storage:
  journal:
    enabled: true
  #數據文件的存儲路徑,這裏指定一個文件夾即可
  dbPath: /root/mongodb-cluster/data/
  # 是否一個庫一個文件夾
  directoryPerDB: true
net:
  #這裏可以配置ip白名單,可以按需配置,當前配置代表允許所有ip訪問(ipv4或ipv6)
  bindIpAll: true
  #mongodb監聽端口
  port: 27017
replication:
  oplogSizeMB: 2048
  # 配置節點所屬的複製集名字,後面創建複製集的時候會靠這個名字找到複製集的成員
  replSetName: configRepSet
sharding:
  # 代表當前節點在sharding集羣中是config server的角色
  clusterRole: configsvr
processManagement:
  # mongodb啓動之後是在後臺運行,不佔用控制檯
  fork: true
security:
  #開啓身份認證,後面會講解
  authorization: enabled
  #密鑰文件,用於集羣內部認證。這裏指定第三部生成keyfile文件的路徑
  keyFile: /root/mongodb-cluster/keyFile.key 

執行命令

mongod --config /root/mongodb-cluster/config.conf       

上面是啓動mongodb的命令,--config後面的參數是配置文件的路徑,讓mongodb按照配置文件配置的內容啓動。

三臺機器都做完上面的操作之後,隨便找一臺機器使用

mongo --host:localhost:27017

連接上剛剛啓動的mongodb,連接成功後出現如下界面

在當前界面輸入:

rs.initiate({
    _id: "configRepSet",
    members: [
      { _id : 0, host : "192.168.43.132:27017" },
      { _id : 1, host : "192.168.43.133:27017" },
      { _id : 2, host : "192.168.43.134:27017" }
    ]
  }
);

這段代碼告訴mongodb,開始初始化副本集。_id屬性的值爲副本集名稱,也就是在config.conf配置文件中replSetName屬性的值。member中_id的值爲序號,這裏不需要改動,從0排下來即可。member中host的值爲三個config server實例的ip和端口號。

執行完後出現如下字樣代表副本集構建成功,可以使用rs.status()查看config server副本集的狀態。

5.部署shard分片1

官方推薦,每一個分片都需要以副本集的形式部署,以提高其可用性。所以其操作與4中部署config server副本集是一樣的,這裏簡單略過。只貼出分片1的配置文件shard-1.conf

systemLog:
   destination: file
   path: "/root/mongodb-cluster/log/shard-1.log" #注意修改路徑
   logAppend: true
storage:
   journal:
      enabled: true
   dbPath: "/root/mongodb-cluster/data" #注意修改路徑
processManagement:
   fork: true
net:
   bindIpAll: true
   port: 27017   #注意修改端口
setParameter:
   enableLocalhostAuthBypass: true
replication:
   # 配置節點所屬的複製集名字,後面創建複製集的時候會靠這個名字找到複製集的成員
   replSetName: shardRepSet1
sharding:
   # 代表當前節點在sharding集羣中是分片的角色
   clusterRole: shardsvr 
security:
    #開啓權限認證,後面會講
    authorization: enabled
    keyFile: /root/mongodb-cluster/keyFile.key #密鑰文件,用於集羣內部認證

6.部署shard分片2

步驟同5相同,只不過再創建一個分片副本集而已

6.部署mongos

mongos可以根據集羣所要承載的流量情況部署一個或多個,我們這裏先部署兩個,後期可以根據壓測情況調整。

在192.168.43.130;192.168.43.131下分別執行如下步驟:

進入mongodb安裝目錄的conf文件夾,創建mongos.conf文件,文件內容如下:


systemLog:
   destination: file
   path: /root/mongodb-cluster/log/mongos.log
   logAppend: true
processManagement:
   fork: true
net:
   bindIpAll: true
   port: 27017 
setParameter:
   enableLocalhostAuthBypass: true
sharding:
   # config server副本集的地址,mongos需要從config server取集羣的元數據,所以需要指定地址
   configDB: configRepSet/192.168.43.132:27017,192.168.43.133:27017,192.168.43.134:27017
security:
    authorization: enabled
    keyFile: /root/mongodb-cluster/keyFile.key #密鑰文件,用於集羣內部認證

執行命令

mongod --config /root/mongodb-cluster/mongos.conf       

上面是啓動mongodb的命令,--config後面的參數是配置文件的路徑,讓mongodb按照配置文件配置的內容啓動。

啓動成功後mongos就部署成功了(mongos不需要副本集,其本身是一個無狀態的可橫向擴展的輕量級組件)。

7.配置集羣的權限

還記得上面配置文件中的這段配置嗎?

security:
    authorization: enabled
    keyFile: /root/mongodb-cluster/keyFile.key #密鑰文件,用於集羣內部認證

它是用來給我們的mongodb添加權限認證的。mongodb的權限認證分爲內部認證和外部認證,內部認證是指集羣間各個組件通信的權限認證,外部認證是指外部的客戶端訪問集羣組件時的認證。

內部認證:

內部認證有兩種方式,可以任選其一:keyfile和x.509。本系統就是使用的keyfile,網上有朋友說正式環境官方推薦x.509,不過我覺得都差不多,我大體看了下官網沒找到相關說法,可能是我沒找仔細,也可能在最新版4.2的文檔中已經沒有這句話了,總之使用keyfile也不會有問題。內部認證只要我們在配置文件內配置好了之後就無需認爲干預了,mongodb會自動做權限認證,對用戶是透明的。

外部認證:

外部認證就是我們平時說的登陸的賬號密碼,如果開啓了權限認證也就是authorization:爲enabled時,外部的客戶端想要連接到mongodb就需要使用用戶名和密碼。我們這裏着重說sharding-cluster的外部權限認證。

*:mongodb的用戶是在數據庫下面的,每個數據庫會有不同的用戶,而不是像mysql那樣用戶下面有一個個的數據庫,用戶還可以被授予不同的角色。對於角色的介紹,推薦一篇博文,寫的非常詳細https://www.cnblogs.com/dbabd/p/10811523.html

下面我們來配置集羣的權限認證。內部認證我們已經在配置的時候配置過了,所以我們直接來配置外部認證。我們選擇爲每一臺mongodb實例配置一個root用戶用來管理,在mongos上根據需要額外配置普通用戶,讓程序員增刪改查使用。

爲shard1設置用戶:

由於之前我們已經啓動了shard1複製集,所以我們需要找到複製集的主節點,在主節點上設置用戶(從節點不接受寫請求)。這裏我的主節點是192.168.43.135這臺,在這臺機器上使用

mongo --host localhost:27017   --連接config server

use admin   ---切換數據庫
  
db.createUser(     ---創建用戶
{
	user: "admin",
	pwd: "123456",
	roles: [ { role: "root", db: "admin" } ]
}
)

我們創建的用戶爲admin,角色爲root,是超級數據庫管理員(用戶是在數據庫下面的,root角色的用戶只能到admin庫下面創建)。

由於副本集是可以自動同步的,我們在主節點上創建用戶後,主節點會把改動同步到從庫節點,所以,從節點也會自動擁有admin用戶。

爲shard2設置用戶:

與上面步驟相同,也開一個名叫admin的root用戶

爲mongos設置用戶:

mongos的用戶比較特殊,其本身不存儲數據,也就沒有用戶數據。它鑑別用戶權限是要去config server中獲取用戶信息的(真實情況是mongos內部會有用戶信息的緩存,只要config server中用戶信息變動就會刷新mongos的緩存)。所以我們爲mongos設置用戶其實就是爲config server設置用戶。設置用戶的步驟爲:

mongos --port 27017   --連接mongos,連接mongos要用mongos命令,而不是mongo

use admin   ---切換數據庫
  
db.createUser(     ---創建用戶
{
	user: "admin",
	pwd: "123456",
	roles: [ { role: "root", db: "admin" } ]
}
)

當前節點配置完後,config server集羣的用戶也配置完了,當用戶信息更改時,又會通知所有的mongos刷新緩存,所以這一下子mongos和config server的用戶都配置完畢了。

但是在生產環境中我不推薦暴露root用戶,我們可以再創建一個擁有readWrite角色的用戶,讓程序員們使用這個用戶連接sharding集羣。

8.開啓分片集

剛纔我們僅僅是搭建了一個config server副本集,一個shard1副本集,一個shard1副本集,兩個mongos節點,但還有將集羣合併起來。下面我們就開始合併的操作。

連接任意的mongos執行如下命令:

轉到admin庫,需要使用admin庫中的用戶信息登陸
use admin
算是登陸吧
db.auth("admin","123456")
添加分片1到集羣中
sh.addShard( "shardRepSet1/192.168.43.135:27017,192.168.43.136:27017,192.168.43.137:27017")
sh.addShard( "shardRepSet1/192.168.43.138:27017,192.168.43.139:27017,192.168.43.140:27017")

*:sharding集羣並不是所有的數據都會分片存儲,只有指定數據庫爲分片數據庫,並且指定分片數據庫的某個集合爲分片集合之後,存入這個集合的數據纔會分片存儲。如果不做任何配置的數據庫和集合是不會分片的,其數據會全部存儲在主分片中,可以直接當成是存儲在副本集中,不用考慮分片的相關問題。

指定springboot數據庫爲分片數據庫:

sh.enableSharding("springboot")

指定springboot庫的user集合爲分片集合並且指定分片鍵爲id,使用hash分片:

sh.shardCollection("springboot.user", { _id : "hashed" } )

設置完成後當前user集合就是一個分片集合了,存入user集合的數據會自動分片存儲。

至此,sharding集羣構建完畢。如有疏漏出錯的地方還望指出,我會及時修改。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章