Mongodb 分片
原文地址:伍儀洲的博客
介紹
分片是指將數據拆分,並分散放在多個服務器中組成一個集群,這可以將N臺服務器的性能集中到一起來處理數據,這將很大程度的提高數據處理的速度。
在Mongodb的分片中必須具備三個角色:
- 路由服務器:用於處理和響應請求,並把各個分片服務器查詢到的結果處理合並然後返回。
- 配置服務器(configServer):存儲集群、數據的描述信息。
- 分片服務器:用於儲存拆分的數據服務器。
而這三個角色都是普通的數據庫,只是扮演的角色不一樣。
它們的請求流程、響應就如下圖中表示一樣:
因為所有的應用程序都是通過路由進行請求,所以對於應用程序來說,它沒有什麽不同就如請求一個普通數據服務器一樣:
搭建配置服務器
首先我們需要搭建配置服務器,配置服務器如同分片的大腦,保存著集群和數據的描述信息。
因為Mongodb3.4版本後需要配置服務器必須配置為副本集,所以需要給配置服務器配置副本集,如果你還清楚如何搭建副本集,你可以試著看看我的上一篇文章《Mongodb 副本集》。
首先建立三個空的數據庫目錄,用於搭建配置服務器的副本集,並分別啟動它們,在啟動的時候需要加上我們副本集的名稱和--configsvr
來表示這是一個配置服務器,並分別指定不同的端口。
$ mkdir config0 config1 config2 $ mongod --dbpath config0 --replSet conServer --configsvr --port 27020 $ mongod --dbpath config1 --replSet conServer --configsvr --port 27021 $ mongod --dbpath config2 --replSet conServer --configsvr --port 27020
然後通過mongo隨意進入一個副本集成員,並為配置服務器的副本集進行配置:
$ mongo --port 27020 --host localhost > var conf = { _id: ‘conServer‘, version: 1, members: [ { _id: 0, host: ‘localhost:27020‘ }, { _id: 1, host: ‘localhost:27021‘ }, { _id: 2, host: ‘localhost:27022‘ } ] }; > rs.initiate(conf);
至此我們的配置服務器配置完成。
搭建分片服務器
官方建議我們的分片服務區至少在3個或以上才能發揮出更好的性能,我們這裏也創建三個分片服務器。
因為分片服務器沒有強制要求必須是副本集,所以下面就創建了三個單機分片服務器,但是Mongodb接受分片服務器為副本集。
下面創建三個空數據庫目錄,然後啟動它們,在啟動的時候需要加上--shardsvr
以表示這是一個分片服務器:
$ mkdir sh0 sh1 sh2
$ mongod --dbpath sh0 --shardsvr --port 27030
$ mongod --dbpath sh1 --shardsvr --port 27031
$ mongod --dbpath sh2 --shardsvr --port 27032
至此我們的分片服務器也搭建完成。
搭建路由服務器
mongodb提供了一個路由工具,它會隨著我們下載包一起下載,名字為mongos
或mongos.exe
,通過它配置路由功能。
啟動路由我們需要加上參數--configdb
,它的語法為:
--configdb 配置服務器副本集名稱/配置服務器1地址端口,配置服務器1地址端口...
啟動路由,並為路由指定一個端口,用於開放給客戶端鏈接:
$ mongos --configdb conServer/localhost:27020,localhost:27021,localhost:27022 --port 27040
至此路由已經搭建完成。
配置分片
配置分片服務器
通過mongodb提供的mongo進入到路由服務器中進行配置,把我們開始創建的三個分片服務器通過sh.addShard()
方法添加進行,這個方法接受一個字符串裏面的格式為host:port
。
$ mongo --port 27040 --host localhost
> sh.addShard(‘localhost:27030‘);
> sh.addShard(‘localhost:27031‘);
> sh.addShard(‘localhost:27032‘);
如果你可以通過rs.status()
方法中返回的shards
字段看是否添加成功。
配置片鍵
到目前為止,分片服務器已經搭建完成,但是目前分片服務器無法正常工作,我們所有的操作都將在隨機的一個主分片上操作,這是因為分片服務器不知道怎麽進行分片,所以我們還需要配置片鍵來告訴分片服務器按照什麽來分片。
分片是基於數據庫集合中的文檔的一個鍵進行分片的,比如選擇username鍵,那麽會根據這個鍵的順序就行分片,而mongodb會自動平衡分片的數據。
Mongodb要求作為片鍵的鍵必須是索引過的,所以我們在建立片鍵之前需要對鍵進行索引,建立後片鍵就是集合中的最重要的索引。
在生產環境中建議先想好數據建構建立索引和片鍵後開始操作數據,這樣會減輕分片服務器的負載。
首先我們在需要進行分片的數據庫上開啟分片功能,通過sh.enableSharding
方法開啟。
$ mongo --port 27040 --host localhost
> sh.enableSharding(‘test‘);
然後在開啟分片的數據庫中的test集合插入測試數據,註意此時我們還沒有進行配置片鍵,所以所有的數據操作都在分片服務器隨機分配的一個主分片上面進行的。
> for(var i = 0; i < 100; i++){
db.test.insert({
username: ‘user‘ + i,
idNum: i
})
}
這時候以username為片鍵,通過sh.shardCollection
方法進行建立,它的語法為:
sh.shardCollection(namespace, key, unique, options)
首先給我們要建立的片鍵建立索引:
> db.test.ensureIndex({‘username‘: 1});
然後建立片鍵:
> sh.shardCollection(‘test.test‘, {username:1});
等待幾分鐘後,可以通過sh.status
方法查看數據分片的情況了,可以從中很清楚的看見哪些數據在哪個分片服務器上面,並且通過explain
方法來查看我們查詢的過程中哪些分片服務器參與了查詢。
參考
MongoDB權威指南(第2版)
Mongodb Docs
Mongodb 分片