Mongodb 笔记 —- Sharding

Mongodb 笔记 —- Sharding

5 6 月, 2019 阅读 586 字数 5672 评论 0 喜欢 0

定义:将数据拆分并存储到不同机器上。

优点:

  1. 常用数据放到更强的硬件上,增强读性能。
  2. 按地域分区数据,增快区域性的读写。
  3. 单纯增强读写的性能。
架构图:

Mongos

客户端与mongos连接,作为集群前台响应客户端请求。mongos可以拉取/修改config server中存放的元数据。

mongos本身不存放元数据,只在启动时拉取到mongos内存中。

当config server不可用时,monogs即无法修改元数据。但仍有可能继续正常工作一段时间。

当客户端需要从多个shard读取数据时, mongos负责收集从所有shard数据,再返回给客户端。

初始化mongos
为mongos配置config servers:

mongos –configdb configRS/cfg1.example.net:27019,cfg2.example.net:27019,cfg3.example.net:27019 \–bind_ip localhost,198.51.100.100 –logpath /var/log/mongos.log

通过mongos为shard集群配置添加shard servers:

sh.addShard(“rs0/svr1.example.net:27017,svr2.example.net:27017,svr3.example.net:27017” )

手动强制使mongos和config server同步:

db.adminCommand({“flushRouterConfig” : 1})

运行mongos的数量:
  • 一般,我们在一个application server上运行一个mongos。
  • mongos不是越多越好,mongos会与集群中所有节点建立通讯连接通道,增加了网络开销。

Config servers

Config servers实质为一个专门用来存放sharding集群元数据的replica set或者standalone-server。

  • 必须使用WT engine
  • 为了保证数据不丢失需要在config server上开启journal功能。
  • 生产环境最好使用replica set(最少3个节点)的形式来组建config server。
  • 写入Config server使用Write concern majority来保证数据在一定数量的主从节点之间的一致。当宕机发生时,至少有一台机器拥有最新的数据。
  • 读取Config server使用read concern majority 来保证读取的数据在一定数量的主从节点之间的一致
  • 1KB元数据大约相当于20MB存储在shard server上的数据。因为config server不是很消耗资源,一定情况下可以考虑放到弱性能服务器上。

config server中的数据库

admin 数据库存有权限相关的collection数据

other system.* collections for internal use

config 数据库存有 sharded cluster 的元数据

配置启动config server
启动mongd时,使用–configsvr即指定为config server

mongod –configsvr –replSet configRS –bind_ip localhost,198.51.100.51

初始化config server的replica set,也需要使用configsvr参数:

rs.initiate(  {   

_id: “configRS”,   

configsvr: true,   

members: [     

{ _id : 0, host : “cfg1.example.net:27019” },     

{ _id : 1, host : “cfg2.example.net:27019” },   

 { _id : 2, host : “cfg3.example.net:27019” }    ]  })

Shard Servers:

正真存放数据的replica set。

配置启动shard server

启动mongd时,使用–shardsvr 即指定为shard server

mongod –replSet “rs0” –shardsvr –port 27017 –bind_ip localhost,<ip address of member>

移除shard: 

移除时数据会从这个shard 迁移到其他shard上去(意味着消耗很多时间,和硬件资源) 移除shard的时候一定要确保balancer是开启的!

db.adminCommand({“removeShard” : “shard03”})  –(remove开始后,如果再次运行这个命令,可以查看remove的进程)

如果该SHARD是某个数据库的primary shard的话需要移除primary shard

 db.adminCommand({“movePrimary” : “video”, “to” : “shard01”})

Primary Shard

一个shard是一个replica set。对于一个数据库,用来存放没有sharding 的collection的replica set,就是primary shard。

启动sharding:

对于某个数据库启用sharding:

sh.enableSharding(“accounts”)

对于shard key创建索引(必须)

db.users.createIndex({“username” : 1})

注意:
1.对于数据已经存在的collection, 没有对应索引, shardCollection 会报错
2.对于不存在的collection, shardcollection会自动创建对应的索引
Shard collection:

sh.shardCollection(“accounts.users”, {“username” : 1})

查看sharding集群的状态:

sh.status()

targeted queries:需要访问单个或多个shard但不是全部shard的query
scatter-gather queries: 需要访问所有shard的query

只访问单个shard的查询,执行计划显示为: “stage” : “SINGLE_SHARD”。两个以上则为” stage”:”SHARD_MERGE”

Chunks:

在sharding中,chunks是存放相同或一定范围sharding key值的数据的单元。

在非sharding的collection中,数据存放就是一个single chunk。

chunk不是物理上硬盘上的区别,而逻辑是的区别。所以split chunk实质上也只是元数据上的改变。

一个新的shard collection从一个single chunk 开始。

config server上存放chunk相关元数据信息的collection: config.chunks
在手动处理chunk或者控制sharding之前:我们需要关闭balancer
查看chunk:

db.chunks.find() //查看集群上所有chunk

