主頁 > 資料庫 > 分布式檔案存盤資料庫之MongoDB分片集群

分布式檔案存盤資料庫之MongoDB分片集群

2020-11-12 06:58:55 資料庫

  前文我們聊到了mongodb的副本集以及配置副本集,回顧請參考https://www.cnblogs.com/qiuhom-1874/p/13953598.html;今天我們來聊下mongodb的分片;

  1、什么是分片?為什么要分片?

  我們知道資料庫服務器一般出現瓶頸是在磁盤io上,或者高并發網路io,又或者單臺server的cpu、記憶體等等一系列原因;于是,為了解決這些瓶頸問題,我們就必須擴展服務器性能;通常擴展服務器有向上擴展和向外擴展;所謂向上擴展就是給服務器加更大的磁盤,使用更大更好的記憶體,更換更好的cpu;這種擴展在一定程度上是可以解決性能瓶頸問題,但隨著資料量大增大,瓶頸會再次出現;所以通常這種向上擴展的方式不推薦;向外擴展是指一臺服務器不夠加兩臺,兩臺不夠加三臺,以這種方式擴展,只要出現瓶頸我們就可以使用增加服務器來解決;這樣一來服務器性能解決了,但用戶的讀寫怎么分散到多個服務器上去呢?所以我們還要想辦法把資料切分成多塊,讓每個服務器只保存整個資料集的部分資料,這樣一來使得原來一個很大的資料集就通過切片的方式,把它切分成多分,分散的存放在多個服務器上,這就是分片;分片是可以有效解決用戶寫操作性能瓶頸;雖然解決了服務器性能問題和用戶寫性能問題,同時也帶來了一個新問題,就是用戶的查詢;我們把整個資料集分散到多個server上,那么用戶怎么查詢資料呢?比如用戶要查詢年齡大于30的用戶,該怎么查詢呢?而年齡大于30的用戶的資料,可能server1上有一部分資料,server2上有部分資料,我們怎么才能夠把所有滿足條件的資料全部查詢到呢?這個場景有點類似我們之前說的mogilefs的架構,用戶上傳圖片到mogilefs首先要把圖片的元資料寫進tracker,然后在把資料存放在對應的data節點,這樣一來用戶來查詢,首先找tracker節點,tracker會把用戶的請求檔案的元資料告訴客戶端,然后客戶端在到對應的data節點取資料,最后拼湊成一張圖片;而在mongodb上也是很類似,不同的的是在mogilefs上,客戶端需要自己去和后端的data節點互動,取出資料;在mongdb上客戶端不需要直接和后端的data節點互動,而是通過mongodb專有的客戶端代理去代客戶端互動,最后把資料統一由代理回傳給客戶端;這樣一來就可以解決用戶的查詢問題;簡單講所謂分片就是把一個大的資料集通過切分的方式切分成多分,分散的存放在多個服務器上;分片的目的是為了解決資料量過大而導致的性能問題;

  2、資料集分片示意圖

  提示:我們通過分片,可以將原本1T的資料集,平均分成4分,每個節點存盤原有資料集的1/4,使得原來用一臺服務器處理1T的資料,現在可以用4臺服務器來處理,這樣一來就有效的提高了資料處理程序;這也是分布式系統的意義;在mongodb中我們把這種共同處理一個資料集的部分資料的節點叫shard,我們把使用這種分片機制的mongodb集群就叫做mongodb分片集群;

  3、mongodb分片集群架構

 

  提示:在mongodb分片集群中,通常有三類角色,第一類是router角色,router角色主要用來接收客戶端的讀寫請求,主要運行mongos這個服務;為了使得router角色的高可用,通常會用多個節點來組成router高可用集群;第二類是config server,這類角色主要用來保存mongodb分片集群中的資料和集群的元資料資訊,有點類似mogilefs中的tracker的作用;為了保證config server的高可用性,通常config server也會將其運行為一個副本集;第三類是shard角色,這類角色主要用來存放資料,類似mogilefs的資料節點,為了保證資料的高可用和完整性,通常每個shard是一個副本集;

  4、mongodb分片集群作業程序

  首先用戶將請求發送給router,router接收到用戶請求,然后去找config server拿對應請求的元資料資訊,router拿到元資料資訊后,然后再向對應的shard請求資料,最后將資料整合后回應給用戶;在這個程序中router 就相當于mongodb的一個客戶端代理;而config server用來存放資料的元資料資訊,這些資訊主要包含了那些shard上存放了那些資料,對應的那些資料存放在那些shard上,和mogilefs上的tracker非常類似,主要存放了兩張表,一個是以資料為中心的一張表,一個是以shard節點為中心的一張表;

   5、mongodb是怎么分片的?

  在mongodb的分片集群中,分片是按照collection欄位來分的,我們把指定的欄位叫shard key;根據shard key的取值不同和應用場景,我們可以基于shard key取值范圍來分片,也可以基于shard key做hash分片;分好片以后將結果保存在config server上;在configserver 上保存了每一個分片對應的資料集;比如我們基于shardkey的范圍來分片,在configserver上就記錄了一個連續范圍的shardkey的值都保存在一個分片上;如下圖

  上圖主要描述了基于范圍的分片,從shardkey最小值到最大值進行分片,把最小值到-75這個范圍值的資料塊保存在第一個分片上,把-75到25這個范圍值的資料塊保存在第二個分片上,依次類推;這種基于范圍的分片,很容易導致某個分片上的資料過大,而有的分片上的資料又很小,造成分片資料不均勻;所以除了基與shard key的值的范圍分片,也可以基于shard key的值做hash分片,如下圖

  基于hash分片,主要是對shardkey做hash計算后,然后根據最后的結果落在哪個分片上就把對應的資料塊保存在對應的分片上;比如我們把shandkey做hash計算,然后對分片數量進行取模計算,如果得到的結果是0,那么就把對應的資料塊保存在第一個分片上,如果取得到結果是1就保存在第二個分片上依次類推;這種基于hash分片,就有效的降低分片資料不均衡的情況,因為hash計算的值是散列的;

  除了上述兩種切片的方式以外,我們還可以根據區域切片,也叫基于串列切片,如下圖

  上圖主要描述了基于區域分片,這種分片一般是針對shardkey的取值范圍不是一個順序的集合,而是一個離散的集合,比如我們可用這種方式對全國省份這個欄位做切片,把流量特別大的省份單獨切一個片,把流量小的幾個省份組合切分一片,把國外的訪問或不是國內省份的切分為一片;這種切片有點類似給shardkey做分類;不管用什么方式去做分片,我們盡可能的遵循寫操作要越分散越好,讀操作要越集中越好;

  6、mongodb分片集群搭建

  環境說明

