MongoDB的集群模式--Sharding(分片)

来源:https://www.cnblogs.com/sz-wenbin/archive/2019/06/20/11022563.html
-Advertisement-
Play Games

分片是數據跨多台機器存儲,MongoDB使用分片來支持具有非常大的數據集和高吞吐量操作的部署。 具有大型數據集或高吞吐量應用程式的資料庫系統可能會挑戰單個伺服器的容量。例如,高查詢率會耗盡伺服器的CPU容量。工作集大小大於系統的RAM會強調磁碟驅動器的I / O容量。 有兩種解決系統增長的方法:垂直 ...


 

 

分片是數據跨多台機器存儲,MongoDB使用分片來支持具有非常大的數據集和高吞吐量操作的部署。

具有大型數據集或高吞吐量應用程式的資料庫系統可能會挑戰單個伺服器的容量。例如,高查詢率會耗盡伺服器的CPU容量。工作集大小大於系統的RAM會強調磁碟驅動器的I / O容量。

有兩種解決系統增長的方法:垂直和水平縮放。

垂直擴展涉及增加單個伺服器的容量,例如使用更強大的CPU,添加更多RAM或增加存儲空間量。可用技術的局限性可能會限制單個機器對於給定工作負載而言足夠強大。此外,基於雲的提供商基於可用的硬體配置具有硬性上限。結果,垂直縮放有實際的最大值。

水平擴展涉及劃分系統數據集並載入多個伺服器,添加其他伺服器以根據需要增加容量。雖然單個機器的總體速度或容量可能不高,但每台機器處理整個工作負載的子集,可能提供比單個高速大容量伺服器更高的效率。擴展部署容量只需要根據需要添加額外的伺服器,這可能比單個機器的高端硬體的總體成本更低。權衡是基礎架構和部署維護的複雜性增加。

MongoDB支持通過分片進行水平擴展

一、組件

  • shard:每個分片包含分片數據的子集。每個分片都可以部署為副本集(replica set)。可以分片,不分片的數據存於主分片伺服器上。部署為3成員副本集
  • mongos:mongos充當查詢路由器,提供客戶端應用程式和分片集群之間的介面。可以部署多個mongos路由器。部署1個或者多個mongos
  • config servers:配置伺服器存儲群集的元數據和配置設置。從MongoDB 3.4開始,必須將配置伺服器部署為3成員副本集

 註意:應用程式或者客戶端必須要連接mongos才能與集群的數據進行交互,永遠不應連接到單個分片以執行讀取或寫入操作

shard的replica set的架構圖:

config servers的replica set的架構圖:

 

 分片策略

1、散列分片

  • 使用散列索引在共用群集中分區數據。散列索引計算單個欄位的哈希值作為索引值; 此值用作分片鍵。
  • 使用散列索引解析查詢時,MongoDB會自動計算哈希值。應用程式也不會需要計算哈希值。
  • 基於散列值的數據分佈有助於更均勻的數據分佈,尤其是在分片鍵單調變化的數據集中。

 

 2、範圍分片

  • 基於分片鍵值將數據分成範圍。然後根據分片鍵值為每個塊分配一個範圍。
  • mongos可以將操作僅路由到包含所需數據的分片。
  • 分片鍵的規劃很重要,可能導致數據不能均勻分佈。

 二、部署

1、環境說明

