前一部分的文章:
MongoDB 快速入门实战教程基础篇 一 :文档的 CR操作
MongoDB 快速入门实战教程基础篇 一 :文档的 UD操作
MongoDB 快速入门实战教程基础篇 二: 流式聚合操作
MongoDB 快速入门实战教程基础篇 三:执行计划与索引
MongoDB 快速入门实战教程进阶篇 一:数据模型
MongoDB 快速入门实战教程进阶篇 二:提高数据服务可用性的复制集
综合篇 分片、数据备份与访问控制
经过前面几篇的学习,我们已经掌握了 MongoDB 的基本使用,这些知识能够满足日常开发的需求。本篇我们将学习 MongoDB 中的分片、访问控制和数据备份等知识,这将使我们更好地管理 MongoDB 服务。
了解 MongoDB 中的分片
MongoDB 服务的性能有可能会受到业务增长的影响,例如高频的查询会导致 CPU 占用率居高不下,高吞吐的需求会挑战单个服务器的性能等。面对这种问题,通常有两种解决办法:
- 垂直扩展:堆砌单一服务器的硬件以提升其性能,例如增加内存、使用更强的 CPU或增加磁盘数量。
- 水平扩展:增加服务器数量以提升整体性能。
垂直扩展和水平扩展各有缺点,例如垂直扩展会受到单机性能上限的困扰,并且会降低容灾能力;水平扩展虽然不会受到性能上限的困扰,但增加了运维复杂度和成本。MongoBD 推荐的解决办法是通过分片进行水平扩展。
分片概述
MongoDB 中的分片是一种多机分散存储数据的方法,这种方法被用于解决单机难以应对超大数据量或超高吞吐操作的问题,多机组成的的协同工作组称为分片集群。
分片集群由以下几个部分组成:
- 分片:每个分片包含分片数据的子集,每个分片可以是单个 mongo 服务,也可以部署为复制集。
- mongos:充当查询路由器,将客户端的操作转发给分片集群。
- 配置服务器:存储集群的元数据和配置,配置服务器必须是复制集。
MongoDB 使用分片键对集合进行划分,划分好的数据将散布在多台机器上。分片键由集合中的一个或多个不可变字段组成,且一个分片集合只能拥有一个分片键。要注意的是,集合分片之后,分片键和分片键的值都是不可改变的,即无法为集合选择其他分片键,也无法更新分片键字段的值。分片键的选择很重要,它的选择将会影响分片集群的性能和可伸缩性。要注意的是,MongoDB 在集合级别实现分片,而不是数据库级别。
散列分片与范围分片
MongoDB 使用与集合相关的分片键将集合数据分成块,每个块都由分片数据构成。每个块都有一个基于分片键的左闭右开的区间,每个分片可以含有多个块。MongoDB 提供了散列分片和范围分片这两种划分块的方式。
散列分片
散列分片将单个字段的散列值作为分片键,这种方式使得数据分布更均匀。下图描述了散列分片的块划分方式:上图中,x
为分片键值,Chunk
代表块。分片键值相近的文档会散布在不同的块中,而不是同一个块或相邻的块。
假设使用一个单调递增的值 X
(例如 ObjectId
)作为集合的分片键,那么散列分片的结果如下图所示:
散列分片的语法格式如下:
sh.shardCollection( "database.collection", { <field> : "hashed" } )
范围分片
顾名思义,范围分片就是块的划分是根据分片键值确定的连续范围,分片键值相近的文档可能会被划分到同一个块或者分片中。这种连续的范围分片查询效率较高,但写入性能很有可能会因为选择了不合适的分片键的降低。下图描述了范围分片的块划分方式:上图中,x
为分片键值,Chunk
代表块。x < minKey < -75
的文档将会被划分到 Chunk 1
中,x < 175 < maxKey
的文档将会被划分到 Chunk 4
中,其他块的划分将依此规则类推。下图描述了范围分片的结果:
由于值 X
始终在增加,因此具有上限( maxKey
)的块接收大多数写入。这将会降低分片集群的优势,也就是上面提到的“分片键的选择将会影响分片集群的性能”。
范围分片是 MongoDB 默认的分片方式。范围分片的语法格式如下:
sh.shardCollection( "database.collection", { <shard key> } )
MongoDB 允许混用分片集合和非分片集合,分片集合散布在多台服务器中,非分片集合存储在主分片上。下图描述了不同服务器上的集合关系:
其中,collection 1
表示分片集合,collection 2
表示非分片集合。客户端必须借助 mongos 路由才能与分片集群中的集合进行交互,这里的集合包括分片集合和非分片集合。下图描述了客户端、mongos 路由和分片集群的交互流程:
客户端可以通过 MongoShell 或者对应的数据库驱动连接到 mongos 路由。
块的拆分和迁移
MongoDB 中,块的默认大小为 64
兆字节。MongoDB 允许调整块的大小,但大小限制为 1 <= chunksize <= 1024
。假设我们希望调整块的大小,首先我们应该切换到 config
数据库,对应示例如下:
> use config
然后使用 save()
方法更改 chunksize
的值,对应示例如下:
> db.settings.save( {_id:"chunksize", value: <sizeInMB>})
其中,<sizeInMB>
为块的大小。当块超出指定大小或者块中的文档数超出时,MongoDB 就会根据块的分片键值拆分块,即将一个过大的块拆分成多个块。大多数时候,触发块拆分的操作是插入或更新。下图描述了块的拆分过程:
网友评论