天天看点

mongodb分片集群技术

1、介绍

MongoDB几乎能自动完成所有事情,只要告诉MongoDB要分配数据,它就能自动维护数据在不同服务器之间的均衡。

mongodb分片集群技术

1.1 分片机制提供了如下三种优势

1.对集群进行抽象,让集群“不可见”

  MongoDB自带了一个叫做mongos的专有路由进程。mongos就是掌握统一路口的路由器,其会将客户端发来的请求准确无误的路由到集群中的一个或者一组服务器上,同时会把接收到的响应拼装起来发回到客户端。

2.保证集群总是可读写

  MongoDB通过多种途径来确保集群的可用性和可靠性。将MongoDB的分片和复制功能结合使用,在确保数据分片到多台服务器的同时,也确保了每分数据都有相应的备份,这样就可以确保有服务器换掉时,其他的从库可以立即接替坏掉的部分继续工作。

3.使集群易于扩展

当系统需要更多的空间和资源的时候,MongoDB使我们可以按需方便的扩充系统容量。

1.2 分片集群架构

mongodb分片集群技术
mongodb分片集群技术

分片集群的构造

(1)mongos :数据路由,和客户端打交道的模块。mongos本身没有任何数据,他也不知道该怎么处理这数据,去找config server

(2)config server:所有存、取数据的方式,所有shard节点的信息,分片功能的一些配置信息。可以理解为真实数据的元数据。

(3)shard:真正的数据存储位置,以chunk为单位存数据。

1.3 集群中数据分布

Chunk

  在一个shard server内部,MongoDB还是会把数据分为chunks,每个chunk代表这个shard server内部一部分数据。chunk的产生,会有以下两个用途:

  Splitting:当一个chunk的大小超过配置中的chunk size时,MongoDB的后台进程会把这个chunk切分成更小的chunk,从而避免chunk过大的情况

  Balancing:在MongoDB中,balancer是一个后台进程,负责chunk的迁移,从而均衡各个shard server的负载,系统初始1个chunk,chunk size默认值64M,生产库上选择适合业务的chunk size是最好的。MongoDB会自动拆分和迁移chunks。

分片集群的数据分布(shard节点)

(1)使用chunk来存储数据

(2)进群搭建完成之后,默认开启一个chunk,大小是64M,

(3)存储需求超过64M,chunk会进行分裂,如果单位时间存储需求很大,设置更大的chunk

(4)chunk会被自动均衡迁移。

chunksize的选择

  适合业务的chunksize是最好的。

  chunk的分裂和迁移非常消耗IO资源;chunk分裂的时机:在插入和更新,读数据不会分裂。

  chunksize的选择:

小的chunksize:数据均衡是迁移速度快,数据分布更均匀。数据分裂频繁,路由节点消耗更多资源。大的chunksize:数据分裂少。数据块移动集中消耗IO资源。通常100-200M。

chunk分裂及迁移

chunk 自动分裂只会在数据写入时触发

mongodb分片集群技术
mongodb分片集群技术

1.4 数据区分

分片键shard key

  MongoDB中数据的分片是、以集合为基本单位的,集合中的数据通过片键(Shard key)被分成多部分。其实片键就是在集合中选一个键,用该键的值作为数据拆分的依据。

为了按照片键划分数据块,MongoDB使用基于范围的分片方式或者 基于哈希的分片方式。

分片键是不可变。

分片键必须有索引。

分片键大小限制512bytes。

分片键用于路由查询。

MongoDB不接受已进行collection级分片的collection上插入无分片

键的文档(也不支持空值插入)

分片键选择建议

1、递增的sharding key

数据文件挪动小。(优势)

因为数据文件递增,所以会把insert的写IO永久放在最后一片上,造成最后一片的写热点。同时,随着最后一片的数据量增大,将不断的发生迁移至之前的片上。

2、随机的sharding key

数据分布均匀,insert的写IO均匀分布在多个片上。(优势)

大量的随机IO,磁盘不堪重荷。

3、混合型key

大方向随机递增,小范围随机分布。

为了防止出现大量的chunk均衡迁移,可能造成的IO压力。我们需要设置合理分片使用策略(片键的选择、分片算法(range、hash))

分片键是不可变、分片键必须有索引、分片键大小限制512bytes、分片键用于路由查询。

MongoDB不接受已进行collection级分片的collection上插入无分片键的文档(也不支持空值插入)

1.5 查询请求

查询请求不包含shard key,则必须将查询分发到所有的shard,然后合并查询结果返回给客户端

查询请求包含shard key,则直接根据shard key计算出需要查询的chunk,向对应的shard发送查询请求

写请求

写操作必须包含shard key,mongos根据shard key算出文档应该存储到哪个chunk,然后将写请求发送到chunk所在的shard。

更新/删除请求

更新、删除请求的查询条件必须包含shard key或者_id,如果是包含shard key,则直接路由到指定的chunk,如果只包含_id,则需将请求发送至所有的shard。

2、配置节点Config Server介绍

Config server存储Sharded cluster的所有元数据,所有的元数据都存储在config数据库

Config Server可部署为一个独立的复制集,极大的方便了Sharded cluster的运维管理。

config.shards

config.shards集合存储各个Shard的信息,可通过addShard、removeShard命令来动态的从Sharded cluster里增加或移除shard

