mongodb 分片:
分片:sharding,是指将数据拆分,将其分散存在不同的机器上的过程,又是也用分区的概念。
# 是不是与分布式非常类似
mongodb分片支持自动分片,将集合切分成小块,这些块分散到若干片里面,每个片只负责总数居的一部分,程序不必知道哪片对应哪些数据,甚至不需要知道数据已经被拆分,所以分片之前要运行一个路由进程,进程名为mongos,
#为什么使用分片
复制所有的写入操作到主节点
延迟的敏感数据会在主节点查询
单个副本集限制在12个节点
当请求量巨大时会出现内存不足
本地磁盘不足,
垂直扩展,性价比不高
分片与复制的区别:
复制是将数据集做副本,一模一样,分片是将一个数据集切分成多个片,存储在多个节点上。
Sharding组件:
Shard:用于存储实际的数据块,实际生成环境中一个shard server角色可由几台机器组个一个replica set承担,防止主机单点故障。
Config Server:mongod实例,存储整个ClusterMetadata,其中包括chunk信息
Query Routers:前段路由,客户端由此接入,且让整个集群看上去像单一数据库,前段应用可以透明使用。
sharding最最最关键的是sharding key(片键)
片键的选择决定了插入操作在片之间的分布
mongo分片架构中的角色:
mongos:Router process,询问config server需要到哪个shard上查询或保存记录,
config server:元数据服务器,存储所有shard节点的配置信息,每个chunk的shard key范围,chunk在各shard的分布情况,该集群中所有db和collection的sharding配置信息
shard:数据节点,mongod节点,实际存储数据的分片,为了实现每个shard内部的auto-failover,mongodb每个shard为一组replicaSet
切片:
基于范围切片:range
基于列表切片:list
基于hash切片:hash
切片原则:写离散,读集中
sharding 实验:
将用户姓名,年龄等信息做为数据存储到mongodb的sharding集群,
sharding key以age与name,为基础进行chunk分片。
192.168.1.154 node1 路由 启动 mongos
192.168.3.6 node2 配置 启动 mongod
192.168.2.33 node3 分片节点 启动 mongod
192.168.2.147 node4 分片节点 启动 mongod
# config server
vi /etc/mongod.conf
dbpath=/data/mongodb
configsvr=true
service mongod start
# mongos
mongos --configdb 192.168.3.6 # 会占用当前shell
# 分片(每一个分片节点应该是以replSet存在,保证高可用)
vi /etc/mongod.conf
dbpath=/data/mongodb
service mongod start
# sharding是针对数据库的集合来设置的
mongos上设置
sh.addShard("192.168.2.33") # mongos添加分片节点
sh.addShard("192.168.2.147")
# 默认情况下,任何数据库都不会被分片
# 添加需要分片的数据库
sh.enableSharing(testdb)
# 设置该数据库下分片集合,已经sharding key(以哪些键做为分片基准)
sh.shardCollection("testdb.testcoll",{age:1,name:1}) # 以age与name的组合键作为sharding key
sh.status()
# 插入海量数据
for(i=1;i<=100000;i++) db.testcoll.insert({name:"user"+i,age:i,address:"#"+i+"tianzhong,shenzhen,china",prefrebooks:["book"+i,"helloworld"]})
# 查看分片效果
mongos> sh.status()
--- Sharding Status ---
sharding version: {
"_id" : 1,
"version" : 4,
"minCompatibleVersion" : 4,
"currentVersion" : 5,
"clusterId" : ObjectId("5926f793306532d728e6c173")
}
shards: # 分片节点
{ "_id" : "shard0000", "host" : "192.168.2.33:27017" }
{ "_id" : "shard0001", "host" : "192.168.2.147:27017" }
databases: # 数据库
{ "_id" : "admin", "partitioned" : false, "primary" : "config" }
{ "_id" : "testdb", "partitioned" : true, "primary" : "shard0001" } # testdb 分区,主shard节点为shard0001
testdb.testcoll
shard key: { "age" : 1, "name" : 1 }
chunks:
shard0001 7 # 分片节点的chunk数目
shard0000 6
{ "age" : { "$minKey" : 1 }, "name" : { "$minKey" : 1 } } -->> { "age" : 1, "name" : "user1" } on : shard0001 Timestamp(5, 0)
{ "age" : 1, "name" : "user1" } -->> { "age" : 58, "name" : "user26758" } on : shard0001 Timestamp(6, 0)
{ "age" : 58, "name" : "user26758" } -->> { "age" : 149, "name" : "user899" } on : shard0001 Timestamp(4, 1)
{ "age" : 149, "name" : "user899" } -->> { "age" : 79778, "name" : "user79778" } on : shard0001 Timestamp(3, 2)
{ "age" : 79778, "name" : "user79778" } -->> { "age" : 158106, "name" : "user158106" } on : shard0001 Timestamp(3, 4)
{ "age" : 158106, "name" : "user158106" } -->> { "age" : 236043, "name" : "user236043" } on : shard0000 Timestamp(7, 1)
{ "age" : 236043, "name" : "user236043" } -->> { "age" : 313980, "name" : "user313980" } on : shard0000 Timestamp(4, 4)
{ "age" : 313980, "name" : "user313980" } -->> { "age" : 392779, "name" : "user392779" } on : shard0000 Timestamp(5, 2)
{ "age" : 392779, "name" : "user392779" } -->> { "age" : 470716, "name" : "user470716" } on : shard0000 Timestamp(5, 4)
{ "age" : 470716, "name" : "user470716" } -->> { "age" : 627687, "name" : "user627687" } on : shard0000 Timestamp(6, 2)
{ "age" : 627687, "name" : "user627687" } -->> { "age" : 783556, "name" : "user783556" } on : shard0000 Timestamp(6, 4)
{ "age" : 783556, "name" : "user783556" } -->> { "age" : 939425, "name" : "user939425" } on : shard0001 Timestamp(7, 2)
{ "age" : 939425, "name" : "user939425" } -->> { "age" : { "$maxKey" : 1 }, "name" : { "$maxKey" : 1 } } on : shard0001 Timestamp(7, 3)
{ "_id" : "test", "partitioned" : false, "primary" : "shard0001" }
# 以上可以看到分片节点chunk内部存储实际数据的范围,此时数据还没有完全插入完成
# 检查shard状态
mongos> db.testcoll.stats()
{
"sharded" : true,
"systemFlags" : 1,
"userFlags" : 1,
"ns" : "testdb.testcoll",
"count" : 4726810,
"numExtents" : 33,
"size" : 1134434400,
"storageSize" : 1487077376,
"totalIndexSize" : 353497536,
"indexSizes" : {
"_id_" : 153398112,
"age_1_name_1" : 200099424
},
"avgObjSize" : 240,
"nindexes" : 2,
"nchunks" : 28,
"shards" : {
"shard0000" : {
"ns" : "testdb.testcoll",
"count" : 2769114, # shard0000 count
"size" : 664587360,
"avgObjSize" : 240,
"storageSize" : 857440256,
"numExtents" : 17,
"nindexes" : 2,
"lastExtentSize" : 227803136,
"paddingFactor" : 1,
"systemFlags" : 1,
"userFlags" : 1,
"totalIndexSize" : 207130784,
"indexSizes" : {
"_id_" : 89870592,
"age_1_name_1" : 117260192
},
"ok" : 1
},
"shard0001" : {
"ns" : "testdb.testcoll",
"count" : 1957696,
"size" : 469847040,
"avgObjSize" : 240,
"storageSize" : 629637120,
"numExtents" : 16,
"nindexes" : 2,
"lastExtentSize" : 168742912,
"paddingFactor" : 1,
"systemFlags" : 1,
"userFlags" : 1,
"totalIndexSize" : 146366752,
"indexSizes" : {
"_id_" : 63527520,
"age_1_name_1" : 82839232
},
"ok" : 1
}
},
"ok" : 1
}
# 新增shard Server
# 新增一个shard分片节点,
# mongos添加新的shard分片节点
sh.addShard("192.168.2.X")
sh.status() #检查
# 移除shard节点,需要特别注意,会进行数据转移到剩余节点,剩余节点的数据容量是否可承载。
sh.removeShardTag("192.168.2.X)
replica Sets + Sharding
Shard:每shard节点做replica Sets
Config:3组配置服务器,确保元数据完整性
Route:3组路由实例,实现负载平衡
网友评论