1.分片的原理概述
分片就是把數據分成塊,再把塊存儲到不同的服務器上,mongodb的分片是自動分片的,當用戶發送讀寫數據請求的時候,先經過mongos這個路由層,mongos路由層去配置服務器請求分片的信息,再來判斷這個請求應該去那一台服務器上讀寫數據。

2.分片的條件
1):服務器磁盤不夠的時候
2):服務器出現寫瓶頸的時候
3):想將大量數據放在內存中提高性能
3.分片中的角色,有三種:
1):配置服務器:存放分片信息,分片的數據與片的關系
2):mongos路由:是一個路由進程,把所有對mongodb的數據讀寫請求根據配置服務器的配置信息分配到不同的分片服務器上去。本身不存儲數據與配置信息,但會緩存配置信息,
3):片:指一個分片,這個分片可以是一台服務器,也可以是多台服務器組成的一個集群。對應的多台服務器中只能有一台主服務器
4.分片是以什么來分的
1)以數據庫來分,那就是把數據庫里的多個集合分到不同的分片上,同一個集合的數據只能在同一分片上
2)以某個集合中的某個鍵來分,這個鍵稱為片鍵,根據設置的片鍵把一個集合的數據分到不同的片上,這個分片鍵可以是多個鍵的組合鍵
5.實際的生產環境
在一個實際的生產環境中會同時存在多個配置服務器,多個mongos路由進程,多個分片,每一個分片會是一個副本集。
因為配置服務器與mongos路由進程占用的資源非常少,所以有些人會通過不同的端口,把他們配置到同一台服務器上,但是不要把多個配置服務器與多個mongos路由進程配置在同一台服務器,最好是一台服務器一個配置服務器,一個路由進程就夠,如果是多個在同一台服務器,當這個服務器掛掉了,那你的整個分片的架構可能就跟着掛了,不能提供服務了,下面給出一個參考的架構圖。

6.搭建分片服務器架構的流程
1):創建配置服務器的數據與日志目錄,並配置和啟動配置服務器,主要參數:mongod --configsvr ..............
2):創建mongos的日志目錄,因為mongos本身不存儲數據,所以不用數據目錄。接着配置和啟動mongos路由進程,啟動的時候是以mongos,來啟動的。主要參數:mongos --configdb 配置服務器的ip:端口 ............
3) : 創建分片副本集的數據與日志目錄,配置和啟動副本集,主要參數:mongod --shardsvr --replSet 副本集名 .........
4):對分片副本集進行初始化,設置仲裁節點,把初始化信息寫在config變量中,接着用rs.initiate(config)進行初始化
5):登錄mongos,把副本集增加到切片中,必須在admin數據中運行命令:db.runCommand({"addshard":"副本集名稱/ip:port,ip:port......","name":"分片名"})
6):打開數據庫和集合的分片功能db.runCommand({"enableSharding":"數據庫"}),db.runCommand({"shardcollection":"數據庫.集合名","key":{"鍵名":1}})
7.分片架構規划
1)規划:如果按以上的架構圖來搭建沒有這么多服務器,所以我們以三台服務器為例分別是:192.168.1.1,192.168.1.2,192.168.1.3
配置服務器的端口是:20000,mongos路由的端口是:20004,副本集1的端口是:20001,副本集2的端口是:20002,副本集3的端口是:20003
2):架構圖如下:

8.開始搭建分片
創建一個總目錄shard,之后創建的目錄都在這個文件夾中,假設現在正在mongodb的安裝目錄下,目錄名為mongodb,在根目錄下。
1):配置與啟動配置服務器
mkdir ./shard/config //配置服務器的目錄
mkdir ./shard/config/data //配置服務器的數據目錄
mkdir ./shard/config/log //配置服務器的日志目錄
//配置和啟動配置服務器
mongod --configsvr --dbpath="/mongodb/shard/config/data" --logpath="/mongodb/shard/config/log/config.log" --port 2000 --fork --logappend
把以上的步驟分別在三台服務器中執行一遍
2):配置和啟動mongos路由進程
mkdir ./shard/mongos //配置服務器的目錄
mkdir ./shard/mongos/log //配置服務器的日志目錄
配置和啟動mongos
mongos --configdb 192.168.1.1:20000,192.168.1.2:20000,192.168.1.3:20000 --logpath="/mongodb/shard/mongos/log/mongos.log" --port 2004 --fork --logappend
把以上的步驟分別在三台服務器中執行一遍
3):創建與啟動第一副本集,並加入到分片中
mkdir ./shard/replset/rs1/data
mkdir ./shard/replset/rs1/log
echo -n 'shard' | md5sum >> ./auth.txt(配置通信憑證文件)
配置和啟動副本集
mongod --shardsrv --replset rs1 --keyFile ./auth.txt --dbpath=./shard/replset/rs1/data --logpath=./shard/replset/rs1/log/rs1.log --fork --port 20001 --logappend
分別在三台服務器中執行以上命令
登錄其中的一台並配置副本集:mongo 192.168.1.1:2001
var config = {"_id":rs1,member:[{_id:1,host:192.168.1.1:20001},{_id:1,host:192.168.1.2:20001},{_id:1,host:192.168.1.3:20001,'arbiteOnly':true}]}
rs.initiate(config);
登錄其中一台mongos路由並把副本集加到分塊中:
mongo 192.168.1.1:20004
db.runCommand({"addshard":"rs1/192.168.1.1:20001,192.168.1.2:20001,192.168.1.3:20001"}); //增加副本集到分片中
db.runCommand({"enbaleSharding":test(數據庫名)});//啟動數據庫分片
db.runCommand({"shardCollection":test.user(集合名),key:{name(分塊鍵):1}});//按數據庫中的某個集合的某個健分片
4)重復第3個步驟創建rs2,rs3,但要修改相對應的地方,比如端口,和文件夾名稱,副本集名稱
5.查看分片的狀態:db.printShardingStatus();
db.runCommand({"listShards":1});
6.刪除分片:
db.runCommand({"removeshard":"ip:端口"});
刪除的分片上的數據會移到其他分片上,移完之后自動刪除分片.
