1. 程式人生 > >.NET Core+MongoDB叢集搭建與實戰

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

[TOC] ## 安裝 MongoDB 安裝 MongoDB 網上有很多教程,MongoDB 官方文件:[https://docs.mongodb.com/manual/tutorial/install-mongodb-on-ubuntu/](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”) 更新軟體源 ```shell sudo apt update sudo apt upgrade ``` ### apt 直接安裝(方法1) 如果你要安裝穩定版本,則直接使用一條命令安裝: ```shell sudo apt install mongodb ``` 執行命令檢查 MingoDB 的狀態: ```shell sudo systemctl status mongodb ``` ### apt 倉庫安裝(方法2) 此種方式可以讓你安裝最新版本的 MongoDB 。 **匯入包管理系統使用的公鑰** ```csharp wget -qO - https://www.mongodb.org/static/pgp/server-4.4.asc | sudo apt-key add - ``` **新增 MongoDB 的倉庫原始檔** ```csharp /etc/apt/sources.list.d/mongodb-org-4.4.list ``` **新增 MongoDB 的倉庫源地址** ```csharp # 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 的軟體包** ```shell sudo apt-get update ``` **安裝最新穩定版本的 MongoDB** ```shell sudo apt-get install -y mongodb-org ``` 如果你想安裝指定版本: ```shell 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 的狀態**: ```shell sudo systemctl status mongodb ``` **啟動 MongoDB**: ```shell sudo systemctl start mongod ``` **開機啟動 MongoDB**: ```shell sudo systemctl enable mongod ``` **檢視 MongoDB 版本**: ```shell mongo --version mongod --version ``` 注意:由於 Linux/Unix 系統會對檔案描述符的數量或者執行緒數量加以限制,如果安裝過程或者啟動時報錯,需要自行另外查詢方法解決,這裡不再贅述。 ### 通過二進位制包安裝(方法3) 適合網路不會或者離線安裝,有 `tgz`、`deb` 、`source code` 等方法安裝,這裡只使用 `tgz` 方式。 #### 安裝依賴 ```shell # 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](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)。 ![不同種類的軟體包](https://img2020.cnblogs.com/blog/1315495/202010/1315495-20201017210808666-1071566095.png) #### deb 安裝 MongoDB 如果下載了 .deb 檔案,請使用下面命令安裝。 ```shell wget {下載地址} sudo dpkg -i {軟體包名}.deb ``` #### tgz 安裝 MongoDB 如果下載了 `.tar.gz` 檔案,請使用下面命令安裝。 ```shell tar -zxvf mongodb-{版本}.tgz # 下面是示例 cd mongodb-linux-x86_64-ubuntu1604-4.4.1 ... ... |-- bin | `-- mongo |-- LICENSE-Community.txt |-- MPL-2 |-- README `-- THIRD-PARTY-NOTICES ``` 開啟解壓的目錄,執行: ```shell sudo cp bin/* /usr/local/bin/ # 實際上就是將二進位制可執行檔案放到 bin 目錄 ``` #### 啟動 MongoDB **建立資料存放目錄**: ```shell sudo mkdir -p /var/lib/mongo ``` **建立日誌存放目錄:** ```shell sudo mkdir -p /var/log/mongodb ``` 如果不是使用 root 使用者登入,則需要獲取檔案許可權: ```shell # whoami是你的使用者名稱 sudo chown `whoami` /var/lib/mongo sudo chown `whoami` /var/log/mongodb ``` **執行 MongoDB:** ```shell mongod --dbpath /var/lib/mongo --logpath /var/log/mongodb/mongod.log --fork ``` 之後終端會提示已經成功啟動;也可以檢視 `/var/log/mongodb/mongod.log` 日誌檔案中的內容確定 MongoDB 的執行情況; `cat /var/log/mongodb/mongod.log` 日誌檔案,會發現第一行: ```shell pid=22639 port=27017 ``` port 即 MongoDB 的連線埠。 ### 解除安裝方法 #### apt 解除安裝方法 適合使用 映象倉庫安裝的 MongoDB。 ```shell sudo apt-get purge mongodb mongodb-clients mongodb-server mongodb-dev sudo apt-get purge mongodb-10gen sudo apt-get autoremove ``` 注:執行過程報錯不用管。 #### tgz 解除安裝方法 適合解除安裝使用 .tar.gz 安裝的包。 ```shell rm /usr/local/bin/mongo* ``` ### 指定啟動的配置 #### 通過配置檔案 如果前面提到過配置檔案 `/etc/mongod.conf`,如果通過配置檔案啟動,則會方便很多,使用配置檔案啟動 MongoDB 的方法: ```shell mongod --config /etc/mongod.conf ``` #### 通過引數 通過引數啟動 MongoDB 的話,每次啟動都比較麻煩: ```shell mongod --bind_ip=0.0.0.0 --dbpath /var/lib/mongo --logpath /var/log/mongodb/mongod.log --fork ``` ### MongoDB 繫結IP、埠 檢視 MongoDB 配置: ```shell # 進入 shell mongo # 執行 use admin db.runCommand( { getParameter : '*' } ) ``` 預設 MongoDB 是本地服務,外界無法訪問主機的 MongoDB 服務,這裡來配置一下,使其能夠被外網訪問。 在 MongoDB 啟動後,執行以下命令修改配置。 ```shell # 繫結所有地址 mongod --bind_ip_all # 修改埠 mongod --port 27017 ``` 或者停了 MongoDB 服務後,使用以下命令啟動: ```shell 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`: ```shell # network interfaces net: port: 27017 bindIp: 0.0.0.0 ``` 修改完畢後,需要關閉 MongoDB,再開啟,請參考後面 ”停止 MongoDB“ 一節。 #### 測試遠端 IP 連線 測試連線指定 IP 和 port 的 MongoDB 服務: ```shell mongo {你的伺服器公網IP}:27017 ``` ### 加上密碼驗證 #### 設定賬號密碼 ```shell mongo # 進入 MongoDB shell 後 use admin db.createUser({user:"admin",pwd:"123456",roles:[{role:"root",db:"admin"}]}) ``` 如果不生效,請自行找方法解決,這裡不再贅述~ #### 開啟登入驗證 然後開啟 `/etc/mongod.conf` 檔案,將 `#security:` 改成: ```shell security: authorization: enabled ``` 如果不生效,請自行找方法解決,這裡不再贅述~ ### 停止 MongoDB ```shell mongod --dbpath /var/lib/mongo --logpath /var/log/mongodb/mongod.log --shutdown ``` ## 搭建叢集 按照此方法,再炮製一臺伺服器就行。 建議使用 docker 一次性搞好,自己手動在物理機上面安裝,太折騰了。 接下來,我們要根據官方文件,搭建簡單的副本叢集。 官方文件地址:[https://docs.mongodb.com/manual/replication/](https://docs.mongodb.com/manual/replication/) ### 副本集 副本集是一組 MongoDB 例項來維護相同資料集。 官網文件解釋:一個副本集包含多個數據承載節點和一個仲裁器節點(可選)。在資料承載節點中,只有一個成員被視為主要節點,而其他節點則被視為次要節點。 用一下官方的圖: ![mongoDB副本集](https://img2020.cnblogs.com/blog/1315495/202010/1315495-20201017211004159-962848062.png) ### 故障轉移 圖中有三臺 MongoDB 例項,當 Primary 掛了後,`Secondary` 可以換掉掛了的伺服器,成為新的 Primary。 ![故障轉移](https://img2020.cnblogs.com/blog/1315495/202010/1315495-20201017211023896-613602242.png) 由於我只有兩臺伺服器,因此只能組雙機熱備。 ### 方案 **主節點(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/](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](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()` 清除配置。 ```shell rsconf = rs.conf() rsconf.members = [{_id: 1, host: "本機的ip:27017"}] rs.reconfig(rsconf, {force: true}) ``` 在 Secondary 機器,執行命令停止執行: ```shell mongod --dbpath /var/lib/mongo --logpath /var/log/mongodb/mongod.log --shutdown ``` 重新啟動 Secondary 機器: ```shell mongod --replSet "beitai" --bind_ip=0.0.0.0 --dbpath /var/lib/mongo --logpath /var/log/mongodb/mongod.log --fork ``` 設定為 Secondary 節點: ```json 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: ```shell mongod --replSet "beitai" --bind_ip=0.0.0.0 --dbpath /var/lib/mongo --logpath /var/log/mongodb/mongod.log --fork ``` 在 primary 進入 shell: ```shell mongo ``` 執行命令進行初始化並設定自己為 primary: ```json 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](https://img2020.cnblogs.com/blog/1315495/202010/1315495-20201017211112680-9833465.png) ### 副本集狀態檢視 檢視複製延遲: ```shell rs.printSlaveReplicationInfo() ``` 執行結果: ```shell 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](http://www.nuget.org/packages/mongodb.driver) 並安裝,接下來一步步使用連線 MongoDB。 文件地址:[https://mongodb.github.io/mongo-csharp-driver/2.10/getting_started/](https://mongodb.github.io/mongo-csharp-driver/2.10/getting_started/) 新增 using 引用: ```csharp using MongoDB.Bson; using MongoDB.Driver; ``` 連線 MongoDB ```shell var client = new MongoClient("mongodb://primary的ip:27017,secondary的ip:27017"); ``` 獲取資料庫 ```shell IMongoDatabase database = client.GetDatabase("Test"); ``` 獲取文件集合 ```shell var collection = database.GetCollection("MyCollection"); ``` 插入文件(json) ```csharp var document = new BsonDocument { { "name", "MongoDB" }, { "type", "Database" }, { "count", 1 }, { "info", new BsonDocument { { "x", 203 }, { "y", 102 } }} }; ``` 其源結構的 json 如下: ```json { "name": "MongoDB", "type": "database", "count": 1, "info": { x: 203, y: 102 } } ``` 將文件插入到集合中: ```csharp collection.InsertOne(document); // 使用非同步 await collection.InsertOneAsync(document); ``` 然後執行程式,一會兒後,開啟 MongoDB 管理器,檢視集合。 ![](https://img2020.cnblogs.com/blog/1315495/202010/1315495-20201017211139947-12585771