1. 程式人生 > >MongoDB基礎教程系列--第九篇 MongoDB 分片

MongoDB基礎教程系列--第九篇 MongoDB 分片

https://www.cnblogs.com/liruihuan/p/6750236.html

1、分片介紹

分片(sharding)是將資料拆分,將其分散存到不同機器上的過程。MongoDB 支援自動分片,可以使資料庫架構對應用程式不可見。對於應用程式來說,好像始終在使用一個單機的 MongoDB 伺服器一樣,另一方面,MongoDB 自動處理資料在分片上的分佈,也更容易新增和刪除分片。

請記住:複製是讓多臺伺服器擁有同樣的資料副本,每一臺伺服器都是其他伺服器的映象,而每一個分片都與其他分片擁有不同的資料子集。

通常,分片可以用來:

  • 增加可用的記憶體
  • 增加可用的磁碟空間
  • 減輕單臺伺服器的負載
  • 處理單個 mongod 伺服器無法承受的吞吐量

2、MongoDB 分片叢集組成

MongoDB 的分片叢集由以下部分組成:

shard:每個分片包含分片資料的一個子集,每個分片可以部署為一個副本集

mongos:作為一個查詢路由器,提供客戶端應用程式和分片叢集之間的介面。

config servers:配置伺服器儲存群集的元資料和配置資訊。MongoDB 3.4 版本開始,配置伺服器必須部署一個副本集。

分片叢集的配置分為 Production Configuration 和 Development Configuration,一個用於生產環境下的配置,另個用於開發或者測試環境的配置。

2.1、Production Configuration(生產環境配置)

在生產叢集(production cluster)中,如果集合資料是冗餘的,並且系統配置夠用,生產分片叢集部署,需滿足一下幾點:

  • 部署配置伺服器包含三個成員的副本集(Deploy Config Servers as a 3 member replica set)
  • 部署每一個分片可以是三個成員的副本集(Deploy each Shard as a 3 member replica set)
  • 部署可以有一個或多個路由(Deploy one or more mongos routers)

結構圖如下:

2.2、Development Configuration(開發環境配置)

測試或者開發環境,可以使用最少的元件部署一個分片叢集,這些非生產叢集包含以下元件:

  • 具有一個成員的副本集配置伺服器(A replica set config server with one member)
  • 至少一個分片作為一個成員的副本集(At least one shard as a single-member replica set)
  • 一個 mongos 例項(One mongos instance)

結構圖如下:

注意:使用測試叢集結構,僅僅用於測試或者開發。

下面用較簡單的 Development Configuration 舉例說明一下。

3、範例

接下來我們就用範例具體說明一下分片的過程,這裡準備三臺伺服器,分別為 218.245.4.11、218.245.4.12、218.245.4.13。

218.245.4.11 作為配置伺服器(config server),在該伺服器上建立一個成員的副本集。實際專案中,需要三個成員的副本集。

218.245.4.12 作為分片(shard)伺服器,在該伺服器上也建立一個成員的副本集。實際專案中,可以建立多個分片,每個分片也可以是副本集。

218.245.4.13 作為 mongos 伺服器。實際專案中,可以建立多個 mongos。

3.1 建立配置伺服器副本集(Create the Config Server Replica Set)

3.1.1 啟動配置伺服器副本集中的成員(Start a member of the config server replica set),這裡定義副本集名字為“configRep”,需要指定 --configsvr 引數,實際專案中用 --bind_ip 指定具體的IP地址

1

mongod --port 27017 --bind_ip 218.245.4.11 --configsvr  --replSet configRep --dbpath c:\data\db

3.1.2 連線到其中一個配置伺服器,用 rs.initiate() 初始化副本集

1

2

3

4

5

6

7

8

9

rs.initiate(

   {

      _id: "configRep",

      configsvr: true,

      members: [

         { _id: 0, host : "218.245.4.11:27017" }

      ]

   }

)

3.2 建立 Shard 副本集(Create the Shard Replica Sets)

