MongoDB 基础(九)分片

来源:互联网 发布:linux的vi命令 编辑:程序博客网 时间:2024/06/06 12:46


分片(sharding)是通过多台服务器存储数据的方法。Mongodb使用分片可支持部署非常大的数据集和高的吞吐量操作。单台服务器的能力在各方面都有限,如CPU、IO、RAM、存储空间等。解决扩展的问题,数据库提供了两种方法:垂直扩展和分片。


垂直扩展:增加CPU、RAM,存储资源等,这也受限于硬件设备。而有些基于云的供应商也规定用户使用小的系统。


分片(水平扩展):划分数据集,将数据分布到多台服务器中,每个碎片(chard)是一个独立的数据库,这些碎片共同组成了一个逻辑的数据库。(这类似于Windows动态磁盘条带化一样)


Mongodb 中的分片集群结构如下:


分片集群有三个组件:shards,query routers 和 configservers。

 

Shards:碎片,存储数据,提供高可用性和数据的一致性。分片集群中,每个碎片都是一个复制集。

 

query routers查询路由,或称mongos实例,客户端应用程序直接操作碎片的接口。查询路由处理和定位操作到碎片中并返回相关数据到客户端。一个分片集群包含多个查询路由来划分客户端的请求压力。

 

configservers:配置服务器,存储集群中的元数据。这些数据包含集群数据到碎片的映射。查询路由使用这些元数据定位操作到明确的碎片中。共享集群需要有3台配置服务器。


注:用于测试,可以值配置1个config servers


Mongodb 分布数据或碎片,是在collection 级别上。分片是通过shardkey 划分一个集合的数据。shard key 可以是一个索引键列,或者是存在每个文档中的复合键列。Mongodb 划分shard key 值到 chunk 中,并将chunk平均分配到碎片中。Mongodb 使用划分的方法为范围分区或者哈希分区。(更多参考:shardkey)


分片集群部署:

Mongodb服务器:(Red HatEnterprise Linux 6 64-bit + Mongodb 3.0.2)

192.168.1.11    mongodb11.kk.net  21017

192.168.1.12    mongodb12.kk.net  21018

192.168.1.13    mongodb13.kk.net  21019

192.168.1.14    mongodb14.kk.net  21020


用于测试结构如下:


注:配置前确保要加入集群中的成员都能相互连接。



【1. 配置 config servers】(在 192.168.1.14服务器上)

配置服务器(config servers)存储集群元数据,因此首先配置该服务器。配置服务器需使用参数—configsvr 来启动mongod服务。若有多个配置服务器,每个配置服务器都完整保存集群的元素就。

1. 1 创建数据库目录 configdb :

[root@mongodb14 ~]# mkdir /var/lib/mongo/configdb[root@mongodb14 ~]# chown mongod:mongod /var/lib/mongo/configdb/

1.2.  配置启动参数文件:

[root@mongodb14 ~]# vi /etc/mongod.conf

192.168.1.14

logpath=/var/log/mongodb/mongod.log

pidfilepath=/var/run/mongodb/mongod.pid

logappend=true

fork=true

port=27020

bind_ip=192.168.1.14

dbpath=/var/lib/mongo/configdb

configsvr=true


1.3.  重启 mongod 服务:

[root@mongodb14 ~]# service mongod restart


【2. 配置 router】(在 192.168.1.11服务器上)