主機名 角色 ip地址
node01 router 192.168.0.41
node02/node03/node04 config server replication set

192.168.0.42

192.168.0.43

192.168.0.44

node05/node06/node07 shard1 replication set

192.168.0.45

192.168.0.46

192.168.0.47

node08/node09/node10 shard2 replication set

192.168.0.48

192.168.0.49

192.168.0.50

 

 

 

 

 

 

 

 

 

 

 

 

  

 

  

  基礎環境,各server做時間同步,關閉防火墻,關閉selinux,ssh互信,主機名決議

  主機名決議

[root@node01 ~]# cat /etc/hosts
127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4
::1         localhost localhost.localdomain localhost6 localhost6.localdomain6
192.168.0.99 time.test.org time-node
192.168.0.41 node01.test.org node01
192.168.0.42 node02.test.org node02
192.168.0.43 node03.test.org node03
192.168.0.44 node04.test.org node04
192.168.0.45 node05.test.org node05
192.168.0.46 node06.test.org node06
192.168.0.47 node07.test.org node07
192.168.0.48 node08.test.org node08
192.168.0.49 node09.test.org node09
192.168.0.50 node10.test.org node10
192.168.0.51 node11.test.org node11
192.168.0.52 node12.test.org node12
[root@node01 ~]#

  準備好基礎環境以后,配置mongodb yum源

[root@node01 ~]# cat /etc/yum.repos.d/mongodb.repo
[mongodb-org]
name = MongoDB Repository
baseurl = https://mirrors.aliyun.com/mongodb/yum/redhat/7/mongodb-org/4.4/x86_64/
gpgcheck = 1
enabled = 1
gpgkey = https://www.mongodb.org/static/pgp/server-4.4.asc
[root@node01 ~]# 

  將mongodb yum源復制給其他節點

[root@node01 ~]# for i in {02..10} ; do scp /etc/yum.repos.d/mongodb.repo node$i:/etc/yum.repos.d/; done
mongodb.repo                                                                  100%  206   247.2KB/s   00:00    
mongodb.repo                                                                  100%  206   222.3KB/s   00:00    
mongodb.repo                                                                  100%  206   118.7KB/s   00:00    
mongodb.repo                                                                  100%  206   164.0KB/s   00:00    
mongodb.repo                                                                  100%  206   145.2KB/s   00:00    
mongodb.repo                                                                  100%  206   119.9KB/s   00:00    
mongodb.repo                                                                  100%  206   219.2KB/s   00:00    
mongodb.repo                                                                  100%  206   302.1KB/s   00:00    
mongodb.repo                                                                  100%  206   289.3KB/s   00:00    
[root@node01 ~]# 

  在每個節點上安裝mongodb-org這個包

for i in {01..10} ; do ssh node$i ' yum -y install mongodb-org '; done

  在config server 和shard節點上創建資料目錄和日志目錄,并將其屬主和屬組更改為mongod

[root@node01 ~]# for i in {02..10} ; do ssh node$i 'mkdir -p /mongodb/{data,log} && chown -R mongod.mongod /mongodb/ && ls -ld /mongodb'; done
drwxr-xr-x 4 mongod mongod 29 Nov 11 22:47 /mongodb
drwxr-xr-x 4 mongod mongod 29 Nov 11 22:45 /mongodb
drwxr-xr-x 4 mongod mongod 29 Nov 11 22:45 /mongodb
drwxr-xr-x 4 mongod mongod 29 Nov 11 22:45 /mongodb
drwxr-xr-x 4 mongod mongod 29 Nov 11 22:45 /mongodb
drwxr-xr-x 4 mongod mongod 29 Nov 11 22:45 /mongodb
drwxr-xr-x 4 mongod mongod 29 Nov 11 22:45 /mongodb
drwxr-xr-x 4 mongod mongod 29 Nov 11 22:45 /mongodb
drwxr-xr-x 4 mongod mongod 29 Nov 11 22:45 /mongodb
[root@node01 ~]# 

  配置shard1 replication set