config.databases

config.databases集合存储所有数据库的信息,包括DB是否开启分片,primary shard信息,对于数据库内没有开启分片的集合,所有的数据都会存储在数据库的primary shard上。

config.colletions

数据分片是针对集合维度的,某个数据库开启分片功能后,如果需要让其中的集合分片存储,则需调用shardCollection命令来针对集合开启分片。

config.chunks

集合分片开启后,默认会创建一个新的chunk,shard key取值[minKey, maxKey]内的文档(即所有的文档)都会存储到这个chunk。当使用Hash分片策略时,也可以预先创建多个chunk,以减少chunk的迁移。

config.settings

config.settings集合里主要存储sharded cluster的配置信息,比如chunk size,是否开启balancer等

其他集合

config.tags主要存储sharding cluster标签(tag)相关的信息

config.changelog主要存储sharding cluster里的所有变更操作,比如balancer迁移chunk的动作就会记录到changelog里

config.mongos存储当前集群所有mongos的信息

config.locks存储锁相关的信息,对某个集合进行操作时,比如moveChunk,需要先获取锁,避免多个mongos同时迁移同一个集合的chunk。chunk默认大小为64M

修改配置服务器:修改配置服务器非常困难,而且有风险,通常还需要停机。注意,修改配置服务器前,应做好备份。 首先必须关闭所有mongos进程,然后使用新的–configdb参数重启所有mongos进程。

3、负载均衡

MongoDB Sharding的自动负载均衡目前是由mongos的后台线程来做的,并且每个集合同一时刻只能有一个迁移任务,负载均衡主要根据集合在各个 shard上chunk的数量来决定的,相差超过一定阈值(跟chunk总数量相关)就会触发chunk迁移。采用Balancer实现

平衡器Balancer

Balancer默认是开启的,为了避免chunk迁移影响到线上业务,可以通过设置迁移执行窗口,比如只允许凌晨2:00-6:00期间进行迁移。

mongo --port=27019 --连接到mongos

use config

db.settings.update(

{ _id: “balancer” },

{ $set: { activeWindow : { start : “02:00”, stop : “06:00” } } },

{ upsert: true }

)

另外,在进行sharding备份时(通过mongos或者单独备份config server和所有shard),需要停止负载均衡以免备份出来的数据出现状态不一致问题。

sh.setBalancerState(“false”)

或者:

sh.stopBalancer()

均衡器:均衡器只使用块的数量,而非数据大小,作为衡量分片间是否均衡的指标。

mongodb分片集群技术

_secondaryThrottle值决定何时继续迁移下一个文件

如果将平衡器的_secondaryThrottle设置设置为写入问题,则在继续执行下一个文档之前,在块迁移期间移动的每个文档都必须接收所请求的确认。

如果平衡器的_secondaryThrottle设置设置为true,则在块迁移期间移动的每个文档必须在迁移继续进行块中的下一个文档之前从至少一个辅助节点接收确认。这相当于\ {w:2 }的写入问题。

如果未设置_secondaryThrottle设置,则迁移 process 不会等待复制到辅助节点,而是继续下一个文档。

更改_secondaryThrottle设置

use config db.settings.update( { “_id” : “balancer” }, { $set : { “_secondaryThrottle” : { “w”: “majority” } } }, { upsert : true } )

更改_secondaryThrottle设置的效果可能不会立即生效。要确保立即生效,请停止并重新启动平衡器以启用_secondaryThrottle的所选 value。

等待删除

平衡器的_waitForDelete设置和moveChunk命令会影响平衡器如何从分片迁移多个块。默认情况下,在开始下一个块迁移之前,平衡器不会等待 on-going 迁移的删除阶段完成。要使删除阶段阻止下一个块迁移的开始,可以将_waitForDelete设置为 true。

use config db.settings.update( { “_id” : “balancer” }, { $set : { “_waitForDelete” : true } }, { upsert : true } )

4、分片备份、还原

因为分片机制里面会有平衡器来迁移数据,所以各个分片里的数据很可能会移动,所以在备份分片时需要做:

①:先停止平衡器的工作,并检查没有chunk move动作,保证dump的时候没有进行数据迁移。

mongos> sh.stopBalancer()

②:锁定数据库,保证数据没有写入:在各个分片上和配置服务器上执行。

db.fsyncLock()

{

“info” : “now locked against writes, use db.fsyncUnlock() to unlock”,

“seeAlso” : “http://dochub.mongodb.org/core/fsynccommand”,

“ok” : 1

}

③:执行备份操作,备份各个分片服务器和配置服务器。

mongodump -udba -p12345 -d dba_test --authenticationDatabase admin -o backup/

④:解锁数据库,备份完成之后在分片和配置服务器上解锁数据库,允许修改。

db.fsyncUnlock()

{ “ok” : 1, “info” : “unlock completed” }

当数据库出现问题,需要还原的时候,需要还原各个分片和配置服务器,并且重启MongoDB实例。还原数据库需要做:

①:还原各个分片和配置服务器。

mongorestore --host=127.0.0.1 --port=27017 -udba -p12345 -d dba_test --authenticationDatabase admin --drop backup/dba_test

②:重启各个实例

mongos无法开启慢日志!!!也操作不了local库

mongodb分片集群技术