作者:小晶2502890507 | 来源:互联网 | 2023-09-23 08:47
(一)分片的由来随着系统的业务量越来越大,业务系统往往会出现这样一些特点:高吞吐量高并发超大规模的数据量高并发的业务可能会耗尽服务器的CPU,高吞吐量、超大规模的数据量也会带来内存
(一)分片的由来
随着系统的业务量越来越大,业务系统往往会出现这样一些特点:
高并发的业务可能会耗尽服务器的CPU,高吞吐量、超大规模的数据量也会带来内存、磁盘的压力。
对于这类问题,解决系统增长的方法有2种:垂直扩展和水平扩展。
- 垂直扩展主要是增加单个服务器的资源。例如:使用增强大的CPU、增加更多的内存、使用固态硬盘等。
- 水平扩展主要是增加服务器。虽然单台服务器的整体速度或者容量都比较低,但如果每台服务器只处理工作量的一部分,则与单台服务器相比,可以提供更多的资源,提高效率。
垂直扩展终归有一个上限,例如,我已经用了最好的CPU、服务器主板也已经插满了内存、也使用了SSD存储设备,可是依然还是无法满足需求。那么这个时候就不得不考虑使用水平扩展了,通过增加机器,将业务、数据拆分到不同的机器上,实现业务的分流。
MongoDB是如何实现水平扩展的呢?Sharding,中文即分片。分片是指将数据拆分,将其分散放在不同主机上的过程。
(二)何时分片
如果在系统建设初期,就能够较为准确的评估出将来的业务量,那么直接在建设系统时就实施分片是最好的。但是在实际应用中,我们很难评估出将来的业务量大小,所以最好是在业务运行一段时间之后进行分片,当然,也不能在业务运行了几乎达到满负载运行时才进行分片,因为在近乎满负载的集群上不停机进行分片是非常困难的。通常,分片用来:
- 增加可用RAM
- 增加可用磁盘空间
- 减轻单台服务器的负载
- 处理单台服务器无法处理的吞吐量
(三)分片集群架构
一个完整的分片集群的架构如下图
其核心主要包括:mongos、config server、shard三部分。
(3.1)mongos
mongos是查询路由,在客户端程序和分片之间提供接口,用户如果要访问mongodb分片数据库,必须使用mongos。部署多个mongos可支持高可用性和可拓展性,一个常见的模式是在每个应用服务器上部署一个mongos,以减少应用程序和mongos之间的网络延迟。
mongos从配置服务器读取分片集群元数据并缓存下来,利用元数据,实现对客户端读写操作的路由。
(3.1.1)mongos如何处理查询修饰符
sort :如果查询语句不包含排序,则mongos实例将打开结果游标,对该游标分片上的所有游标进行轮询。
limit :如果使用limit限制了结果集大小,则mongos会将limit操作下发到分片上,然后再将limit操作用于分片返回的结果。
skip :如果查询中使用了skip,则不能将skip传给分片,而是从分片检索未跳过的结果,并将组装完结果后跳过指定的文档数量
(3.1.2)确认与mongos实例的连接
要检测客户端是否连接到mongos,使用isMaster命令,当连接到mongos时,会返回"msg" : "isdbgrid"。
db.isMaster()
/* 1 */
{
"ismaster" : true,
"msg" : "isdbgrid",
"maxBsonObjectSize" : 16777216,
"maxMessageSizeBytes" : 48000000,
"maxWriteBatchSize" : 100000,
"localTime" : ISODate("2021-01-15T07:00:23.585Z"),
"logicalSessionTimeoutMinutes" : 30,
"connectionId" : 42,
"maxWireVersion" : 8,
"minWireVersion" : 0,
"ok" : 1.0,
"operationTime" : Timestamp(1610694017, 2),
"$clusterTime" : {
"clusterTime" : Timestamp(1610694017, 2),
"signature" : {
"hash" : { "$binary" : "AAAAAAAAAAAAAAAAAAAAAAAAAAA=", "$type" : "00" },
"keyId" : NumberLong(0)
}
}
}
(3.1.3)目标操作和广播操作
在分片集群中,最快的操作是使用mongos通过shard key路由到单个分片上,这种目标操作使用shard key定位满足查询的文档分片或分片子集。对于不包含分片键的查询,mongos必须查询所有的分片,然后将结果返回给客户端,这些“scatter/gather”查询可能会消耗更多的时间。
(3.1.4)元数据操作
mongos使用"majority"写关注操作元数据:
命令 方法
------------- ----------------
addShard sh.addShard()
create db.createCollection()
drop db.collection.drop()
dropDatabase db.dropDatabase()
enableSharding sh.enableSharding()
movePrimary
renameCollection db.collection.renameCollection()
shardCollection sh.shardCollection()
removeShard
setFeatureCompatibilityVersion
(3.1.5)FCV兼容性
从MongoDB 4.0开始,mongos尝试连接mongod实例时,如果mongos功能兼容版本(feature compatibility version,fcv)小于mongod,则会造成mongos的二进制文件崩溃。例如:
- 不能使用fcv是4.0版本的mongos连接到fcv是4.2版本的分片集群
- 可以使用fcv是4.2版本的mongos连接到fcv是4.0版本的分片集群
(3.2)config server
配置服务器存储集群的元数据,元数据反映分片集群的内所有数据和组件的状态和组织方式,元数据包含每个分片上的块列表以及定义块的范围。从3.4版本开始,已弃用镜像服务器用作配置服务器(SCCC),config Server必须部署为副本集架构(CSRS)。
Mongos实例缓存配置服务器的数据,并使用它路由读和写操作到正确的分片。当元数据发生改变的时候(例如:添加新的分片、chunks分裂),mongos更新缓存数据。此外,配置服务器还存储基于角色的用户权限信息。MongoDB也是用配置服务器管理分布式锁。每个分片集群都必须有自己的配置服务器,不能共享同一个配置服务器,配置服务器必须运行在WiredTiger存储。
(3.2.1)配置服务器的读写操作
在配置服务器上存在admin和config数据库,admin数据库包含身份验证以及授权相关的集合及其它的system.*集合,config数据库包含分片集群元数据的集合,当元数据发生变更时,MongoDB会将数据写入到config服务器。在做操作或者维护期间,我们应该避免直接去写配置服务器。当我们从副本集配置服务器读数据时,MongoDB使用”majority”读关注,以避免幻读;当我们从副本集配置服务器写数据时,MongoDB使用”majority”写关注,以确保数据不会丢失。
(3.2.2)配置服务器可用性
如果配置副本集丢失其主服务器并且无法选举主节点,则集群元数据变为只读,此时仍然可以从集群中读和写数据,但是不能够执行chunk合并、分裂等改变元数据的操作。
如果所有的副本集服务器不可用,集群将变得不可用。为了确保配置服务器保持可用和完整,备份就显得十分重要,配置服务器数据量很小,备份对主机的性能影响也相对较小。
(3.3.3)分片集群的元数据
分片集群的元数据存储在配置服务器的config数据库中。通常,永远不要直接编辑config数据库的内容,config数据库包含以下集合:
use config
show collections
------------------------------
actionlog
changelog
chunks
collections
databases
lockpings
locks
migrations
mongos
shards
system.sessions
tags
transactions
version
(3.3)Shard
shard是存储数据的地方,每个shard包含集合的一部分数据,从3.6版本开始,每个shard必须部署为副本集(replica set)架构。
(3.3.1)主分片的概念
分片集群中的每个数据库都有一个主分片,其中包含该数据库所有未分片的集合。当在分片集群中创建一个新的数据库时,mongos会为新数据库选择一个分片作为主分片。选择的机制为:选择数据量少的分片作为新数据库的主分片。如下图:集群存在2个分片,对于Collection2集合,没有实施分片,则将全部数据存放在其主分片上。
特别注意:
主分片与副本集的主节点没有任何关系。
【完】
相关文档合集:
1. MongoDB Sharding(一) -- 分片的概念 2. MongoDB Sharding(二) -- 搭建分片集群 3. MongoDB Sharding(三) -- zone 4. MongoDB Sharding(四) -- 分片集群的维护管理
|