[root@node05 ~]# cat /etc/mongod.conf 
systemLog:
  destination: file
  logAppend: true
  path: /mongodb/log/mongod.log

storage:
  dbPath: /mongodb/data/
  journal:
    enabled: true

processManagement:
  fork: true
  pidFilePath: /var/run/mongodb/mongod.pid
  timeZoneInfo: /usr/share/zoneinfo

net:
  bindIp: 0.0.0.0

sharding:
  clusterRole: shardsvr

replication:
  replSetName: shard1_replset
[root@node05 ~]# scp /etc/mongod.conf node06:/etc/
mongod.conf                                                                   100%  360   394.5KB/s   00:00    
[root@node05 ~]# scp /etc/mongod.conf node07:/etc/
mongod.conf                                                                   100%  360   351.7KB/s   00:00    
[root@node05 ~]#

  配置shard2 replication set

[root@node08 ~]# cat /etc/mongod.conf
systemLog:
  destination: file
  logAppend: true
  path: /mongodb/log/mongod.log

storage:
  dbPath: /mongodb/data/
  journal:
    enabled: true

processManagement:
  fork: true
  pidFilePath: /var/run/mongodb/mongod.pid
  timeZoneInfo: /usr/share/zoneinfo

net:
  bindIp: 0.0.0.0

sharding:
  clusterRole: shardsvr

replication:
  replSetName: shard2_replset
[root@node08 ~]# scp /etc/mongod.conf node09:/etc/
mongod.conf                                                                   100%  360   330.9KB/s   00:00    
[root@node08 ~]# scp /etc/mongod.conf node10:/etc/
mongod.conf                                                                   100%  360   385.9KB/s   00:00    
[root@node08 ~]# 

  啟動shard1 replication set和shard2 replication set

[root@node05 ~]# systemctl start mongod.service 
[root@node05 ~]# ss -tnl
State      Recv-Q Send-Q           Local Address:Port                          Peer Address:Port              
LISTEN     0      128                          *:22                                       *:*                  
LISTEN     0      100                  127.0.0.1:25                                       *:*                  
LISTEN     0      128                          *:27018                                    *:*                  
LISTEN     0      128                         :::22                                      :::*                  
LISTEN     0      100                        ::1:25                                      :::*                  
[root@node05 ~]#for i in {06..10} ; do ssh node$i 'systemctl start mongod.service && ss -tnl';done
State      Recv-Q Send-Q Local Address:Port               Peer Address:Port              
LISTEN     0      128          *:22                       *:*                  
LISTEN     0      100    127.0.0.1:25                       *:*                  
LISTEN     0      128          *:27018                    *:*                  
LISTEN     0      128         :::22                      :::*                  
LISTEN     0      100        ::1:25                      :::*                  
State      Recv-Q Send-Q Local Address:Port               Peer Address:Port              
LISTEN     0      128          *:22                       *:*                  
LISTEN     0      100    127.0.0.1:25                       *:*                  
LISTEN     0      128          *:27018                    *:*                  
LISTEN     0      128         :::22                      :::*                  
LISTEN     0      100        ::1:25                      :::*                  
State      Recv-Q Send-Q Local Address:Port               Peer Address:Port              
LISTEN     0      128          *:22                       *:*                  
LISTEN     0      100    127.0.0.1:25                       *:*                  
LISTEN     0      128          *:27018                    *:*                  
LISTEN     0      128         :::22                      :::*                  
LISTEN     0      100        ::1:25                      :::*                  
State      Recv-Q Send-Q Local Address:Port               Peer Address:Port              
LISTEN     0      128          *:22                       *:*                  
LISTEN     0      100    127.0.0.1:25                       *:*                  
LISTEN     0      128          *:27018                    *:*                  
LISTEN     0      128         :::22                      :::*                  
LISTEN     0      100        ::1:25                      :::*                  
State      Recv-Q Send-Q Local Address:Port               Peer Address:Port              
LISTEN     0      128          *:22                       *:*                  
LISTEN     0      100    127.0.0.1:25                       *:*                  
LISTEN     0      128          *:27018                    *:*                  
LISTEN     0      128         :::22                      :::*                  
LISTEN     0      100        ::1:25                      :::*                  
[root@node05 ~]# 

  提示:默認不指定shard監聽埠,它默認就監聽在27018埠,所以啟動shard節點后,請確保27018埠正常監聽即可;

  連接node05的mongodb 初始化shard1_replset副本集

> rs.initiate(
...   {
...     _id : "shard1_replset",
...     members: [
...       { _id : 0, host : "node05:27018" },
...       { _id : 1, host : "node06:27018" },
...       { _id : 2, host : "node07:27018" }
...     ]
...   }
... )
{
        "ok" : 1,
        "$clusterTime" : {
                "clusterTime" : Timestamp(1605107401, 1),
                "signature" : {
                        "hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
                        "keyId" : NumberLong(0)
                }
        },
        "operationTime" : Timestamp(1605107401, 1)
}
shard1_replset:SECONDARY>

  連接node08的mongodb 初始化shard2_replset副本集