2.1.启用 mongos (MongoDB Shard)实例,连接到 config servers:(更多参考:mongos 

#使用mongos连接到config servers,指定本地端口,否则默认27017#当前服务器mongod 端口为27017,所以配置mongos 端口为27016#mongo --host <hostname of machine running mongos> --port <port mongos listens on>[root@redhat11 ~]# mongos --configdb mongodb14.kk.net:27020 --port 27016 --chunkSize 200 --logpath /var/log/mongodb/mongos.log --fork

实际环境中,若配置了多个config servers ,mongos 可同时指定多个。

mongos--configdb mongodb14.kk.net:27020, mongodb15.kk.net:27020,mongodb16.kk.net:27020……


【3. 添加 shard 成员到集群中】(添加IP为 11、12、13 分片集中 ,以192.168.1.11为例)

3.1. 配置启动参数文件:

[root@redhat11 ~]# vi /etc/mongod.conf

192.168.1.11

192.168.1.12

192.168.1.13

logpath=/var/log/mongodb/mongod.log

pidfilepath=/var/run/mongodb/mongod.pid

logappend=true

fork=true

port=27017

bind_ip=192.168.1.11

dbpath=/var/lib/mongo

shardsvr=true

 

logpath=/var/log/mongodb/mongod.log

pidfilepath=/var/run/mongodb/mongod.pid

logappend=true

fork=true

port=27018

bind_ip=192.168.1.12

dbpath=/var/lib/mongo

shardsvr=true

 

logpath=/var/log/mongodb/mongod.log

pidfilepath=/var/run/mongodb/mongod.pid

logappend=true

fork=true

port=27019

bind_ip=192.168.1.13

dbpath=/var/lib/mongo

shardsvr=true

 


3.2.重启 mongod 服务:

[root@mongodb11 ~]# service mongod restart

3.3各shard 成员连接到mongos 实例中添加(添加前把已存在的用户数据移走或者删除):

[root@mongodb11 ~]# mongo 192.168.1.11:27016mongos> sh.addShard("mongodb11.kk.net:27017")mongos> sh.addShard("mongodb12.kk.net:27018")mongos> sh.addShard("mongodb13.kk.net:27019")

3.4添加完成!~连接到mongos可查看系统相关信息:

configsvr> show dbsconfigsvr> use configconfigsvr> show collectionsconfigsvr> configsvr> db.mongos.find(){ "_id" : "mongodb11.kk.net:27016", "ping" : ISODate("2015-05-23T11:16:47.624Z"), "up" : 1221, "waiting" : true, "mongoVersion" : "3.0.2" }configsvr> configsvr> db.shards.find(){ "_id" : "shard0000", "host" : "mongodb11.kk.net:27017" }{ "_id" : "shard0001", "host" : "mongodb12.kk.net:27018" }{ "_id" : "shard0002", "host" : "mongodb13.kk.net:27019" }configsvr> configsvr> db.databases.find(){ "_id" : "admin", "partitioned" : false, "primary" : "config" }{ "_id" : "mydb", "partitioned" : false, "primary" : "shard0000" }{ "_id" : "test", "partitioned" : false, "primary" : "shard0000" }


【4. 对数据库启用分片】

4.1 当前可连接到 mongos 查看数据库或者集合的分片情况(没有分片):

mongos> db.stats()mongos> db.tab.stats()

4.2 对数据库激活分片功能:

[root@mongodb11 ~]# mongo 192.168.1.11:27016mongos> sh.enableSharding("test")#或者[root@mongodb11 ~]# mongo 192.168.1.11:27016mongos> use adminmongos> db.runCommand( { enableSharding: "test"} )

4.3 此时查看数据库分区情况,partitioned 变为 “true”。

configsvr> use configswitched to db configconfigsvr> db.databases.find(){ "_id" : "admin", "partitioned" : false, "primary" : "config" }{ "_id" : "mydb", "partitioned" : true, "primary" : "shard0000" }{ "_id" : "test", "partitioned" : true, "primary" : "shard0000" }


启用数据库分片并没有将数据进行分开,还需要对 collection 进行分片。

【5. 对集合启用分片】

启用前,有几个问题需要考虑的:

1. 选择哪个键列作为 shard key  。(更多参考: Considerations for Selecting Shard Keys)

2. 如果集合中已经存在数据,在选定作为shard key 的键列必须创建索引;如果集合为空,mongodb 将在激活集合分片(sh.shardCollection)时创建索引。

3. 集合分片函数 sh.shardCollection ,


sh.shardCollection("<database>.<collection>", shard-key-pattern)


mongos> sh.shardCollection("test.tab", { "_id": "hashed" })


测试:

for (var i=1; i<100000; i++) {db.kk.insert({"id": i, "myName" : "kk"+i, "myDate" : new Date()});}mongos> show collectionsmongos> db.kk.find()mongos> db.kk.createIndex({ "id": "hashed" })mongos> db.kk.getIndexes()mongos> sh.shardCollection("test.kk", { "id": "hashed" })mongos> db.stats()mongos> db.kk.stats()


由于数据分区需要时间,过会再查看数据分布情况:

 总行数:99999

mongos> db.kk.count()99999

mongos> db.printShardingStatus();--- Sharding Status ---   sharding version: {"_id" : 1,"minCompatibleVersion" : 5,"currentVersion" : 6,"clusterId" : ObjectId("556023c02c2ebfdfbc8d39eb")}  shards:{  "_id" : "shard0000",  "host" : "mongodb11.kk.net:27017" }{  "_id" : "shard0001",  "host" : "mongodb12.kk.net:27018" }{  "_id" : "shard0002",  "host" : "mongodb13.kk.net:27019" }  balancer:Currently enabled:  yesCurrently running:  noFailed balancer rounds in last 5 attempts:  0Migration Results for the last 24 hours: 1334 : Success2 : Failed with error 'could not acquire collection lock for test.kk to migrate chunk [{ : MinKey },{ : MaxKey }) :: caused by :: Lock for migrating chunk [{ : MinKey }, { : MaxKey }) in test.kk is taken.', from shard0000 to shard0001  databases:{  "_id" : "admin",  "partitioned" : false,  "primary" : "config" }{  "_id" : "mydb",  "partitioned" : true,  "primary" : "shard0000" }{  "_id" : "test",  "partitioned" : true,  "primary" : "shard0000" }test.kkshard key: { "id" : "hashed" }chunks:shard0000667shard0001667shard0002667too many chunks to print, use verbose if you want to force print{  "_id" : "events",  "partitioned" : false,  "primary" : "shard0002" }mongos> 


看这里 chunks :
shard0000 667
shard0001 667
shard0002 667

原本 shard0000 最大,shard0001 与 shard0002 为 0 。最终平均,数据将稳定不再变化。

mongos> db.kk.stats(){"sharded" : true,"paddingFactorNote" : "paddingFactor is unused and unmaintained in 3.0. It remains hard coded to 1.0 for compatibility only.","userFlags" : 1,"capped" : false,"ns" : "test.kk","count" : 99999,"numExtents" : 19,"size" : 11199888,"storageSize" : 44871680,"totalIndexSize" : 10416224,"indexSizes" : {"_id_" : 4750256,"id_hashed" : 5665968},"avgObjSize" : 112,"nindexes" : 2,"nchunks" : 2001,"shards" : {"shard0000" : {"ns" : "test.kk","count" : 33500,"size" : 3752000,"avgObjSize" : 112,"numExtents" : 7,"storageSize" : 22507520,"lastExtentSize" : 11325440,"paddingFactor" : 1,"paddingFactorNote" : "paddingFactor is unused and unmaintained in 3.0. It remains hard coded to 1.0 for compatibility only.","userFlags" : 1,"capped" : false,"nindexes" : 2,"totalIndexSize" : 3605616,"indexSizes" : {"_id_" : 1913184,"id_hashed" : 1692432},"ok" : 1},"shard0001" : {"ns" : "test.kk","count" : 32852,"size" : 3679424,"avgObjSize" : 112,"numExtents" : 6,"storageSize" : 11182080,"lastExtentSize" : 8388608,"paddingFactor" : 1,"paddingFactorNote" : "paddingFactor is unused and unmaintained in 3.0. It remains hard coded to 1.0 for compatibility only.","userFlags" : 1,"capped" : false,"nindexes" : 2,"totalIndexSize" : 3343984,"indexSizes" : {"_id_" : 1389920,"id_hashed" : 1954064},"ok" : 1},"shard0002" : {"ns" : "test.kk","count" : 33647,"size" : 3768464,"avgObjSize" : 112,"numExtents" : 6,"storageSize" : 11182080,"lastExtentSize" : 8388608,"paddingFactor" : 1,"paddingFactorNote" : "paddingFactor is unused and unmaintained in 3.0. It remains hard coded to 1.0 for compatibility only.","userFlags" : 1,"capped" : false,"nindexes" : 2,"totalIndexSize" : 3466624,"indexSizes" : {"_id_" : 1447152,"id_hashed" : 2019472},"ok" : 1}},"ok" : 1}mongos> 


上面中,个分片数据分布情况:

"shard0000"  "count" : 33500

"shard0001"  "count" : 32852

"shard0002"  "count" : 33647


总计99999 行,完全准确,数据分布也很平均了。

(测试数据尽量多些,否则看不得效果。一开始本人测试数据较少,不到1000行,没有效果,还以为哪里出现问题,又多折腾了2小时!~)



参考: Sharding Introduction

(官方文档的步骤不是很清楚,倒腾了好久。网上也有些博客介绍,也只是博主的总结,对于一个新人来讲,在哪操作,操作什么不详细)




1 0