3.2.1 啟動 Shard 伺服器副本集中的成員(Start a member of the shard replica set),這裡定義副本集名字為“shardRep”,需要指定 --shardsvr 引數。這裡可以不用是一個副本集,可以是單臺 mongod 伺服器。

1

mongod --port 27017 --bind_ip 218.245.4.12 --shardsvr  --replSet shardRep --dbpath c:\data\shard

3.2.2 連線到 Shard 伺服器,用 rs.initiate() 初始化副本集

1

2

3

4

5

6

7

8

rs.initiate(

   {

      _id: "shardRep"

      members: [

         { _id: 0, host : "218.245.4.12:27017" }

      ]

   }

)

3.3 啟動 mongos 例項

1

mongos --configdb configRep/218.24.5.4.11:27017 --port 27017

MongoDB 3.4 版本中,引數 --configdb 的值必須包含副本集的名稱,這也是 MongoDB 3.4 版本為什麼配置伺服器要部署為副本集的原因。

3.4 給叢集新增分片

新增分片的操作,必須在 mongos 下操作,也就是要先連上 mongos。可以用 sh.addShard() 方法新增分片

1

sh.addShard("shardRep/218.245.4.12:27017")

如果分片不用副本集,可以這樣新增分片

1

sh.addShard("218.245.4.12:27017")

3.5 設定分片儲存的資料庫

MongoDB 中用 sh.enableSharding() 方法設定需要分片儲存的資料庫,連上 mongos。

1

sh.enableSharding("liruihuan")

3.6 設定需要分片的集合

在設定分片集合之前,我們有必要了解一下片鍵(shard key)的概念。MongoDB是怎麼對集合分片的呢?這時候就用到了片鍵。片鍵是集合的一個鍵,MongoDB 根據這個鍵拆分資料。例如,如果選擇基於“name”進行分片,MongoDB 對根據不同名字進行分片:“name1”到“name100”位於第一片,“name101”到“name200”位於第二片,以此類推。

給集合分片,需要用 sh.shardCollection() 方法指定需要分片的集合和片鍵,下面例子是給 user 集合分片,片鍵為 name,連上 mongos。

1

sh.shardCollection("liruihuan.user", { name : 1 } )

注意,如果這個集合包含有資料,在用 shardCollection() 之前,我們必須用 db.collection.createIndex() 方法給片鍵建立索引。如果這個集合為空,MongoDB 在用 shardCollection() 時會建立索引。

3.7 給 user 集合新增20萬條資料

給 user 集合新增20萬條資料,看看集合是這麼分片的

1

2

3

4

for(var i = 0; i <200000; i++)

{

    db.user.insert({"name":"lrh"+i,"age":18})

}

用 sh.status() 檢視分片情況

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

--- Sharding Status ---

  sharding version: {

    "_id" : 1,

    "minCompatibleVersion" : 5,

    "currentVersion" : 6,

    "clusterId" : ObjectId("58fcb9e3f6420984b3570e11")

}

  shards:

    {  "_id" "shardRep",  "host" "shardRep/218.245.4.12:27017",  "state" : 1 }

  active mongoses:

    "3.4.3" : 1

  databases:

    {  "_id" "liruihuan",  "primary" "shardRep",  "partitioned" true }

        liruihuan.user

            shard key: { "name" : 1 }

            uniquefalse

            balancing: true

            chunks:

                shardRep    3

            "name" : { "$minKey" : 1 } } -->> { "name" : "liruihuan" } on : shardRep Timestamp(1, 1)

            "name" "liruihuan" -->> { "name" : "lrh7" } on : shardRep Timestamp(1, 2)

            "name" "lrh7" -->> { "name" : { "$maxKey" : 1 } } on : shardRep Timestamp(1, 3)

我們可以看出集合的資料被分到名為 shardRep 副本集的分片上了,我們這裡只用了一個分片,大家可以啟動多個分片,看看資料是怎麼分割的。