> rs.initiate(
...   {
...     _id : "shard2_replset",
...     members: [
...       { _id : 0, host : "node08:27018" },
...       { _id : 1, host : "node09:27018" },
...       { _id : 2, host : "node10:27018" }
...     ]
...   }
... )
{
        "ok" : 1,
        "$clusterTime" : {
                "clusterTime" : Timestamp(1605107644, 1),
                "signature" : {
                        "hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
                        "keyId" : NumberLong(0)
                }
        },
        "operationTime" : Timestamp(1605107644, 1)
}
shard2_replset:OTHER> 

  配置configserver replication set 

[root@node02 ~]# cat /etc/mongod.conf
systemLog:
  destination: file
  logAppend: true
  path: /mongodb/log/mongod.log

storage:
  dbPath: /mongodb/data/
  journal:
    enabled: true

processManagement:
  fork: true
  pidFilePath: /var/run/mongodb/mongod.pid
  timeZoneInfo: /usr/share/zoneinfo

net:
  bindIp: 0.0.0.0

sharding:
  clusterRole: configsvr

replication:
  replSetName: cfg_replset
[root@node02 ~]# scp /etc/mongod.conf node03:/etc/mongod.conf 
mongod.conf                                                                   100%  358   398.9KB/s   00:00    
[root@node02 ~]# scp /etc/mongod.conf node04:/etc/mongod.conf  
mongod.conf                                                                   100%  358   270.7KB/s   00:00    
[root@node02 ~]# 

  啟動config server

[root@node02 ~]# systemctl start mongod.service 
[root@node02 ~]# ss -tnl
State      Recv-Q Send-Q           Local Address:Port                          Peer Address:Port              
LISTEN     0      128                          *:27019                                    *:*                  
LISTEN     0      128                          *:22                                       *:*                  
LISTEN     0      100                  127.0.0.1:25                                       *:*                  
LISTEN     0      128                         :::22                                      :::*                  
LISTEN     0      100                        ::1:25                                      :::*                  
[root@node02 ~]# ssh node03 'systemctl start mongod.service && ss -tnl'  
State      Recv-Q Send-Q Local Address:Port               Peer Address:Port              
LISTEN     0      128          *:27019                    *:*                  
LISTEN     0      128          *:22                       *:*                  
LISTEN     0      100    127.0.0.1:25                       *:*                  
LISTEN     0      128         :::22                      :::*                  
LISTEN     0      100        ::1:25                      :::*                  
[root@node02 ~]# ssh node04 'systemctl start mongod.service && ss -tnl' 
State      Recv-Q Send-Q Local Address:Port               Peer Address:Port              
LISTEN     0      128          *:27019                    *:*                  
LISTEN     0      128          *:22                       *:*                  
LISTEN     0      100    127.0.0.1:25                       *:*                  
LISTEN     0      128         :::22                      :::*                  
LISTEN     0      100        ::1:25                      :::*                  
[root@node02 ~]# 

  提示:config server 默認在不指定埠的情況監聽在27019這個埠,啟動后,請確保該埠處于正常監聽;

  連接node02的mongodb,初始化cfg_replset 副本集

> rs.initiate(
...   {
...     _id: "cfg_replset",
...     configsvr: true,
...     members: [
...       { _id : 0, host : "node02:27019" },
...       { _id : 1, host : "node03:27019" },
...       { _id : 2, host : "node04:27019" }
...     ]
...   }
... )
{
        "ok" : 1,
        "$gleStats" : {
                "lastOpTime" : Timestamp(1605108177, 1),
                "electionId" : ObjectId("000000000000000000000000")
        },
        "lastCommittedOpTime" : Timestamp(0, 0),
        "$clusterTime" : {
                "clusterTime" : Timestamp(1605108177, 1),
                "signature" : {
                        "hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
                        "keyId" : NumberLong(0)
                }
        },
        "operationTime" : Timestamp(1605108177, 1)
}
cfg_replset:SECONDARY> 

  配置router

[root@node01 ~]# cat /etc/mongos.conf
systemLog:
   destination: file
   path: /var/log/mongodb/mongos.log
   logAppend: true

processManagement:
   fork: true

net:
   bindIp: 0.0.0.0
sharding:
  configDB: "cfg_replset/node02:27019,node03:27019,node04:27019"
[root@node01 ~]# 

  提示:configDB必須是副本集名稱/成員監聽地址:port的形式,成員至少要寫一個;

  啟動router

[root@node01 ~]# mongos -f /etc/mongos.conf
about to fork child process, waiting until server is ready for connections.
forked process: 1510
child process started successfully, parent exiting
[root@node01 ~]# ss -tnl
State      Recv-Q Send-Q           Local Address:Port                          Peer Address:Port              
LISTEN     0      128                          *:22                                       *:*                  
LISTEN     0      100                  127.0.0.1:25                                       *:*                  
LISTEN     0      128                          *:27017                                    *:*                  
LISTEN     0      128                         :::22                                      :::*                  
LISTEN     0      100                        ::1:25                                      :::*                  
[root@node01 ~]#

  連接mongos,添加shard1 replication set 和shard2 replication set