伺服器名稱 IP地址 操作系統版本 MongoDB版本 配置伺服器(Config Server)埠 分片伺服器1(Shard Server 1 分片伺服器2(Shard Server 2) 分片伺服器3(Shard Server 3) 功能
mongo1.example.net 10.10.18.10 Centos7.5 4.0 27027(Primary 27017(Primary 27018(Arbiter 27019(Secondary 配置伺服器和分片伺服器
mongo2.example.net 10.10.18.11 Centos7.5 4.0 27027(Secondary 27017(Secondary
27018(Primary 27019(Arbiter 配置伺服器和分片伺服器
mongo3.example.net 10.10.18.12 Centos7.5 4.0 27027(Secondary 27017(Arbiter 27018(Secondary 27019(Primary 配置伺服器和分片伺服器
mongos.example.net  192.168.11.10 Centos7.5 4.0   mongos的埠:27017     mongos

官方推薦配置中使用邏輯DNS,所以該文檔中,將伺服器名稱和IP地址的DNS映射關係寫入到各伺服器的/etc/hosts文件中

2、部署MongoDB

環境中4台伺服器的MongoDB的安裝部署,詳見:MongoDB安裝

創建環境需要的目錄:

mkdir -p /data/mongodb/data/{configServer,shard1,shard2,shard3}
mkdir -p /data/mongodb/{log,pid}

3、創建配置伺服器(Config Server)的 Replica Set(副本集)

3台伺服器上配置文件內容: /data/mongodb/configServer.conf

mongo1.example.net伺服器上

systemLog:
   destination: file
   path: "/data/mongodb/log/configServer.log"
   logAppend: true
storage:
   dbPath: "/data/mongodb/data/configServer"
   journal:
      enabled: true
   wiredTiger:
      engineConfig:
        cacheSizeGB: 2
processManagement:
   fork: true
   pidFilePath: "/data/mongodb/pid/configServer.pid"
net:
   bindIp: mongo1.example.net
   port: 27027
replication:
   replSetName: cs0
sharding:
  clusterRole: configsvr

mongo2.example.net伺服器上

systemLog:
   destination: file
   path: "/data/mongodb/log/configServer.log"
   logAppend: true
storage:
   dbPath: "/data/mongodb/data/configServer"
   journal:
      enabled: true
   wiredTiger:
      engineConfig:
        cacheSizeGB: 2
processManagement:
   fork: true
   pidFilePath: "/data/mongodb/pid/configServer.pid"
net:
   bindIp: mongo2.example.net
   port: 27027
replication:
   replSetName: cs0
sharding:
  clusterRole: configsvr

mongo3.example.net伺服器上

systemLog:
   destination: file
   path: "/data/mongodb/log/configServer.log"
   logAppend: true
storage:
   dbPath: "/data/mongodb/data/configServer"
   journal:
      enabled: true
   wiredTiger:
      engineConfig:
        cacheSizeGB: 2
processManagement:
   fork: true
   pidFilePath: "/data/mongodb/pid/configServer.pid"
net:
   bindIp: mongo3.example.net
   port: 27027
replication:
   replSetName: cs0
sharding:
  clusterRole: configsvr

啟動三台伺服器Config Server

mongod -f /data/mongodb/configServer.conf

連接到其中一個Config Server

mongo --host mongo1.example.net --port 27027

結果:

 1 MongoDB shell version v4.0.10
 2 connecting to: mongodb://mongo1.example.net:27027/?gssapiServiceName=mongodb
 3 Implicit session: session { "id" : UUID("1a4d4252-11d0-40bb-90da-f144692be88d") }
 4 MongoDB server version: 4.0.10
 5 Server has startup warnings: 
 6 2019-06-14T14:28:56.013+0800 I CONTROL  [initandlisten] 
 7 2019-06-14T14:28:56.013+0800 I CONTROL  [initandlisten] ** WARNING: Access control is not enabled for the database.
 8 2019-06-14T14:28:56.013+0800 I CONTROL  [initandlisten] **          Read and write access to data and configuration is unrestricted.
 9 2019-06-14T14:28:56.013+0800 I CONTROL  [initandlisten] ** WARNING: You are running this process as the root user, which is not recommended.
10 2019-06-14T14:28:56.013+0800 I CONTROL  [initandlisten] 
11 2019-06-14T14:28:56.013+0800 I CONTROL  [initandlisten] 
12 2019-06-14T14:28:56.013+0800 I CONTROL  [initandlisten] ** WARNING: /sys/kernel/mm/transparent_hugepage/enabled is 'always'.
13 2019-06-14T14:28:56.013+0800 I CONTROL  [initandlisten] **        We suggest setting it to 'never'
14 2019-06-14T14:28:56.014+0800 I CONTROL  [initandlisten] 
15 2019-06-14T14:28:56.014+0800 I CONTROL  [initandlisten] ** WARNING: /sys/kernel/mm/transparent_hugepage/defrag is 'always'.
16 2019-06-14T14:28:56.014+0800 I CONTROL  [initandlisten] **        We suggest setting it to 'never'
17 2019-06-14T14:28:56.014+0800 I CONTROL  [initandlisten] 
18 > 
View Code

配置Replica Set

rs.initiate(
  {
    _id: "cs0",
    configsvr: true,
    members: [
      { _id : 0, host : "mongo1.example.net:27027" },
      { _id : 1, host : "mongo2.example.net:27027" },
      { _id : 2, host : "mongo3.example.net:27027" }
    ]
  }
)

結果:

 1 {
 2         "ok" : 1,
 3         "operationTime" : Timestamp(1560493908, 1),
 4         "$gleStats" : {
 5                 "lastOpTime" : Timestamp(1560493908, 1),
 6                 "electionId" : ObjectId("000000000000000000000000")
 7         },
 8         "lastCommittedOpTime" : Timestamp(0, 0),
 9         "$clusterTime" : {
10                 "clusterTime" : Timestamp(1560493908, 1),
11                 "signature" : {
12                         "hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
13                         "keyId" : NumberLong(0)
14                 }
15         }
16 }
View Code

查看Replica Set的狀態

cs0:PRIMARY> rs.status()

結果:  可以看出三個伺服器:1個Primary,2個Secondary

  1 {
  2         "set" : "cs0",
  3         "date" : ISODate("2019-06-14T06:33:31.348Z"),
  4         "myState" : 1,
  5         "term" : NumberLong(1),
  6         "syncingTo" : "",
  7         "syncSourceHost" : "",
  8         "syncSourceId" : -1,
  9         "configsvr" : true,
 10         "heartbeatIntervalMillis" : NumberLong(2000),
 11         "optimes" : {
 12                 "lastCommittedOpTime" : {
 13                         "ts" : Timestamp(1560494006, 1),
 14                         "t" : NumberLong(1)
 15                 },
 16                 "readConcernMajorityOpTime" : {
 17                         "ts" : Timestamp(1560494006, 1),
 18                         "t" : NumberLong(1)
 19                 },
 20                 "appliedOpTime" : {
 21                         "ts" : Timestamp(1560494006, 1),
 22                         "t" : NumberLong(1)
 23                 },
 24                 "durableOpTime" : {
 25                         "ts" : Timestamp(1560494006, 1),
 26                         "t" : NumberLong(1)
 27                 }
 28         },
 29         "lastStableCheckpointTimestamp" : Timestamp(1560493976, 1),
 30         "members" : [
 31                 {
 32                         "_id" : 0,
 33                         "name" : "mongo1.example.net:27027",
 34                         "health" : 1,
 35                         "state" : 1,
 36                         "stateStr" : "PRIMARY",
 37                         "uptime" : 277,
 38                         "optime" : {
 39                                 "ts" : Timestamp(1560494006, 1),
 40                                 "t" : NumberLong(1)
 41                         },
 42                         "optimeDate" : ISODate("2019-06-14T06:33:26Z"),
 43                         "syncingTo" : "",
 44                         "syncSourceHost" : "",
 45                         "syncSourceId" : -1,
 46                         "infoMessage" : "could not find member to sync from",
 47                         "electionTime" : Timestamp(1560493919, 1),
 48                         "electionDate" : ISODate("2019-06-14T06:31:59Z"),
 49                         "configVersion" : 1,
 50                         "self" : true,
 51                         "lastHeartbeatMessage" : ""
 52                 },
 53                 {
 54                         "_id" : 1,
 55                         "name" : "mongo2.example.net:27027",
 56                         "health" : 1,
 57                         "state" : 2,
 58                         "stateStr" : "SECONDARY",
 59                         "uptime" : 102,
 60                         "optime" : {
 61                                 "ts" : Timestamp(1560494006, 1),
 62                                 "t" : NumberLong(1)
 63                         },
 64                         "optimeDurable" : {
 65                                 "ts" : Timestamp(1560494006, 1),
 66                                 "t" : NumberLong(1)
 67                         },
 68                         "optimeDate" : ISODate("2019-06-14T06:33:26Z"),
 69                         "optimeDurableDate" : ISODate("2019-06-14T06:33:26Z"),
 70                         "lastHeartbeat" : ISODate("2019-06-14T06:33:29.385Z"),
 71                         "lastHeartbeatRecv" : ISODate("2019-06-14T06:33:29.988Z"),
 72                         "pingMs" : NumberLong(0),
 73                         "lastHeartbeatMessage" : "",
 74                         "syncingTo" : "mongo1.example.net:27027",
 75                         "syncSourceHost" : "mongo1.example.net:27027",
 76                         "syncSourceId" : 0,
 77                         "infoMessage" : "",
 78                         "configVersion" : 1
 79                 },
 80                 {
 81                         "_id" : 2,
 82                         "name" : "mongo3.example.net:27027",
 83                         "health" : 1,
 84                         "state" : 2,
 85                         "stateStr" : "SECONDARY",
 86                         "uptime" : 102,
 87                         "optime" : {
 88                                 "ts" : Timestamp(1560494006, 1),
 89                                 "t" : NumberLong(1)
 90                         },
 91                         "optimeDurable" : {
 92                                 "ts" : Timestamp(1560494006, 1),
 93                                 "t" : NumberLong(1)
 94                         },
 95                         "optimeDate" : ISODate("2019-06-14T06:33:26Z"),
 96                         "optimeDurableDate" : ISODate("2019-06-14T06:33:26Z"),
 97                         "lastHeartbeat" : ISODate("2019-06-14T06:33:29.384Z"),
 98                         "lastHeartbeatRecv" : ISODate("2019-06-14T06:33:29.868Z"),
 99                         "pingMs" : NumberLong(0),
100                         "lastHeartbeatMessage" : "",
101                         "syncingTo" : "mongo1.example.net:27027",
102                         "syncSourceHost" : "mongo1.example.net:27027",
103                         "syncSourceId" : 0,
104                         "infoMessage" : "",
105                         "configVersion" : 1
106                 }
107         ],
108         "ok" : 1,
109         "operationTime" : Timestamp(1560494006, 1),
110         "$gleStats" : {
111                 "lastOpTime" : Timestamp(1560493908, 1),
112                 "electionId" : ObjectId("7fffffff0000000000000001")
113         },
114         "lastCommittedOpTime" : Timestamp(1560494006, 1),
115         "$clusterTime" : {
116                 "clusterTime" : Timestamp(1560494006, 1),
117                 "signature" : {
118                         "hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
119                         "keyId" : NumberLong(0)
120                 }
121         }
122 }
View Code

創建管理用戶

use admin
db.createUser(
  {
    user: "myUserAdmin",
    pwd: "abc123",
    roles: [{ role: "userAdminAnyDatabase", db: "admin" },"readWriteAnyDatabase"]
  }
)

開啟Config Server的登錄驗證和內部驗證

使用Keyfiles進行內部認證,在其中一臺伺服器上創建Keyfiles

openssl rand -base64 756 > /data/mongodb/keyfile
chmod 400  /data/mongodb/keyfile

將這個keyfile文件分發到其它的三台伺服器上,並保證許可權400

/data/mongodb/configServer.conf  配置文件中開啟認證

security:
   keyFile: "/data/mongodb/keyfile"
   clusterAuthMode: "keyFile"
   authorization: "enabled"

然後依次關閉2個Secondary,在關閉 Primary

mongod -f /data/mongodb/configServer.conf --shutdown

依次開啟Primary和兩個Secondary

mongod -f /data/mongodb/configServer.conf 

使用用戶密碼登錄mongo

mongo --host mongo1.example.net --port 27027 -u myUserAdmin --authenticationDatabase "admin" -p 'abc123'

註意:由於剛創建用戶的時候沒有給該用戶管理集群的許可權,所有此時登錄後,能查看所有資料庫,但是不能查看集群的狀態信息。

 1 cs0:PRIMARY> rs.status()
 2 {
 3         "operationTime" : Timestamp(1560495861, 1),
 4         "ok" : 0,
 5         "errmsg" : "not authorized on admin to execute command { replSetGetStatus: 1.0, lsid: { id: UUID(\"59dd4dc0-b34f-43b9-a341-a2f43ec1dcfa\") }, $clusterTime: { clusterTime: Timestamp(1560495849, 1), signature: { hash: BinData(0, A51371EC5AA54BB1B05ED9342BFBF03CBD87F2D9), keyId: 6702270356301807629 } }, $db: \"admin\" }",
 6         "code" : 13,
 7         "codeName" : "Unauthorized",
 8         "$gleStats" : {
 9                 "lastOpTime" : Timestamp(0, 0),
10                 "electionId" : ObjectId("7fffffff0000000000000002")
11         },
12         "lastCommittedOpTime" : Timestamp(1560495861, 1),
13         "$clusterTime" : {
14                 "clusterTime" : Timestamp(1560495861, 1),
15                 "signature" : {
16                         "hash" : BinData(0,"3UkTpXxyU8WI1TyS+u5vgewueGA="),
17                         "keyId" : NumberLong("
              
您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 準備工作下載百度網盤: https://www.baidu.com/s?wd=%E7%99%BE%E5%BA%A6%E7%BD%91%E7%9B%98&rsv_spt=1&rsv_iqid=0xfc68ab6200065efa&issp=1&f=8&rsv_bp=1&rsv_idx=2&ie=utf ...
  • 想通過VPN上網,因為各種免費或收費的VPN工具不是不穩定就是怕不靠譜,所以打算自己搭一個玩玩。以下是搭建的大致過程: 因為只是做個實驗環境,所以申請了一個騰訊雲的15天免費伺服器,以下是相關信息: 系統:CentOS 6.5 64位 公網IP:139.155.96.23 內網IP:172.27.0 ...
  • 創建一個socket,使用函數socket() socket(套接字)實質上提供了進程通信的端點,進程通信之前,雙方首先必須建立各自的一個端點,否則沒有辦法通信。通過socket將IP地址和埠綁定之後,客戶端就可以和伺服器通信了 #include<sys/socket.h> int socket( ...
  • 有時候動態sql需要進行變數的賦值,這個時候就需要調用系統的存儲過程sp_executesql了。使用中還是有些註意事項,代碼如下: 執行結果如下: ...
  • 一、查詢表空間常規語句 1.查詢表空間使用情況 SELECT Upper(F.TABLESPACE_NAME) "表空間名", D.TOT_GROOTTE_MB "表空間大小(M)", D.TOT_GROOTTE_MB - F.TOTAL_BYTES "已使用空間(M)", To_char(Roun ...
  • MySQL表操作 存儲引擎:存儲數據的方式 Innodb存儲引擎: Myisam存儲: Memory存儲引擎: 查看當前的預設存儲引擎: 表介紹 表就相當於文件,表中的一條記錄就相當於文件的一行內容,不同的是,表中的一條記錄有對應的標題,稱為表的欄位 還記得我們之前寫過的‘員工信息表作業’麽?存儲這 ...
  • 主從介紹Mysql主從又叫Replication、AB複製。簡單講就是A與B兩台機器做主從後,在A上寫數據,另外一臺B也會跟著寫數據,實現數據實時同步mysql主從是基於binlog,主上需開啟binlog才能進行主從主從過程大概有3個步驟主將更改操作記錄到binlog里從將主的binlog事件(s ...
  • 題目 編寫一個 SQL 查詢,獲取 表中第 n 高的薪水(Salary)。 例如上述 表,n = 2 時,應返回第二高的薪水 。如果不存在第 n 高的薪水,那麼查詢應返回 。 解法 摘自: https://www.cnblogs.com/grandyang/p/5348976.html ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...