一基本概念
分片 (sharding) 是一个通过多台机器分配数据的方法 MongoDB 使用分片支持大数据集和高吞吐量的操作大数据集和高吞吐量的数据库系统挑战着单一服务的性能例如: 高查询率将耗尽 CPU 的性能大于系统 RAM 的工作集将给磁盘的 IO 很大的压力
应对系统的增长有两个方法: 垂直扩展和水平扩展
垂直扩展的方法是提升单一服务的性能, 例如: 使用一个更强的 CPU, 或更多的内存, 或提升大量的存储空间可用技术的局限性将限制单一服务的工作负载另外基于云的提供者也有硬件配置的上限所以, 垂直扩展是有上限的
水平扩展的方法是将系统的数据集分配到多个服务上, 添加额外的服务可以提升系统的能力一个单独机器的性能和速度可以不是很高, 每台机器处理整个工作负载的一个子集, 潜在地相比一个单一的高速度高性能的服务, 提供了更好的性能扩展部署的能力仅仅需要添加额外的需要的服务, 这比添加高档的硬件要便宜不少
1.1 分片集群
MongoDB 的分片集群由下面的几个组件组成:
分片(shard): 每个分片包含了分片数据的一个子集, 每个分片可以作为一个副本集部署
mongos:mongos 扮演者查询路由的角色, 提供着客户端应用和分片集群的接口
config servers: 配置服务存储着集群的元数据和配置设置, MongoDB3.4 以后, 配置服务必须部署成副本集
下图描述了分片集群中, 各个组件的交互
mongodb 在 collection 级别对数据进行分片, 分配 collection 数据到集群中的每一个分片
1.2 分片主键(shard keys)
为了在集合中分配文档, MongoDB 使用分片主键分割集合分片主键由不重复的字段或者字段集合组成
对一个集合分片时, 你要选择分片主键, 分片主键在分片以后不能修改一个分片集合只有一个分片主键
为了对非空的集合进行分片, 集合必须有一个以分片主键开头的索引对于空集合, 如果集合对于分片主键没有一个合适的索引, MongoDB 将创建索引
分片主键的选择将影响分片集群的性能效果和扩展能力一个最佳的硬件和基础设施的集群的瓶颈取决于分片主键的选择分片主键的选择将影响你的集群使用的分片策略
1.3 区块(chunks)
MongoDB 分割分片数据到区块, 每一个区块包含基于分片主键的左闭右开的区间范围在分片集群中, MongoDB 通过分片迁移区块, 使用分片集群权衡器权衡器视图完成一个公平的区块平衡, 通过集群中所有的分片
1.4 分片的优点
MongoDB 通过集群中的分片分配读和写的工作负载, 允许每个分片处理集群中的一部分操作, 读和写的工作负载可以通过添加分片进行横向扩展包含分片主键或者组合主键前缀的查询, mongos 可以定位这个查询到特定的分片或者分片子集上这种定位操作比广播到所有分片要高效的多
集群中的分片存储整个数据中的一部分, 随着数据的增长, 增加额外的分片可以增加集群的存储能力
即使集群中的一个或多个分片不可用, 集群也可以继续执行一部分读写操作在宕机期间, 不可用的分片上的数据是不能够处理的, 可用分片上的读写操作是可以被成功处理的在生产环境, 每一个分片将被部署成副本集, 提供可增长的冗余和高可用
1.5 分片之前的考虑
分片集群的基础需求和复杂性需要小心的计划执行和维护谨慎地考虑分片主键是确保集群性能和效率所必须的在分片之后, 你不能改变分片的主键, 也不能使集合不分片如果查询不包含分片主键或者组合主键的前缀, mongos 将执行广播操作, 查询所有分片, 这些查询将执行很长时间
1.6 分片和不分片集合
一个数据库可以有分片集合和不分片集合的混合, 分片集合通过集群中的分片进行分割和分配, 不分片集合将存储在基础分片中每个数据库都有一个自己的基础分片
1.7 连接分片集群
你必须连接 mongos 路由和集合中的集合进行交互这包含分片和不分片的集合客户端绝不可能连接一个单独的分片进行操作你可以像连接 mongod 一样连接 mongos, 他们是一样的
1.8 分片策略
MongoDB 支持两种分片策略进行数据分片
Hash 分片
Hash 分片是计算一个分片主键的 hash 值, 每一个区块将分配一个范围的 hash 值
当分片主键中的一个范围被关闭, 他们的 hash 值不可能在相同的区块中基于 hash 值分布的数据促使了更多的数据分布, 特别是分片主键单调变化的数据集
Hash 分布意味着基于分片主键的范围查询很少可能命中一个单一的分片, 导致了更多的广播操作
范围分片
范围分片是基于分片主键的值切分数据, 每一个区块将会分配到一个范围
分片主键的范围被关闭, 他们也很有可能落在相同的区块中这使得 mongos 可以路由操作到请求数据的分片上范围分片的效率取决于分片主键的选择, 欠考虑的分片主键将导致数据分布不均匀这将取消一些分片的益处, 还可以导致性能瓶颈
二分片集群的搭建
由于测试机有限, 这里我们只展示最简单的分片搭建, 即一个分片一个配置服务一个路由
首先, 我们启动配置服务, 配置服务的 mongodb 的配置文件如下:
- sharding:
- clusterRole: configsvr
- replication:
- replSetName: "rs"
- net:
- bindIp: 192.168.2.233
clusterRole 设置成 configsvr, 表名这个 mongod 是配置服务; 副本集的名字叫做 rs
./bin/mongod --config conf/mongod.conf
然后, 我们通过 mongo shell 连接这个 mongod 实例
mongo --host 192.168.2.233 --port 27019
值得注意的是, 配置服务启动时, 默认的端口是 27019, 本人一开始并没有注意到, 一直连接 27017, 连接不上, 最后才发现端口不对然后添加副本集
rs.initiate()
返回如下:
- {
- "info2" : "no configuration specified. Using a default configuration for the set",
- "me" : "192.168.2.233:27019",
- "ok" : 1,
- "operationTime" : Timestamp(1519283130, 1),
- "$gleStats" : {
- "lastOpTime" : Timestamp(1519283130, 1),
- "electionId" : ObjectId("000000000000000000000000")
- },
- "$clusterTime" : {
- "clusterTime" : Timestamp(1519283130, 1),
- "signature" : {
- "hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
- "keyId" : NumberLong(0)
- }
- }
- }
当出现 ok=1 时, 说明添加成功了
其次, 我们启动 shard 实例配置文件的内容如下:
- sharding:
- clusterRole: shardsvr
- replication:
- replSetName: "rs0"
- net:
- bindIp: 192.168.2.234
clusterRole 配置 shardsvr, 说明这个实例是 shard 实例副本集的名字我们叫做 rs0, 区别于配置服务的 rs 启动 mongod 实例
./bin/mongod --config conf/mongod.conf
通过 mongo shell 连接这个实例
./bin/mongo --host 192.168.2.234 --port 27018
注意 shard 的实例启动时端口默认为 27018 然后初始化副本集
rs.initiate()
返回结果如下:
- {
- "info2" : "no configuration specified. Using a default configuration for the set",
- "me" : "192.168.2.234:27018",
- "ok" : 1
- }
最后启动 mongos 实例, 配置文件内容如下:
- sharding:
- configDB: rs/192.168.2.233:27019
- net:
- bindIp: 192.168.2.235
configDB 是配置服务副本集的名字, 格式如下: 副本集名称 / ip: 端口启动 mongos 实例
./bin/mongos --config conf/mongod.conf
注意这里的命令是 mongos, 而不是之前的 mongod 通过 mongo shell 连接这个实例
./bin/mongo --host 192.168.2.235 --port 27017
这里的端口是 mongodb 的默认端口 27017 向集群中添加分片
sh.addShard( "rs0/192.168.2.234:27018")
分片的格式为: 副本集名称 / ip: 端口然后添加分片的数据库
sh.enableSharding("<database>")
配饰分片的集合和主键
sh.shardCollection("<database>.<collection>", { <key> : <direction> } )
<key > 为主键字段的名字
<direction > 为以下 3 种: 1: 主键值正向遍历;
-1: 主键值反向遍历;
hashed: 主键 hash 值
至此, MongoDB 的分片集群介绍完了
来源: https://www.cnblogs.com/boboooo/p/8440846.html