mongos> sh.addShard("shard1_replset/node05:27018,node06:27018,node07:27018")
{
        "shardAdded" : "shard1_replset",
        "ok" : 1,
        "operationTime" : Timestamp(1605109085, 3),
        "$clusterTime" : {
                "clusterTime" : Timestamp(1605109086, 1),
                "signature" : {
                        "hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
                        "keyId" : NumberLong(0)
                }
        }
}
mongos> sh.addShard("shard2_replset/node08:27018,node09:27018,node10:27018")
{
        "shardAdded" : "shard2_replset",
        "ok" : 1,
        "operationTime" : Timestamp(1605109118, 2),
        "$clusterTime" : {
                "clusterTime" : Timestamp(1605109118, 3),
                "signature" : {
                        "hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
                        "keyId" : NumberLong(0)
                }
        }
}
mongos>

  提示:添加shard 副本集也是需要指明副本集名稱/成員的格式添加;

  到此分片集群就配置好了

  查看sharding 集群狀態

mongos> sh.status()
--- Sharding Status --- 
  sharding version: {
        "_id" : 1,
        "minCompatibleVersion" : 5,
        "currentVersion" : 6,
        "clusterId" : ObjectId("5fac01dd8d6fa3fe899662c8")
  }
  shards:
        {  "_id" : "shard1_replset",  "host" : "shard1_replset/node05:27018,node06:27018,node07:27018",  "state" : 1 }
        {  "_id" : "shard2_replset",  "host" : "shard2_replset/node08:27018,node09:27018,node10:27018",  "state" : 1 }
  active mongoses:
        "4.4.1" : 1
  autosplit:
        Currently enabled: yes
  balancer:
        Currently enabled:  yes
        Currently running:  yes
        Collections with active migrations: 
                config.system.sessions started at Wed Nov 11 2020 23:43:14 GMT+0800 (CST)
        Failed balancer rounds in last 5 attempts:  0
        Migration Results for the last 24 hours: 
                45 : Success
  databases:
        {  "_id" : "config",  "primary" : "config",  "partitioned" : true }
                config.system.sessions
                        shard key: { "_id" : 1 }
                        unique: false
                        balancing: true
                        chunks:
                                shard1_replset  978
                                shard2_replset  46
                        too many chunks to print, use verbose if you want to force print
mongos> 

  提示:可以看到當前分片集群中有兩個shard 副本集,分別是shard1_replset和shard2_replset;以及一個config server 

  對testdb資料庫啟用sharding功能

mongos> sh.enableSharding("testdb")
{
        "ok" : 1,
        "operationTime" : Timestamp(1605109993, 9),
        "$clusterTime" : {
                "clusterTime" : Timestamp(1605109993, 9),
                "signature" : {
                        "hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
                        "keyId" : NumberLong(0)
                }
        }
}
mongos> sh.status()
--- Sharding Status --- 
  sharding version: {
        "_id" : 1,
        "minCompatibleVersion" : 5,
        "currentVersion" : 6,
        "clusterId" : ObjectId("5fac01dd8d6fa3fe899662c8")
  }
  shards:
        {  "_id" : "shard1_replset",  "host" : "shard1_replset/node05:27018,node06:27018,node07:27018",  "state" : 1 }
        {  "_id" : "shard2_replset",  "host" : "shard2_replset/node08:27018,node09:27018,node10:27018",  "state" : 1 }
  active mongoses:
        "4.4.1" : 1
  autosplit:
        Currently enabled: yes
  balancer:
        Currently enabled:  yes
        Currently running:  no
        Failed balancer rounds in last 5 attempts:  0
        Migration Results for the last 24 hours: 
                214 : Success
  databases:
        {  "_id" : "config",  "primary" : "config",  "partitioned" : true }
                config.system.sessions
                        shard key: { "_id" : 1 }
                        unique: false
                        balancing: true
                        chunks:
                                shard1_replset  810
                                shard2_replset  214
                        too many chunks to print, use verbose if you want to force print
        {  "_id" : "testdb",  "primary" : "shard2_replset",  "partitioned" : true,  "version" : {  "uuid" : UUID("454aad2e-b397-4c88-b5c4-c3b21d37e480"),  "lastMod" : 1 } }
mongos> 

  提示:在對某個資料庫啟動sharding功能后,它會給我們分片一個主shard所謂主shard是用來存放該資料庫下沒有做分片的colleciton;對于分片的collection會分散在各個shard上;

  啟用對testdb庫下的peoples集合啟動sharding,并指明在age欄位上做基于范圍的分片

mongos> sh.shardCollection("testdb.peoples",{"age":1})
{
        "collectionsharded" : "testdb.peoples",
        "collectionUUID" : UUID("ec095411-240d-4484-b45d-b541c33c3975"),
        "ok" : 1,
        "operationTime" : Timestamp(1605110694, 11),
        "$clusterTime" : {
                "clusterTime" : Timestamp(1605110694, 11),
                "signature" : {
                        "hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
                        "keyId" : NumberLong(0)
                }
        }
}
mongos> sh.status()
--- Sharding Status --- 
  sharding version: {
        "_id" : 1,
        "minCompatibleVersion" : 5,
        "currentVersion" : 6,
        "clusterId" : ObjectId("5fac01dd8d6fa3fe899662c8")
  }
  shards:
        {  "_id" : "shard1_replset",  "host" : "shard1_replset/node05:27018,node06:27018,node07:27018",  "state" : 1 }
        {  "_id" : "shard2_replset",  "host" : "shard2_replset/node08:27018,node09:27018,node10:27018",  "state" : 1 }
  active mongoses:
        "4.4.1" : 1
  autosplit:
        Currently enabled: yes
  balancer:
        Currently enabled:  yes
        Currently running:  no
        Failed balancer rounds in last 5 attempts:  0
        Migration Results for the last 24 hours: 
                408 : Success
  databases:
        {  "_id" : "config",  "primary" : "config",  "partitioned" : true }
                config.system.sessions
                        shard key: { "_id" : 1 }
                        unique: false
                        balancing: true
                        chunks:
                                shard1_replset  616
                                shard2_replset  408
                        too many chunks to print, use verbose if you want to force print
        {  "_id" : "testdb",  "primary" : "shard2_replset",  "partitioned" : true,  "version" : {  "uuid" : UUID("454aad2e-b397-4c88-b5c4-c3b21d37e480"),  "lastMod" : 1 } }
                testdb.peoples
                        shard key: { "age" : 1 }
                        unique: false
                        balancing: true
                        chunks:
                                shard2_replset  1
                        { "age" : { "$minKey" : 1 } } -->> { "age" : { "$maxKey" : 1 } } on : shard2_replset Timestamp(1, 0) 
