.NET Core+MongoDB叢集搭建與實戰

痴者工良發表於2020-10-17

安裝 MongoDB

安裝 MongoDB 網上有很多教程,MongoDB 官方文件:https://docs.mongodb.com/manual/tutorial/install-mongodb-on-ubuntu/

筆者這裡簡單寫一下安裝過程,筆者使用 ubuntu 系統。

要按照的目標版本:MongoDB 4.4 Community Edition

支援的系統:

  • 20.04 LTS (“Focal”)
  • 18.04 LTS (“Bionic”)
  • 16.04 LTS (“Xenial”)

更新軟體源

sudo apt update
sudo apt upgrade

apt 直接安裝(方法1)

如果你要安裝穩定版本,則直接使用一條命令安裝:

sudo apt install mongodb

執行命令檢查 MingoDB 的狀態:

sudo systemctl status mongodb

apt 倉庫安裝(方法2)

此種方式可以讓你安裝最新版本的 MongoDB 。

匯入包管理系統使用的公鑰

wget -qO - https://www.mongodb.org/static/pgp/server-4.4.asc | sudo apt-key add -

新增 MongoDB 的倉庫原始檔

 /etc/apt/sources.list.d/mongodb-org-4.4.list

新增 MongoDB 的倉庫源地址

# ubuntu 16.04
echo "deb [ arch=amd64,arm64 ] https://repo.mongodb.org/apt/ubuntu xenial/mongodb-org/4.4 multiverse" | sudo tee /etc/apt/sources.list.d/mongodb-org-4.4.list

# ubuntu 18.04
echo "deb [ arch=amd64,arm64 ] https://repo.mongodb.org/apt/ubuntu bionic/mongodb-org/4.4 multiverse" | sudo tee /etc/apt/sources.list.d/mongodb-org-4.4.list

# ubuntu 20.04
echo "deb [ arch=amd64,arm64 ] https://repo.mongodb.org/apt/ubuntu focal/mongodb-org/4.4 multiverse" | sudo tee /etc/apt/sources.list.d/mongodb-org-4.4.list

載入 MongoDB 的軟體包

sudo apt-get update

安裝最新穩定版本的 MongoDB

sudo apt-get install -y mongodb-org

如果你想安裝指定版本:

sudo apt-get install -y mongodb-org=4.4.1 mongodb-org-server=4.4.1 mongodb-org-shell=4.4.1 mongodb-org-mongos=4.4.1 mongodb-org-tools=4.4.1

方法1、2啟動 MongoDB

執行命令檢查 MongoDB 的狀態

sudo systemctl status mongodb

啟動 MongoDB

sudo systemctl start mongod

開機啟動 MongoDB

sudo systemctl enable mongod

檢視 MongoDB 版本

mongo --version
mongod --version

注意:由於 Linux/Unix 系統會對檔案描述符的數量或者執行緒數量加以限制,如果安裝過程或者啟動時報錯,需要自行另外查詢方法解決,這裡不再贅述。

通過二進位制包安裝(方法3)

適合網路不會或者離線安裝,有 tgzdebsource code 等方法安裝,這裡只使用 tgz 方式。

安裝依賴

# ubuntu 16.04
sudo apt-get install libcurl3 openssl liblzma5

# ubuntu 18.04 & 20.04
sudo apt-get install libcurl4 openssl liblzma5

選擇合適的系統下載二進位制包

https://www.mongodb.com/try/download/community?tck=docs_server

Package 可以選擇包的形式,如 shell(deb)、shell(tgz)。

注意,要在伺服器下載的話,就不要點選 Download,而是點選 Copy Link 複製二進位制包的下載連結。

請注意下載的軟體版本,mongos 、tagz 包含全部功能;

其它的是單獨提供 server 或者 client(shell) 功能。

本小節將提供安裝 .deb 和 tgz 包的說明,請自行選擇要安裝的包!(建議直接下載 tgz)。

不同種類的軟體包

deb 安裝 MongoDB

如果下載了 .deb 檔案,請使用下面命令安裝。

wget {下載地址}
sudo dpkg -i {軟體包名}.deb

tgz 安裝 MongoDB

如果下載了 .tar.gz 檔案,請使用下面命令安裝。

tar -zxvf mongodb-{版本}.tgz

# 下面是示例
cd mongodb-linux-x86_64-ubuntu1604-4.4.1
... ...
|-- bin
|   `-- mongo
|-- LICENSE-Community.txt
|-- MPL-2
|-- README
`-- THIRD-PARTY-NOTICES

開啟解壓的目錄,執行:

