1. 程式人生 > >【實戰】MongoDB 分片原理概述 + 部署 MongoDB 分片群集 +【源碼包】

【實戰】MongoDB 分片原理概述 + 部署 MongoDB 分片群集 +【源碼包】

balancer test 概述 b- 使用 說明 中一 瓶頸 標記

目錄:

1· MongoDB 分片概述
2· 部署 MongoDB 分片群集
3· MongoDB 分片管理
4· 推薦 MongoDB 、MySQL 基礎文章
5· 文章總結


MongoDB 分片概述

1)什麽是分片:

1·不用專業的術語說,從字面的意思講解,就是把一塊東西分成很多很多塊。


2·稍微專業術語:分片是一種技術,它是使用多個服務器來存放數據,不再是只用一臺服務器。這樣就可以滿足大量的數據寫入,如果沒有分片技術,使用其他方法那麽隨著數據量的增加,磁盤空間、服務器壓力總會產生問題


3·分片技術是一種將海量數據水平擴展的數據庫群集系統,數據分布存儲在分片(sharding)的各個節點上,管理者通過簡單的配置就可以方便的構建一個分布式 MongoDB 分片群集


2).分片的條件

1:服務器磁盤不夠的時候


2:服務器出現寫瓶頸的時候


3:想將大量數據放在內存中提高性能


3)MongoDB 分片群集的組成

1· Shard: 分片服務器,用於存儲實際的數據,在生產環境中一個 shard server 角色可以由幾臺服務器組成一個 Replica Set 承擔,防止單點故障


2· Config Server :配置服務器,存儲了整個分片群集的配置信息,其中包括chunk信息


3· Routers :前端路由,客戶端是由它來接入,且讓整個群集看上去像單一數據庫,前端應用可以透明使用


MongoDB 分片群集的組成如下圖


技術分享圖片


部署 MongoDB 分片群集

部署前說明

1· 部署環境: CenOS 7.4


2· MongoDB 的安裝這裏不再演示,需要的朋友請點擊:MongoDB 安裝詳解


3· 需要源碼包的請點擊:MongoDB 源碼包點擊下載密碼:tpkt


1)部署開始
1·解壓源碼包、優化

[root@localhost ~]# tar xvf mongodb-linux-x86_64-3.2.1.tgz -C /opt/
[root@localhost ~]# cd /opt/
[root@localhost opt]# mv mongodb-linux-x86_64-3.2.1 /usr/local/mongodb


[root@localhost opt]# ln -s /usr/local/mongodb/bin/mongo /usr/bin/mongo
[root@localhost opt]# ln -s /usr/local/mongodb/bin/mongod /usr/bin/mongod


2·創建日誌文件和存儲文件的路徑

[root@localhost opt]# mkdir -p /data/mongodb/mongodb{1,2,3,4} ----(可以連續創建4個數據儲存目錄


[root@localhost opt]# cd /data/mongodb/
[root@localhost mongodb]# mkdir logs


[root@localhost mongodb]# touch mongodb{1,2,3,4}.log ----(創建日誌文件
[root@localhost mongodb]# chmod 777 .log ---(賦予權限


[root@localhost mongodb]# ulimit -n 25000 ----(調高shell系統所暫用的資源比例)
[root@localhost mongodb]# ulimit -u 25000 ----(放大文件數量)


3·添加配置文件

[root@localhost mongodb]# vim /usr/local/mongodb/bin/mongodb1.conf ---(添加配置文件)