mongos> 

  提示:如果對應的collection存在,我們還需要先對collection創建shardkey索引,然后在使用sh.shardCollection()來對colleciton啟用sharding功能;基于范圍做分片,我們可以在多個欄位上做;

  基于hash做分片

mongos> sh.shardCollection("testdb.peoples1",{"name":"hashed"})
{
        "collectionsharded" : "testdb.peoples1",
        "collectionUUID" : UUID("f6213da1-7c7d-4d5e-8fb1-fc554efb9df2"),
        "ok" : 1,
        "operationTime" : Timestamp(1605111014, 2),
        "$clusterTime" : {
                "clusterTime" : Timestamp(1605111014, 2),
                "signature" : {
                        "hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
                        "keyId" : NumberLong(0)
                }
        }
}
mongos> sh.status()
--- Sharding Status --- 
  sharding version: {
        "_id" : 1,
        "minCompatibleVersion" : 5,
        "currentVersion" : 6,
        "clusterId" : ObjectId("5fac01dd8d6fa3fe899662c8")
  }
  shards:
        {  "_id" : "shard1_replset",  "host" : "shard1_replset/node05:27018,node06:27018,node07:27018",  "state" : 1 }
        {  "_id" : "shard2_replset",  "host" : "shard2_replset/node08:27018,node09:27018,node10:27018",  "state" : 1 }
  active mongoses:
        "4.4.1" : 1
  autosplit:
        Currently enabled: yes
  balancer:
        Currently enabled:  yes
        Currently running:  yes
        Collections with active migrations: 
                config.system.sessions started at Thu Nov 12 2020 00:10:16 GMT+0800 (CST)
        Failed balancer rounds in last 5 attempts:  0
        Migration Results for the last 24 hours: 
                480 : Success
  databases:
        {  "_id" : "config",  "primary" : "config",  "partitioned" : true }
                config.system.sessions
                        shard key: { "_id" : 1 }
                        unique: false
                        balancing: true
                        chunks:
                                shard1_replset  543
                                shard2_replset  481
                        too many chunks to print, use verbose if you want to force print
        {  "_id" : "testdb",  "primary" : "shard2_replset",  "partitioned" : true,  "version" : {  "uuid" : UUID("454aad2e-b397-4c88-b5c4-c3b21d37e480"),  "lastMod" : 1 } }
                testdb.peoples
                        shard key: { "age" : 1 }
                        unique: false
                        balancing: true
                        chunks:
                                shard2_replset  1
                        { "age" : { "$minKey" : 1 } } -->> { "age" : { "$maxKey" : 1 } } on : shard2_replset Timestamp(1, 0) 
                testdb.peoples1
                        shard key: { "name" : "hashed" }
                        unique: false
                        balancing: true
                        chunks:
                                shard1_replset  2
                                shard2_replset  2
                        { "name" : { "$minKey" : 1 } } -->> { "name" : NumberLong("-4611686018427387902") } on : shard1_replset Timestamp(1, 0) 
                        { "name" : NumberLong("-4611686018427387902") } -->> { "name" : NumberLong(0) } on : shard1_replset Timestamp(1, 1) 
                        { "name" : NumberLong(0) } -->> { "name" : NumberLong("4611686018427387902") } on : shard2_replset Timestamp(1, 2) 
                        { "name" : NumberLong("4611686018427387902") } -->> { "name" : { "$maxKey" : 1 } } on : shard2_replset Timestamp(1, 3) 
mongos> 

  提示:基于hash做分片只能在一個欄位上做,不能指定多個欄位;從上面的狀態資訊可以看到testdb.peoples被分到了shard2上,peoples1一部分分到了shard1,一部分分到了shard2上;所以在peoples中插入多少條資料,它都會寫到shard2上,在peoples1中插入資料會被寫入到shard1和shard2上;

  驗證:在peoples1 集合上插入資料,看看是否將資料分片到不同的shard上呢?

  在mongos上插入資料

mongos> use testdb
switched to db testdb
mongos> for (i=1;i<=10000;i++) db.peoples1.insert({name:"people"+i,age:(i%120),classes:(i%20)})
WriteResult({ "nInserted" : 1 })
mongos> 

  在shard1上查看資料

shard1_replset:PRIMARY> show dbs
admin   0.000GB
config  0.001GB
local   0.001GB
testdb  0.000GB
shard1_replset:PRIMARY> use testdb
switched to db testdb
shard1_replset:PRIMARY> show tables
peoples1
shard1_replset:PRIMARY> db.peoples1.find().count()
4966
shard1_replset:PRIMARY> 

  提示:在shard1上可以看到對應collection保存了4966條資料;

  在shard2上查看資料

