Mongodb中Sharding集群

        随着mongodb数据量的增多,可能会达到单个节点的存储能力限制,以及application较大的访问量也会导致单个节点无法承担,所以此时需要构建集群环境,并通过sharding方案将整个数据集拆分成多个更小的chunk,并分布在集群中多个mongod节点上,最终达到存储和负载能力扩容、压力分流的作用。在sharding架构中,每个负责存储一部分数据的mongod节点称为shard(分片),shard上分布的数据块称为chunk,collections可以根据“shard key”(称为分片键)将数据集拆分为多个chunks,并相对均衡的分布在多个shards上。

       sharded cluster的拓扑结构,它包含三个组件:shards、config servers和query routers:

    1)Shards:存储节点,为了提高可用性和数据一致性,通常每个shard是一个“replica set”结构。

    2)Query routers:查询路由节点,即mongos节点,mongos接收客户端请求,并负责将operations根据路由规则转发给合适的shard或者shards,然后再将result返回给客户端,它起到了一个路由、转发的作用,类似于proxy层。sharded集群可以有多个mongos节点,可以均衡客户端请求。对于Sharded集群,客户端(包括shell)访问数据需要通过mongos,如果直接与shard相连,只能看到一些零碎的数据表。

    3)Config servers:存储集群的metadata数据,数据中包含shards节点列表、chunk与数据集的映射关系、lock信息等等;它为集群的枢纽部分,mongos使用这些信息将请求路由到特定的shards上,对于production环境,一个集群必须有3个Condig servers。

     shard节点可以为单个mongod,和一个Config server。

     数据的分区根据“shard key”,对于每个需要sharding的collection,都需要指定“shard key”(分片键);分片键必须是索引字段或者为组合索引的左前缀;mongodb根据分片键将数据分成多个chunks,并将它们均匀分布在多个shards节点上。目前,mongodb支持两种分区算法:区间分区(Range)和哈希(Hash)分区。

   1)Range分区:首先shard key必须是数字类型,整个区间的上下边界分别为“正无穷大”、“负无穷大”,每个chunk覆盖一段子区间,即整体而言,任何shard key均会被某个特定的chunk所覆盖。区间均为作闭右开。每个区间均不会有重叠覆盖,且互相临近。当然chunk并不是预先创建的,而是随着chunk数据的增大而不断split。

   2)Hash分区:计算shard key的hash值(64位数字),并以此作为Range来分区,基本方式同1);Hash值具有很强的散列能力,通常不同的shard key具有不同的hash值(冲突是有限的),这种分区方式可以将document更加随机的分散在不同的chunks上。

         Range分区更好的支持range查询,根据指定的shard key进行range查询,router可以很简单的判断出那些chunks覆盖此range,并将请求转发给特定的几个shards。不过当shard key是单调递增时,range分区会导致数据分布不均,因为在一定时间内,所有write请求(读取最新数据的read请求)将会映射到一个shard上,即少数shards在某段时间内承载了系统的大部分请求。

    Hash分区正好相反,即使是单调递增的shard key,它们的Hash值也有较大不同,因此这些数据将会比较随机的分散在多个chunks上,但是这引入了range查询的问题,临近的shard key可能分布在不同的chunks上甚至是shards上,这意味着range查询需要访问所有的shards,特别是在有sort、limit等操作时。    

   数据的增删操作以及集群中增减shards节点,都可能导致数据的分布不均,不过mongos提供了balancer机制,它可以对chunks进行split(分裂)和迁移,最终动态平衡数据分布。

    Splitting:一个后台进程用于避免chunk增长的过大,当chunk尺寸超过指定的chunk size时(默认为64M,可以命令修改),mongodb将会把此chunk分成等同的2个;inserts和updates操作均可以触发split,分离时mongodb不会迁移任何数据,也不会对shard产生影响(split之后shard将会修改config server中的metadata,IO通讯方式同“chunk迁移”。

     Balancing:一个后台线程用于管理chunks迁移,balancer可以运行在任何一个(多个)mongos上;当集群中collection数据分布不均时,balancer将把一部分chunks从chunks量最大的shard上迁移到持有量最小的shards上,直到平衡为止;在chunk迁移时,源shard将会把此chunk数据全部发送给目标shard,在此期间,源shard仍负责接收客户端的请求(read、write);最终,在config servers上变更chunks的位置信息。如果迁移过程中,发生异常,balancer将会终止此chunk的迁移,chunk也将继续保留在原来的shard上;当迁移成功后,mongodb将会删除原来shard上的chunk文件。

     集群环境可以动态调整,比如数据量增大到一定程度,可以向集群中增加shard节点;如果数据量紧缩,也可以移除shard;这些过程均会触发chunks的动态平衡。

一、Sharded集群构成

    1、Shards:上文已知,shards即为存储实际数据的mongodb节点,每个shard持有多个chunks。但是有些collection是不需要sharding的,即此collection的数据保存一个shard节点上,也不会被split,我们称这个节点为primary shard;一个database中,所有的非sharding类型的collections均会保存在同一个primary shard上;但不同的databases它们的primary shard可能不同。如果你希望修改某个database的primay shard,可以使用“movePrimary”指令。

    在production环境中,每个shard通常是replica set结构,为了避免数据丢失或者不一致的情况。如果一个shard的replica set中所有的members都失效,这意味着此shard的数据将不可用,但是其他shard仍然可以继续提供读写服务;不过application的查询需要能够应对这种问题,如果你希望某个shard失效后仍然可以查询部分数据,数据缺失是可以接收的,那么可以在read操作中指定“partial”选项:

  1. MongoCursor<Document> cursor = collection.find(Filters.eq("name", "zhangsan")).batchSize(32)  
  2.                 .limit(32)  
  3.                 .partial(true)  

 2、Config servers:配置服务器,Cluster的枢纽部分,用于保存metadata数据;production环境中,需要三个(exactly)config servers,所有的config servers都有效时才能将metadata保存成功;这三个config servers并非replica set结构,它们独立部署。(参见下文)不过对于测试环境,可以只有一个config server;如果只有一个config server,那么它将成为集群的单点。如果config servers失效,那么整个集群也将无法访问,如果metadata数据丢失,那么整个集群将无法使用。

Config servers将metadata保存在config数据库中(稍后介绍),mongos实例将会从config server中获取metadata并在本地缓存,并用于路由reads、writes请求。mongodb只会在“chunk迁移之后”、“chunk split之后”才会修改metadata数据。当需要修改metadata时,协调者(mongos)将会把变更指令发送给三个config servers并获得它们的响应结果,如果结果不同,则意味着产生了数据不一致的情况,则可能需要人工干预;此时,balancer也将不会执行chunk迁移,mongos也不会执行chunks分裂。

    当mongos启动时将会从config servers获取metadata信息,运行时的某些错误也会导致mongos重新获取metadata。此外,config server中还保存了一些locks,我们稍后介绍。

只要有一个config server失效,那么集群的metadata都将处于只读状态,可以对shards进行数据读写,但是chunks分离和迁移将不能进行,知道三个config servers全部有效为止。如果三个config servers都失效,那么意味着集群将不能读取metadata数据,如果此时重启mongos,那么它将不能获取metadata数据,将无法提供router,直到config servers有效。此外,metadata的数据量非常小,所以这不会对Config servers或者mongos带来存储上的压力。Config server的负载非常小,它对硬件配置要求很低,只需要较少的内存和存储空间即可。

    prodution环境中,需要三个config servers;如果仅仅为了测试可以只需要一个。

备注:mongodb 3.2+版本终于调整了Config servers的部署模式(这里总有问不完的“为什么需要三个Config Servers”),放弃了必须使用三个Config Servers的要求;Config Servers可以采用“Replica set”架构模式,且必须使用WiredTiger存储引擎。这种调整,可以有效的提升config servers的数据一致性,可能利用replica set架构的优点,Config Servers的个数可以扩展到50个节点。不过replica set中,不能有“arbiters”、“delayed”类型的members,且它们的“buildIndexes”必须设定为true。

3、mongos:routers,本身不保存任何用户数据,负责转发客户端的读写请求、对shard的结果进行收集归并、运行balancer进程、跟踪split等;通常我们在每个application节点上部署一个mongos,因为mongos占用内存极少,几乎不占用磁盘,它只需要消耗一定的内存、CPU用于处理数据即可,此外这样部署application与mongos通信距离最短、效率较高。你可能想在applications与mongos之间搭建提个proxy或者负载均衡器,这种方式是很难实施的,而且可能会带来很多

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值