添加內容如下:

  1. > port=37017 ----(配置服務器端口
  2. > dbpath=/data/mongodb/mongodb1 ----(數據存儲目錄
  3. > logpath=/data/mongodb/logs/mongodb1.log ----(指定日誌文件存儲目錄
  4. > logappend=true -----(使用追加方式寫日誌
  5. > maxConns=5000 -----(最大鏈接數
  6. > fork=true -----(後臺運行
  7. > storageEngine=mmapv1 -----(指定存儲引擎為內存映射文件
  8. > configsvr=true -----(模式為配置服務器模式)

當一個節點可用內存不足時,系統會從其他幾點分配內存

[root@localhost mongodb]# sysctl -w vm.zone_reclaim_mode=0


[root@localhost mongodb]# echo never > /sys/kernel/mm/transparent_hugepage/enabled


[root@localhost mongodb]# echo never > /sys/kernel/mm/transparent_hugepage/defrag


到這裏配置服務器已經配置完畢,接下來會配置第一個分片服務器:

[root@localhost mongodb]# cd /usr/local/mongodb/bin/
[root@localhost bin]# cp -p mongodb1.conf mongodb2.conf ---(把配置文件復制一份出來,稍作修改)
[root@localhost bin]# vim mongodb2.conf ---(修改內容如下


加粗內容需要註意與修改:

  1. > port=47017 ---(這裏的端口號需要修改
  2. > dbpath=/data/mongodb/mongodb2 ---(數據存儲路徑修改
  3. > logpath=/data/mongodb/logs/mongodb2.log ----(日誌存儲路徑修改
  4. > logappend=true
  5. > maxConns=5000
  6. > fork=true
  7. > storageEngine=mmapv1
  8. > shardsvr=true ----(這裏是最重要的,這裏的模式就是代表分片模式

配置第二個分片服務器,方法如下:

[root@localhost bin]# cp -p mongodb2.conf mongodb3.conf ---(在復制一份配置文件)


[root@localhost bin]# vim mongodb3.conf ---(修改內容如下)


修改內容如下:

  1. > port=47018 ----(端口號需要修改
  2. > dbpath=/data/mongodb/mongodb3 ----(數據存儲路徑
  3. > logpath=/data/mongodb/logs/mongodb3.log ---(日誌文件
  4. > logappend=true
  5. > maxConns=5000
  6. > fork=true
  7. > storageEngine=mmapv1
  8. > shardsvr=true

開啟3臺實例服務:

  • > [root@localhost bin]# mongod -f mongodb1.conf -----(啟動3臺實例)
  • > [root@localhost bin]# mongod -f mongodb2.conf
  • > [root@localhost bin]# mongod -f mongodb3.conf

開啟前端路由模式,這裏不明白的可以看看上面的組成圖:

  1. > [root@localhost ~]# cd /usr/local/mongodb/bin/
  2. > [root@localhost bin]# ./mongos --port 27017 --fork --logpath=/usr/local/mongodb/bin/route.log --configdb 192.168.106.154:37017 --chunkSize 1

顯示如下字符,開啟成功
2018-09-18T16:03:49.695+0800 W SHARDING [main] Running a sharded cluster with fewer than 3 config servers should only be done for testing purposes and is not recommended for production.
about to fork child process, waiting until server is ready for connections.
forked process: 41001
child process started successfully, parent exiting


現在可以進入 MongoDB 服務器

[root@localhost bin]# mongo


添加兩臺分片服務器:

mongos> sh.addShard("192.168.106.154:47017") ---(這裏註意把端口號寫正確)
{ "shardAdded" : "shard0000", "ok" : 1 }


mongos> sh.addShard("192.168.106.154:47018")
{ "shardAdded" : "shard0001", "ok" : 1 }


查看分片服務器狀態信息:

mongos> sh.status()
--- Sharding Status ---
sharding version: {
"_id" : 1,
"minCompatibleVersion" : 5,
"currentVersion" : 6,
"clusterId" : ObjectId("5ba0b1655ba2e21d63505818")
}
shards:
> { "_id" : "shard0000", "host" : "192.168.106.154:47017" }
> { "_id" : "shard0001", "host" : "192.168.106.154:47018" }
active mongoses:
"3.2.1" : 1
balancer:
Currently enabled: yes
Currently running: no
Failed balancer rounds in last 5 attempts: 0
Migration Results for the last 24 hours:
No recent migrations
databases:


寫入五萬條數據,等待測驗

mongos> for(var i=1;i<=50000;i++)db.school.insert({"id":i,"name":"tpm"+i})
WriteResult({ "nInserted" : 1 }) ----(利用 for 循環添加,只是為了驗證後面分片存儲)


查看信息是否寫入,就看前五條即可,因為數據太多。

mongos> db.school.find().limit(5)
{ "_id" : ObjectId("5ba0b3c6dcdebde5a87ce165"), "id" : 1, "name" : "tpm1" }
{ "_id" : ObjectId("5ba0b3c6dcdebde5a87ce166"), "id" : 2, "name" : "tpm2" }
{ "_id" : ObjectId("5ba0b3c6dcdebde5a87ce167"), "id" : 3, "name" : "tpm3" }
{ "_id" : ObjectId("5ba0b3c6dcdebde5a87ce168"), "id" : 4, "name" : "tpm4" }
{ "_id" : ObjectId("5ba0b3c6dcdebde5a87ce169"), "id" : 5, "name" : "tpm5" }


對 test 這個庫進行分片處理,默認寫入數據就是寫入 test

mongos> sh.enableSharding("test")
{ "ok" : 1 }


對集合建立索引

mongos> db.school.createIndex({"id":1}) ----(建立索引以 id 為列)
{
"raw" : {
"192.168.106.154:47017" : {
"createdCollectionAutomatically" : false,
"numIndexesBefore" : 1,
"numIndexesAfter" : 2,
"ok" : 1
}
},
"ok" : 1
}


對test.shcool這個數據庫中的這個school集合進行分片,指定索引為 id:1

mongos> sh.shardCollection("test.school",{"id":1}) ----(開始分片
{ "collectionsharded" : "test.school", "ok" : 1 }


查看分片狀態:

mongos> sh.status()
--- Sharding Status ---
sharding version: {
"_id" : 1,
"minCompatibleVersion" : 5,
"currentVersion" : 6,
"clusterId" : ObjectId("5ba0b1655ba2e21d63505818")
}
shards:
{ "_id" : "shard0000", "host" : "192.168.106.154:47017" }
{ "_id" : "shard0001", "host" : "192.168.106.154:47018" }

active mongoses:
"3.2.1" : 1
balancer:
Currently enabled: yes
Currently running: no
Failed balancer rounds in last 5 attempts: 0
Migration Results for the last 24 hours:
5 : Success
databases:
{ "_id" : "test", "primary" : "shard0000", "partitioned" : true }
test.school
shard key: { "id" : 1 }
unique: false
balancing: true
chunks:
shard0000 6
shard0001 5
-----(兩個分片)
以下是把五萬條數據分片存儲

      { "id" : { "$minKey" : 1 } } --&gt;&gt; { "id" : 4682 } on : shard0001 Timestamp(2, 0) 
      { "id" : 4682 } --&gt;&gt; { "id" : 9364 } on : shard0001 Timestamp(3, 0) 
      { "id" : 9364 } --&gt;&gt; { "id" : 14046 } on : shard0001 Timestamp(4, 0) 
      { "id" : 14046 } --&gt;&gt; { "id" : 18728 } on : shard0001 Timestamp(5, 0) 
      { "id" : 18728 } --&gt;&gt; { "id" : 23410 } on : shard0001 Timestamp(6, 0) 
      { "id" : 23410 } --&gt;&gt; { "id" : 28092 } on : shard0000 Timestamp(6, 1) 
      { "id" : 28092 } --&gt;&gt; { "id" : 32774 } on : shard0000 Timestamp(1, 6) 
      { "id" : 32774 } --&gt;&gt; { "id" : 37456 } on : shard0000 Timestamp(1, 7) 
      { "id" : 37456 } --&gt;&gt; { "id" : 42138 } on : shard0000 Timestamp(1, 8) 
      { "id" : 42138 } --&gt;&gt; { "id" : 46820 } on : shard0000 Timestamp(1, 9) 
      { "id" : 46820 } --&gt;&gt; { "id" : { "$maxKey" : 1 } } on : shard0000 Timestamp(1, 10

現在來模擬,由於大量的數據,導致空間不足,這時我們需要添加分片服務器:

[root@localhost bin]# cp mongodb3.conf mongodb4.conf --(復制配置文件)
[root@localhost bin]# vim mongodb4.conf ---(做如下修改)


修改內容如下:
port=47019
dbpath=/data/mongodb/mongodb4
logpath=/data/mongodb/logs/mongodb4.log
logappend=true
maxConns=5000
fork=true
storageEngine=mmapv1
shardsvr=true


[root@localhost bin]# mongod -f mongodb4.conf ---(啟動第4個實例)


[root@localhost bin]# mongo ----(進入mongo)


mongos> sh.addShard("192.168.106.154:47019")
{ "shardAdded" : "shard0002", "ok" : 1 } ---(再次添加一臺分片服務器)


再次查看狀態, 我們會發現會自動重新分片到新的服務器中
mongos> sh.status()
--- Sharding Status ---
sharding version: {
"_id" : 1,
"minCompatibleVersion" : 5,
"currentVersion" : 6,
"clusterId" : ObjectId("5ba0b1655ba2e21d63505818")
}
shards:
{ "_id" : "shard0000", "host" : "192.168.106.154:47017" }
{ "_id" : "shard0001", "host" : "192.168.106.154:47018" }
{ "_id" : "shard0002", "host" : "192.168.106.154:47019" }

active mongoses:
"3.2.1" : 1
balancer:
Currently enabled: yes
Currently running: no
Failed balancer rounds in last 5 attempts: 0
Migration Results for the last 24 hours:
8 : Success
databases:
{ "_id" : "test", "primary" : "shard0000", "partitioned" : true }
test.school
shard key: { "id" : 1 }
unique: false
balancing: true
chunks:
shard0000 4 ------(又加入一個分片服務器)
shard0001 4
shard0002 3

{ "id" : { "$minKey" : 1 } } -->> { "id" : 4682 } on : shard0002 Timestamp(9, 0)
{ "id" : 4682 } -->> { "id" : 9364 } on : shard0001 Timestamp(9, 1)
{ "id" : 9364 } -->> { "id" : 14046 } on : shard0001 Timestamp(4, 0)
{ "id" : 14046 } -->> { "id" : 18728 } on : shard0001 Timestamp(5, 0)
{ "id" : 18728 } -->> { "id" : 23410 } on : shard0001 Timestamp(6, 0)
{ "id" : 23410 } -->> { "id" : 28092 } on : shard0002 Timestamp(7, 0)
{ "id" : 28092 } -->> { "id" : 32774 } on : shard0002 Timestamp(8, 0)
{ "id" : 32774 } -->> { "id" : 37456 } on : shard0000 Timestamp(8, 1)
{ "id" : 37456 } -->> { "id" : 42138 } on : shard0000 Timestamp(1, 8)
{ "id" : 42138 } -->> { "id" : 46820 } on : shard0000 Timestamp(1, 9)
{ "id" : 46820 } -->> { "id" : { "$maxKey" : 1 } } on : shard0000 Timestamp(1, 10)


結論:我們可以知道,重新添加分片服務器會讓數據進行重新分片,並不會影響什麽,同理,刪除一臺分片服務器,那麽數據一樣會重新重整數據,進行分片。這樣的話,我們幾乎就不需要在做分片服務器的集群,因為分片服務器本來就可以添加多臺,無論是否掛掉都不會影響什麽。


還可以給分片服務器貼上自己容易記住的標簽:

mongos> sh.addShardTag("shard0000","abc00")
mongos> sh.addShardTag("shard0001","abc01")
mongos> sh.addShardTag("shard0002","abc02")


可以再次查看分片服務器:

shards:
{ "_id" : "shard0000", "host" : "192.168.106.154:47017", "tags" : [ "abc00" ] }
{ "_id" : "shard0001", "host" : "192.168.106.154:47018", "tags" : [ "abc01" ] }
{ "_id" : "shard0002", "host" : "192.168.106.154:47019", "tags" : [ "abc02" ] }


下圖是數據分片的截圖,讓效果更加直觀,重點會又標記:
技術分享圖片


關聯知識點文章推薦:

MongoDB 數據庫安裝:http://blog.51cto.com/13746824/2174874


MongoDB 復制集 + 選舉原理:http://blog.51cto.com/13746824/2175720


詳解 MySQL 高可用群集,MMM搭建高可用:http://blog.51cto.com/13746824/2173073


Amoeba 代理 MySQL 主從復制 + 讀寫分離:http://blog.51cto.com/13746824/2172139


總結:

MongoDB 分片通過在多臺服務器上分割數據,使得數據庫系統能存儲和處理更多的數據


MongoDB 分片群集主要如下三個組件:可以參考文章第一張圖:Shard 分片服務器、Config Server 配置服務器、Routers 前端路由


重新添加分片服務器會讓數據進行重新分片,並不會影響什麽,同理,刪除一臺分片服務器,那麽數據一樣會重新重整數據,進行分片!

【實戰】MongoDB 分片原理概述 + 部署 MongoDB 分片群集 +【源碼包】