shard2_replset:PRIMARY> show dbs
admin   0.000GB
config  0.001GB
local   0.011GB
testdb  0.011GB
shard2_replset:PRIMARY> use testdb
switched to db testdb
shard2_replset:PRIMARY> show tables
peoples
peoples1
shard2_replset:PRIMARY> db.peoples1.find().count()
5034
shard2_replset:PRIMARY> 

  提示:在shard2上可以看到有peoples集合和peoples1集合,其中peoples1集合保存了5034條資料;shard1和shard2總共就保存了我們剛才插入的10000條資料;

  ok,到此mongodb的分片集群就搭建,測驗完畢了;

轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/211590.html

標籤:NoSQL

上一篇:求陳述句,有點難

下一篇:分布式檔案存盤資料庫之MongoDB分片集群

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • GPU虛擬機創建時間深度優化

    **?桔妹導讀:**GPU虛擬機實體創建速度慢是公有云面臨的普遍問題,由于通常情況下創建虛擬機屬于低頻操作而未引起業界的重視,實際生產中還是存在對GPU實體創建時間有苛刻要求的業務場景。本文將介紹滴滴云在解決該問題時的思路、方法、并展示最終的優化成果。 從公有云服務商那里購買過虛擬主機的資深用戶,一 ......

    uj5u.com 2020-09-10 06:09:13 more
  • 可編程網卡芯片在滴滴云網路的應用實踐

    **?桔妹導讀:**隨著云規模不斷擴大以及業務層面對延遲、帶寬的要求越來越高,采用DPDK 加速網路報文處理的方式在橫向縱向擴展都出現了局限性。可編程芯片成為業界熱點。本文主要講述了可編程網卡芯片在滴滴云網路中的應用實踐,遇到的問題、帶來的收益以及開源社區貢獻。 #1. 資料中心面臨的問題 隨著滴滴 ......

    uj5u.com 2020-09-10 06:10:21 more
  • 滴滴資料通道服務演進之路

    **?桔妹導讀:**滴滴資料通道引擎承載著全公司的資料同步,為下游實時和離線場景提供了必不可少的源資料。隨著任務量的不斷增加,資料通道的整體架構也隨之發生改變。本文介紹了滴滴資料通道的發展歷程,遇到的問題以及今后的規劃。 #1. 背景 資料,對于任何一家互聯網公司來說都是非常重要的資產,公司的大資料 ......

    uj5u.com 2020-09-10 06:11:05 more
  • 滴滴AI Labs斬獲國際機器翻譯大賽中譯英方向世界第三

    **桔妹導讀:**深耕人工智能領域,致力于探索AI讓出行更美好的滴滴AI Labs再次斬獲國際大獎,這次獲獎的專案是什么呢?一起來看看詳細報道吧! 近日,由國際計算語言學協會ACL(The Association for Computational Linguistics)舉辦的世界最具影響力的機器 ......

    uj5u.com 2020-09-10 06:11:29 more
  • MPP (Massively Parallel Processing)大規模并行處理

    1、什么是mpp? MPP (Massively Parallel Processing),即大規模并行處理,在資料庫非共享集群中,每個節點都有獨立的磁盤存盤系統和記憶體系統,業務資料根據資料庫模型和應用特點劃分到各個節點上,每臺資料節點通過專用網路或者商業通用網路互相連接,彼此協同計算,作為整體提供 ......

    uj5u.com 2020-09-10 06:11:41 more
  • 滴滴資料倉庫指標體系建設實踐

    **桔妹導讀:**指標體系是什么?如何使用OSM模型和AARRR模型搭建指標體系?如何統一流程、規范化、工具化管理指標體系?本文會對建設的方法論結合滴滴資料指標體系建設實踐進行解答分析。 #1. 什么是指標體系 ##1.1 指標體系定義 指標體系是將零散單點的具有相互聯系的指標,系統化的組織起來,通 ......

    uj5u.com 2020-09-10 06:12:52 more
  • 單表千萬行資料庫 LIKE 搜索優化手記

    我們經常在資料庫中使用 LIKE 運算子來完成對資料的模糊搜索,LIKE 運算子用于在 WHERE 子句中搜索列中的指定模式。 如果需要查找客戶表中所有姓氏是“張”的資料,可以使用下面的 SQL 陳述句: SELECT * FROM Customer WHERE Name LIKE '張%' 如果需要 ......

    uj5u.com 2020-09-10 06:13:25 more
  • 滴滴Ceph分布式存盤系統優化之鎖優化

    **桔妹導讀:**Ceph是國際知名的開源分布式存盤系統,在工業界和學術界都有著重要的影響。Ceph的架構和演算法設計發表在國際系統領域頂級會議OSDI、SOSP、SC等上。Ceph社區得到Red Hat、SUSE、Intel等大公司的大力支持。Ceph是國際云計算領域應用最廣泛的開源分布式存盤系統, ......

    uj5u.com 2020-09-10 06:14:51 more
  • es~通過ElasticsearchTemplate進行聚合~嵌套聚合

    之前寫過《es~通過ElasticsearchTemplate進行聚合操作》的文章,這一次主要寫一個嵌套的聚合,例如先對sex集合,再對desc聚合,最后再對age求和,共三層嵌套。 Aggregations的部分特性類似于SQL語言中的group by,avg,sum等函式,Aggregation ......

    uj5u.com 2020-09-10 06:14:59 more
  • 爬蟲日志監控 -- Elastc Stack(ELK)部署

    傻瓜式部署,只需替換IP與用戶 導讀: 現ELK四大組件分別為:Elasticsearch(核心)、logstash(處理)、filebeat(采集)、kibana(可視化) 下載均在https://www.elastic.co/cn/downloads/下tar包,各組件版本最好一致,配合fdm會 ......

    uj5u.com 2020-09-10 06:15:05 more
