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

安裝 MongoDB

安裝 MongoDB 網上有很多教程,MongoDB 官方文檔://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 - //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 ] //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 ] //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 ] //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

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

//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 一次性搞好,自己手動在物理機上面安裝,太折騰了。

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

官方文檔地址://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 官方的文檔:

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

設計實例名稱

在 primary 機器和 secondary 機器上,分別打開 /etc/mongod.conf 文件,找到 #replication,設置節點名稱。

replication:
  replSetName: {名稱}

primary 機器設置 primary,secondary 機器設置 beitai

replSetName 的作用解釋如下:

//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。

文檔地址://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 管理器,查看集合。