• 主页

  • 投资

  • IT

    🔥
  • 设计

  • 销售

关闭

返回栏目

关闭

返回MongoDB栏目

28 - 高可用 - Sharding - 分片集群

作者:

贺及楼

成为作者

更新日期:2024-07-13 16:14:22

高可用 - Sharding - 分片集群

Sharding 分片模式角色

Sharding 分片模式下按照层次划分可以分为 3 个大模块:

代理层:mongos
配置中心:副本集群(mongod)
数据层:Shard 集群

请求顺序 层次 层次 实际 作用
1 代理层 mongos mongos 请求分发中心。代理层的组件也就是 mongos ,这是个无状态的组件,纯粹是路由功能。向上对接 Client ,收到 Client 写请求的时候,按照特定算法均衡散列到某一个 Shard 集群,然后数据就写到 Shard 集群了。收到读请求的时候,定位找到这个要读的对象在哪个 Shard 上,就把请求转发到这个 Shard 上,就能读到数据。
2 配置中心 config Replica Set 副本集群 代理层是无状态的模块,数据层的每一个 Shard 是各自独立的,那总要有一个集群统配管理的地方,这个地方就是配置中心。配置中心存储的就是集群拓扑,管理的配置信息。配置中心也是一个 Replica Set 集群,数据也是多副本的。mongos本身没有物理存储分片服务器和数据路由信息,只是存缓存在内存中来读取数据,mongos在第一次启动或后期重启时候,就会从config server中加载配置信息,如果配置服务器信息发生更新会通知所有的mongos来更新自己的状态,从而保证准确的请求路由,生产环境中通常也需要多个config server,防止配置文件存在单节点丢失问题。
3 数据层 Shard Replica Set 副本集群 即存储数据的地方。就是由一个个 Replica Set 集群组成。

Sharding 模式怎么存储数据?

单 Shard 集群是有限的,但 Shard 数量是无限的,Mongo 理论上能够提供近乎无限的空间,能够不断的横向扩容。
首先,要选一个字段(或者多个字段组合也可以)用来做 Key,这个 Key 可以是你任意指定的一个字段。我们现在就是要使用这个 Key 来,通过分片策略(Sharding Strategy)算出发往哪个 Shard 上。
输入Sharding Key ,按照Sharding Strategy 计算出一个值,值的集合形成了一个值域,按照固定步长去切分这个值域,每一个片叫做 Chunk ,每个 Chunk 出生的时候就和某个 Shard 绑定起来,这个绑定关系存储在配置中心里。
所以,MongoDB 用 Chunk 做了一层抽象层,隔离了用户数据和 Shard 的位置,用户数据先按照分片策略算出落在哪个 Chunk 上,由于 Chunk 某一时刻只属于某一个 Shard,所以自然就知道用户数据存到哪个 Shard 了。
Sharding 模式下数据读取过程:
mongos 作为路由模块其实就是寻路的组件,写的时候先算出用户 key 属于哪个 Chunk,然后找出这个 Chunk 属于哪个 Shard,最后把请求发给这个 Shard ,就能把数据写下去。读的时候也是类似,先算出用户 key 属于哪个 Chunk,然后找出这个 Chunk 属于哪个 Shard,最后把请求发给这个 Shard ,就能把数据读上来。
实际情况下,mongos 不需要每次都和 Config Server 交互,大部分情况下只需要把 Chunk 的映射表 cache 一份在 mongos 的内存,就能减少一次网络交互,提高性能。
本质上 Sharding Strategy 是形成值域的策略而已,MongoDB 支持两种 Sharding Strategy:

Hashed Sharding 的方式
Range Sharding 的方式

Hashed Sharding 哈希规则分片

把 Key 作为输入,输入到一个 Hash 函数中,计算出一个整数值,值的集合形成了一个值域,按照固定步长去切分这个值域,每一个片叫做 Chunk ,这里的 Chunk 则就是整数的一段范围而已。
优点:计算快,随机好均衡性好。缺点是性能差需要所有Shard 参与。

Range Sharding 范围规则分片

Range 的方式本质上是直接用 Key 本身来做值,形成的 一个值域。

优点:对排序列举场景非常友好,因为数据本来就是按照顺序依次放在 Shard 上的,排序列举的时候,顺序读即可,非常快速;

缺点:容易导致热点,举个例子,如果 Sharding Key 都有相同前缀,那么大概率会分配到同一个 Shard 上,就盯着这个 Shard 写,其他 Shard 空闲的很,却无法使用;

Shard(Replica Set)集群个数多了,即使一个或多个 Shard 不可用,Mongo 集群对外仍可以 提供读取和写入服务。因为每一个 Shard 都有一个 Primary 节点,都可以提供写服务,可用性进一步提升。

创建顺序

  1. # 创建2个Replica Set 用作存数据 分片 启动
  2. (主、从、仲裁)
  3. (主、从、仲裁)
  4. 配置文件:
  5. sharding
  6. clusterRole: shardsvr
  7. # 创建1个Replica Set 用作存配置文件 config 配置中心 启动
  8. (主、从、从)
  9. 配置文件:
  10. sharding
  11. clusterRole: configsvr
clusterRole 集群角色值 说明
configsvr 将此实例作为配置服务器启动。默认情况下,该实例在端口 27019 上启动。将 MongoDB 实例配置为 clusterRole configsvr 时,还必须指定 replSetName
shardsvr 将该实例作为分片启动。默认情况下,该实例在端口 27018 上启动。当您将 MongoDB 实例配置为 clusterRole shardsvr 时,您还必须指定 replSetName
  1. # 创建2个路由节点 mongos 代理
  2. 需要log,不需要data
  3. 配置文件:
  4. sharding
  5. configDB:myconfigrs/ip:端口号,ip:端口号,ip:端口号
  6. 只需配置configsvr3ip
  1. # 在mongos添加分片
  2. sh.addShard("IP:PORT")
  3. sh.addShard("Shard01/IP:PORT,IP:PORT,IP:PORT")
  4. sh.addShard("Shard02/IP:PORT,IP:PORT,IP:PORT")
  5. Shard01Shard02副本集名称
  6. 主、从、仲裁都要加上
  7. # 在mongos开启分片功能
  8. sh.enableSharding("库名")
  9. sh.shardcollection(namespace, key, unique)
  10. 哈希分片,根据nickname
  11. sh.shardcollection("articledb.comment",{"nickname":"hashed"})
  12. 范围分片,根据age
  13. sh.shardcollection("articledb,author",("age":1))
  14. 看状态:
  15. sh.status()
Parameter Type Description
namespace string 要(分片)共享的目标集合的命名空间,格式:<database><collection>
key document 用作分片键的索引规范文档。shard键决定MongoDB如何在shard之间分发文档。除非集合为空,否则索引必须在shard collection命令之前存在。如果集合为空,则MongoDB在对集合进行分片之前创建索引,前提是支持分片键的索引不存在。简单的说:由包含字段和该字段的索引遍历方向的文档组成。
unique boolean 当值为true情况下,片键字段上会限制为确保是唯一索引。哈希策略片键不支持唯一索引。默认是false。
  1. 范围分片
  2. use config
  3. db.settings.save( { _id:"chunksize" value: 1 } )
  4. 设置数据块尺寸默认64M
  5. 设置数据块尺寸1M
  1. 连接的话就连接路由就可以了