最新发布
  • day02-2-商鋪查詢快取

    功能02-商鋪查詢快取 3.商鋪詳情快取查詢 3.1什么是快取? 快取就是資料交換的緩沖區(稱作Cache),是存盤資料的臨時地方,一般讀寫性能較高。 快取的作用: 降低后端負載 提高讀寫效率,降低回應時間 快取的成本: 資料一致性成本 代碼維護成本 運維成本 3.2需求說明 如下,當我們點擊商店詳 ......

    uj5u.com 2023-04-20 08:33:24 more
  • MySQL中binlog備份腳本分享

    關于MySQL的二進制日志(binlog),我們都知道二進制日志(binlog)非常重要,尤其當你需要point to point災難恢復的時侯,所以我們要對其進行備份。關于二進制日志(binlog)的備份,可以基于flush logs方式先切換binlog,然后拷貝&壓縮到到遠程服務器或本地服務器 ......

    uj5u.com 2023-04-20 08:28:06 more
  • day02-短信登錄

    功能實作02 2.功能01-短信登錄 2.1基于Session實作登錄 2.1.1思路分析 2.1.2代碼實作 2.1.2.1發送短信驗證碼 發送短信驗證碼: 發送驗證碼的介面為:http://127.0.0.1:8080/api/user/code?phone=xxxxx<手機號> 請求方式:PO ......

    uj5u.com 2023-04-20 08:27:27 more
  • 快取與資料庫雙寫一致性幾種策略分析

    本文將對幾種快取與資料庫保證資料一致性的使用方式進行分析。為保證高并發性能,以下分析場景不考慮執行的原子性及加鎖等強一致性要求的場景,僅追求最終一致性。 ......

    uj5u.com 2023-04-20 08:26:48 more
  • sql陳述句優化

    問題查找及措施 問題查找 需要找到具體的代碼,對其進行一對一優化,而非一直把關注點放在服務器和sql平臺 降低簡化每個事務中處理的問題,盡量不要讓一個事務拖太長的時間 例如檔案上傳時,應將檔案上傳這一步放在事務外面 微軟建議 4.啟動sql定時執行計劃 怎么啟動sqlserver代理服務-百度經驗 ......

    uj5u.com 2023-04-20 08:26:35 more
  • 云時代,MySQL到ClickHouse資料同步產品對比推薦

    ClickHouse 在執行分析查詢時的速度優勢很好的彌補了MySQL的不足,但是對于很多開發者和DBA來說,如何將MySQL穩定、高效、簡單的同步到 ClickHouse 卻很困難。本文對比了 NineData、MaterializeMySQL(ClickHouse自帶)、Bifrost 三款產品... ......

    uj5u.com 2023-04-20 08:26:29 more
  • sql陳述句優化

    問題查找及措施 問題查找 需要找到具體的代碼,對其進行一對一優化,而非一直把關注點放在服務器和sql平臺 降低簡化每個事務中處理的問題,盡量不要讓一個事務拖太長的時間 例如檔案上傳時,應將檔案上傳這一步放在事務外面 微軟建議 4.啟動sql定時執行計劃 怎么啟動sqlserver代理服務-百度經驗 ......

    uj5u.com 2023-04-20 08:25:13 more
  • Redis 報”OutOfDirectMemoryError“(堆外記憶體溢位)

    Redis 報錯“OutOfDirectMemoryError(堆外記憶體溢位) ”問題如下: 一、報錯資訊: 使用 Redis 的業務介面 ,產生 OutOfDirectMemoryError(堆外記憶體溢位),如圖: 格式化后的報錯資訊: { "timestamp": "2023-04-17 22: ......

    uj5u.com 2023-04-20 08:24:54 more
  • day02-2-商鋪查詢快取

    功能02-商鋪查詢快取 3.商鋪詳情快取查詢 3.1什么是快取? 快取就是資料交換的緩沖區(稱作Cache),是存盤資料的臨時地方,一般讀寫性能較高。 快取的作用: 降低后端負載 提高讀寫效率,降低回應時間 快取的成本: 資料一致性成本 代碼維護成本 運維成本 3.2需求說明 如下,當我們點擊商店詳 ......

    uj5u.com 2023-04-20 08:24:03 more
  • day02-短信登錄

    功能實作02 2.功能01-短信登錄 2.1基于Session實作登錄 2.1.1思路分析 2.1.2代碼實作 2.1.2.1發送短信驗證碼 發送短信驗證碼: 發送驗證碼的介面為:http://127.0.0.1:8080/api/user/code?phone=xxxxx<手機號> 請求方式:PO ......

    uj5u.com 2023-04-20 08:23:11 more