sh.status(true) //查看 集群上所有chunk

sh.splitFind( “records.people”, { “zipcode”: “63109” } ) //查询特定shard key值的结果在哪个chunk 上

手动移动chunk:

sh.moveChunk(“video.movies”, {imdbId: 500000}, “shard02”) 

移动的时存有 imdbId: 500000 的chunk这里并不是表示范围或者取值。 使用shard key值的范围下界来表示chunk。

如果被移动的chunk容量大于现有的max chunk szie 移动会被拒绝。需要手动切割chunk(也有不能被切割的chunk, Jumbo chunks)。或者,调整max chunk size来chunk可以被移动。

手动切割chunk:

sh.splitAt(“video.movies”, {“imdbId”: NumberLong(“7000000000000000000”)})

调整max chunk size:

db.settings.findOne() 查看大小

db.settings.save({“_id” : “chunksize”, “value” : 32})

1. 缩小size,现有chunk不会马上修改大小,只有在insert,update发生时才对应的chunk才会修改。
2. 增加chunk size时,即使有”写操作”发生。chunk不会合并。只会在现有基础上追加数据。
合并chunk :

db.adminCommand( {

mergeChunks: “test.members”,

bounds: [

{ “username” : “user69816” }, //下届

{ “username” : “user96401” } //上届

] } )

Jumbo chunks:

不可移动不可切割且超过了max chunk size的chunk。

为什么会有jumbo chunks:

比如: 按日期建立的shard,一天作为一个chunk。当有一天数据量很大,chunk存放的数据超过了max chunk size的时候。

当一个shard增长的比其他shard都快的很多的时候,很可能就有jumbo chunks了。因为大多数的数据往一个shard写,该shard的chunks不断split,最终肯定会达到无法分割的状态。

查看 jumbo chunks:

sh.status()里对于jumbo chunks也会有标记。

处理方法:

  • 先关闭balancer,
  • 手动设置max chunk size最大的大小为jumbo chunk可以被移动,
  • 移动jumbo chunk到合适的shard上,
  • 手动切割集群的其他chunks,让chunk数量在节点上均匀。(防止balancer启动后发现chunk不平衡,开始疯狂移动集群中的chunks)
  • 调整回原来max chunk size设定。
  • 最后启动balancer

避免方法:

原理:增加shard key的粒度,这样数据在保存的时候就被细分到更小的chunk上。

  1. 比如日期,增加粒度到,小时/分钟/秒
  2. 组合键,使用其他更细粒度得值来做第二位shard key。使数据在第二位KEY上不断增加的同时依然能够被split。

mongos 对于chunks的控制

一、Balancer:

任何一个mongos都有机会/可能充当balancer的角色。balancer通过每个shard server上chunks的数量(不是数据容量)来判断chunks分布是否均匀。如果balancer发现 chunks 在shards上存储的不平衡,那么就会尝试迁移chunks使数据分布“均匀”。

技巧1:balancing window, 在特定的时候启动balancer来平衡数据,可以避免自动平衡带来的服务器性能影响

balancer相关元数据存放在config.locks collection中
查看哪一个mongos是balancer: 0 失效,1 尝试成为balancer,2工作中

db.locks.findOne({“_id” : “balancer”})

关闭/开启balancer:

sh.setBalancerState(false)  –false为关

sh.stopBalancer(): //如果有正在进行的migration,会等到结束再停止balancer

注意:
关闭balancer的目的往往是由需求人为控制sharding的分布
查看balancer是否在运行处理:

sh.isBalancerRunning()

或

db.locks.find({“_id” : “balancer”})[“state”]

技巧:可以在业务重的时候关闭balancer,然后在业务少的窗口期开始balancer来达到期间相对平衡的数据分布。

二、自动切割chunks:

mongos启动后会有counter来记录具体shard key值对应的chunk是否需要被split,达到阈值就会通知config server要split chunks.

注意:

  1. 当config server 宕机的话,mongos任然会持续连接/尝试让config server split,会对mongos服务器造成压力。
  2. mongos检测到有需要split而Config server不可用时,会疯狂尝试通知config server的行为,叫做 split storm
  3. mongos一旦重启,counter就会被清0。如果被频繁重启的话,可能造成chunks永远无法被mongos检测到需要被split。(这时候,你可能需要考虑设置比较小的max chunks size,让系统自动因为size问题,split chunks,增加被切割的频率/可能性。)
–nosplit 启动参数 : 控制mongos,不自动做split。

三、Chunk Migration:

  1. Migrates indexes. If this shard has never held chunks from the migrated collection before, it needs to know what fields are indexed.
  2. Deletes any existing data in the chunk range. There might be data left over from a failed migration or restore procedure which we wouldn’t want to interfere with the current data.
  3. Copies all documents
  4. Replays any operations that happened to these document during the copy (on the “to” shard)
  5. migrated data to a majority of servers
  6. changing the chunk’s metadata to say that it lives on the “to” shardconfig.tags

发表回复

蜀ICP备15005542号