sudo cp bin/* /usr/local/bin/
# 實際上就是將二進位制可執行檔案放到 bin 目錄

啟動 MongoDB

建立資料存放目錄

sudo mkdir -p /var/lib/mongo

建立日誌存放目錄:

sudo mkdir -p /var/log/mongodb

如果不是使用 root 使用者登入,則需要獲取檔案許可權:

# whoami是你的使用者名稱
sudo chown `whoami` /var/lib/mongo
sudo chown `whoami` /var/log/mongodb

執行 MongoDB:

mongod --dbpath /var/lib/mongo --logpath /var/log/mongodb/mongod.log --fork

之後終端會提示已經成功啟動;也可以檢視 /var/log/mongodb/mongod.log 日誌檔案中的內容確定 MongoDB 的執行情況;

cat /var/log/mongodb/mongod.log 日誌檔案,會發現第一行:

pid=22639 port=27017

port 即 MongoDB 的連線埠。

解除安裝方法

apt 解除安裝方法

適合使用 映象倉庫安裝的 MongoDB。

sudo apt-get purge mongodb mongodb-clients mongodb-server mongodb-dev
sudo apt-get purge mongodb-10gen
sudo apt-get autoremove

注:執行過程報錯不用管。

tgz 解除安裝方法

適合解除安裝使用 .tar.gz 安裝的包。

rm /usr/local/bin/mongo*

指定啟動的配置

通過配置檔案

如果前面提到過配置檔案 /etc/mongod.conf,如果通過配置檔案啟動,則會方便很多,使用配置檔案啟動 MongoDB 的方法:

mongod --config /etc/mongod.conf

通過引數

通過引數啟動 MongoDB 的話,每次啟動都比較麻煩:

mongod  --bind_ip=0.0.0.0 --dbpath /var/lib/mongo --logpath /var/log/mongodb/mongod.log --fork

MongoDB 繫結IP、埠

檢視 MongoDB 配置:

# 進入 shell
mongo

# 執行
use admin
db.runCommand( { getParameter : '*' } )

預設 MongoDB 是本地服務,外界無法訪問主機的 MongoDB 服務,這裡來配置一下,使其能夠被外網訪問。

在 MongoDB 啟動後,執行以下命令修改配置。

# 繫結所有地址
mongod --bind_ip_all

# 修改埠
mongod --port 27017

或者停了 MongoDB 服務後,使用以下命令啟動:

mongod  --bind_ip=0.0.0.0 --dbpath /var/lib/mongo --logpath /var/log/mongodb/mongod.log --fork

或者手動修改 /etc/mongod.conf 配置檔案,把其中一段改成 0.0.0.0

# network interfaces
net:
  port: 27017
  bindIp: 0.0.0.0  

修改完畢後,需要關閉 MongoDB,再開啟,請參考後面 ”停止 MongoDB“ 一節。

測試遠端 IP 連線

測試連線指定 IP 和 port 的 MongoDB 服務:

mongo {你的伺服器公網IP}:27017

加上密碼驗證

設定賬號密碼

mongo

# 進入 MongoDB shell 後
use admin
db.createUser({user:"admin",pwd:"123456",roles:[{role:"root",db:"admin"}]})

如果不生效,請自行找方法解決,這裡不再贅述~

開啟登入驗證

然後開啟 /etc/mongod.conf 檔案,將 #security: 改成:

security:
  authorization: enabled

如果不生效,請自行找方法解決,這裡不再贅述~

停止 MongoDB

mongod --dbpath /var/lib/mongo --logpath /var/log/mongodb/mongod.log --shutdown

搭建叢集

按照此方法,再炮製一臺伺服器就行。

建議使用 docker 一次性搞好,自己手動在物理機上面安裝,太折騰了。

接下來,我們要根據官方文件,搭建簡單的副本叢集。

官方文件地址:https://docs.mongodb.com/manual/replication/

副本集

副本集是一組 MongoDB 例項來維護相同資料集。

官網文件解釋:一個副本集包含多個資料承載節點和一個仲裁器節點(可選)。在資料承載節點中,只有一個成員被視為主要節點,而其他節點則被視為次要節點。

用一下官方的圖:

mongoDB副本集

故障轉移

圖中有三臺 MongoDB 例項,當 Primary 掛了後,Secondary 可以換掉掛了的伺服器,成為新的 Primary。

故障轉移

由於我只有兩臺伺服器,因此只能組雙機熱備。

方案

主節點(Primary)

對外接收所有請求,然後將修改同步到所有 Secondary 中。

當 主節點(Primary) 掛了後,其它 Secondary 或者 Arbiter 節點就會重新選舉一個主節點出來。

副本節點(Secondary)

副本節點是備胎,資料集跟主節點(Primary)一致,當主節點掛了後,有機會成為正胎(Primary)。

仲裁者(Arbiter)

不儲存資料集,也不能成為(Primary)。作用是當主節點掛了後,投票給 Secondary,讓 Secondary 成為 Primary。

但是怎麼配置原有的 MongoDB 例項,使其成為 Primary - Secondary 叢集呢?Google 了很久。

找到 MongoDB 官方的文件:

https://docs.mongodb.com/manual/tutorial/deploy-replica-set/

設計例項名稱

在 primary 機器和 secondary 機器上,分別開啟 /etc/mongod.conf 檔案,找到 #replication,設定節點名稱。

replication:
  replSetName: {名稱}

primary 機器設定 primary,secondary 機器設定 beitai

replSetName 的作用解釋如下:

https://docs.mongodb.com/manual/reference/configuration-options/#replication.replSetName

也可以在啟動 MongoDB 時加上 --replSet "beitai" 的引數。

mongod --replSet "beitai" ... ...

請停止 MongoDB 後,使用長命令的方法啟動 MongoDB

請在要設定為 Primary 的機器,執行:

mongod --replSet "primary" --bind_ip=0.0.0.0 --dbpath /var/lib/mongo --logpath /var/log/mongodb/mongod.log --fork

請在要設定為 Secondary 的機器,執行:

mongod --replSet "beitai" --bind_ip=0.0.0.0 --dbpath /var/lib/mongo --logpath /var/log/mongodb/mongod.log --fork

如何建立叢集

必須要做到以下兩點配置:

  • Add Members to a Replica Set
  • Deploy a Replica Set

筆者在這裡踩了很大的坑,試了很多種方法和配置才成功。

啟動兩個例項(配置)

提前說明,如果使用 rs. 指令配置例項,想重新配置,出現 ”"errmsg" : "already initialized"“,可以使用 rs.reconfig() 清除配置。

rsconf = rs.conf()
rsconf.members = [{_id: 1, host: "本機的ip:27017"}]
rs.reconfig(rsconf, {force: true})

在 Secondary 機器,執行命令停止執行:

mongod --dbpath /var/lib/mongo --logpath /var/log/mongodb/mongod.log --shutdown

重新啟動 Secondary 機器:

mongod --replSet "beitai" --bind_ip=0.0.0.0 --dbpath /var/lib/mongo --logpath /var/log/mongodb/mongod.log --fork

設定為 Secondary 節點:

rs.initiate(
   {
      _id: "beitai",
      version: 1,
      members: [
         { _id: 0, host : "primary的ip:27017" }
         { _id: 1, host : "secondary的ip:27017" }
      ]
   }
)

注:id是優先順序。

在 primary 機器,執行命令停止執行:

mongod --dbpath /var/lib/mongo --logpath /var/log/mongodb/mongod.log --shutdown

重新啟動 primary:

mongod --replSet "beitai" --bind_ip=0.0.0.0 --dbpath /var/lib/mongo --logpath /var/log/mongodb/mongod.log --fork

在 primary 進入 shell:

mongo

執行命令進行初始化並設定自己為 primary:

rs.initiate(
   {
      _id: "primary",
      version: 1,
      members: [
         { _id: 0, host : "primary的ip:27017" },
         { _id: 1, host : "secondary的ip:27017" }
      ]
   }
)

分別在兩個例項開啟 mongo shell,執行:

rs.status()

發現:

beitai:SECONDARY> 
...
primary:PRIMARY>

使用工具連線 MongoDB 並建立一個名為 Test 的資料庫:

連線MongoDB

副本集狀態檢視

檢視複製延遲:

rs.printSlaveReplicationInfo()

執行結果:

WARNING: printSlaveReplicationInfo is deprecated and may be removed in the next major release. Please use printSecondaryReplicationInfo instead.
source: *.*.*.*:27017
	syncedTo: Sat Oct 17 2020 20:02:49 GMT+0800 (CST)
	0 secs (0 hrs) behind the freshest member (no primary available at the moment)
source: *.*.*.*:27017
	syncedTo: Thu Jan 01 1970 08:00:00 GMT+0800 (CST)
	1602936169 secs (445260.05 hrs) behind the freshest member (no primary available at the moment)

.NET Core 連線 MongoDB

.NET 程式要連線 MongoDB ,需要通過 Nuget 包安裝 MongoDB.Driver 驅動。

我們來建立一個控制檯程式,Nuget 搜尋 MongoDB.Driver 並安裝,接下來一步步使用連線 MongoDB。

文件地址:https://mongodb.github.io/mongo-csharp-driver/2.10/getting_started/

新增 using 引用:

using MongoDB.Bson;
using MongoDB.Driver;

連線 MongoDB

var client = new MongoClient("mongodb://primary的ip:27017,secondary的ip:27017");

獲取資料庫

IMongoDatabase database = client.GetDatabase("Test");

獲取文件集合

var collection = database.GetCollection<BsonDocument>("MyCollection");

插入文件(json)

            var document = new BsonDocument
            {
                { "name", "MongoDB" },
                { "type", "Database" },
                { "count", 1 },
                { "info", new BsonDocument
                {
                    { "x", 203 },
                    { "y", 102 }
                }}
            };

其源結構的 json 如下:

{
     "name": "MongoDB",
     "type": "database",
     "count": 1,
     "info": {
         x: 203,
         y: 102
     }
}

將文件插入到集合中:

            collection.InsertOne(document);
            // 使用非同步 await collection.InsertOneAsync(document);

然後執行程式,一會兒後,開啟 MongoDB 管理器,檢視集合。

相關文章