第五部分 架构篇 第十八章 MongoDB Sharding 架构(平衡)

1、平衡简介

如果存在多个可用的分片,只要块得数量足够多,MongoDB就会把数据迁移到其他分片上,这个迁移过程叫做平衡(balancing),由叫做平衡器(balancer)的进程负责执行。

2、平衡工作流程

平衡器会把数据块从一个分片挪到另外一个分片上,其优点在于自动化,即你无需担心如何保持数据在分片间的均匀分布,这项工作已经由平衡器替你搞定,不过这也是它的缺点,因为自动意味着如果你不喜欢塔做负载均衡的方式,那只能算你不走运,如果不想让某个块存在于分片3上,你可以手动移动到分片2上,但是平衡器很可能把它再挪回分片3,你只能选择要么对集合重新分片(re-shard),要么关闭平衡化。

在此之前平衡器的算法还不是很智能,它每天基于分片整体大小来移动块,在不久的将来它将变得更加先进。

平衡器的目标不仅是要保持数据均匀分布,还要最小化被移动的数据量,因此触发平衡器需要很多条件,要触发一轮平衡,一个分片必须比块最小的分片多出至少9个块,到那时候,块就会被迁移出拥挤的分片,直到与其他分片平衡为止。

平衡器并不非常激进的原因在于MongoDB希望能够避免将相同数据来回移动,如果平衡器要平衡掉没一点微小的区别,那很可能会不停地浪费资源:分片1比分片2多两个块时,它就发送一个块给分片2,接着一些写操作落到分片2上,使得分片2又比分片1多出两个块,结果同一块数据又被折腾回去,通过等待更严重的不平衡发生,MongoDB能够最小化无意义的数据传输,要知道差9个块其实也不是那么不平衡,因为这还不到2GB数据呢?

说明:

如果如上图所示,每一点轻微的不平衡都被修正,则最终必然导致大量不必要的数据移动。

3、技巧

大家都希望通过看到数据移动来向自己证明分片可以工作,这产生了一个问题:触发一轮平衡所需的数据量远远比大多数人想象的大。

比如说正在尝试分片,于是写了一个命令行脚本来插入50万份文档到分片集合中:

for(i=0;i<500000;i++){
db.foo.insert({"_id":i,"x":1,"y:2"});
}

等插入完成,我应该能看见一些数据飞来飞去了,对不对?错,如果我看一眼数据库状态,就会发生还差得远呢?这些数据大致约40MB,这不够一个块,甚至不够一个块的1/4,前面讲到了一个块默认是200MB,真要想看到数据移动话,需要插入2GB数据,也就是2500万份这样的文档,或者说现在已插入数据的50倍。

开始使用分片时,人们希望看到数据到处移动,这是人的本性使然,尽管如此,在生产系统中你不会希望发生太多迁移,因为这种操作代价极其高昂,因此一方面我们希望看到迁移实际发生,而另外一方面事实又是如果它不是看上去慢慢得让人烦躁就不可能工作的很好,对于这个矛盾,MongoDB需要实现两个技巧,让分片更善解人意,同时又不对生产希望造成破性的影响。

  • 自定义块大小

第一次启动mongos时,可以声明--chunkSize N参数,其中N就是你想要的块大小,单位是MB,如果只是想试试分片,可以设置--chunkSize 1,这样只要插入几MB的数据就能看到迁移发生了。

  • 递增块大小

即使是部署一个真正的应用程序,要达到2GB看起也遥遥无期,所以对于前十几个块,MongoDB会特意自动降低块大小,从200MB降至64MB,而这就是为了更好地照顾一下用户的感受,一旦数据块多起来,它会自动把块大小递增回200MB。

  • 改变块大小

块大小可以通过启动时指定--chunkSize N参数或者修改config.settings集合并整体性重启来改变,尽管如此,除非是为了好玩试试1MB的块大小,否则别启动改动其大小。

时间: 2024-10-16 20:28:15

第五部分 架构篇 第十八章 MongoDB Sharding 架构(平衡)的相关文章

第五部分 架构篇 第二十一章 MongoDB Sharding 架构(实践)

这是一种将海量的数据水平扩展的数据库集群系统,数据分别存储在sharding的各个节点上,使用者通过简单的配置就可以很方便地构建一个分布式MongoDB集群. MongoDB的数据分块成为chunk,每个chunk都是Collection中一段连续的数据记录,通常最大尺寸是200MB,超出则生成新的数据块. 要构建一个MongoDB Sharding Cluster需要以下三个角色: Shard Server 即存储实际数据的分片,每个Shard可以使一个mongod实例,也可以使一组mongo

第五部分 架构篇 第十七章 MongoDB Sharding 架构(理解块)

1.如何创建块 在前面的已经了解MongoDB分片架构中块的基本概念,那么在此来讲述如何创建块?当你决定分配数据时,必须为块区间选择一个键(前面我们一直在用username)这个键叫做片键(shard key),片键可以是任意字段或者字段的组合,比如如下文档中: <pre name="code" class="java"><pre name="code" class="java">{"user

第五部分 架构篇 第十四章 MongoDB Replica Sets 架构(自动故障转移/读写分离实践)

说明:该篇内容部分来自红丸编写的MongoDB实战文章. 1.简介 MongoDB支持在多个机器中通过异步复制达到故障转移和实现冗余,多机器中同一时刻只有一台是用于写操作,正是由于这个情况,为了MongoDB提供了数据一致性的保障,担当primary角色的服务能把读操作分发给Slave(详情请看前两篇关于Replica Set成员组成和理解). MongoDB高可用分为两种: Master-Slave主从复制:只需要在某一个服务启动时加上-master参数,而另外一个服务加上-slave与-so

第五部分 架构篇 第十二章 MongoDB Replica Sets 架构(简介)

1.Replication简介 MongoDB Replication即是在多个服务器中同步复制数据,数据复制的目的为提供冗余和提高数据的可用性,数据复制的操作即在不同的数据库服务器上保存多份复制的数据集,以此来避免单机故障进而丢失数据,复制机制也允许你恢复硬件故障和服务中断,进而起到数据的容灾和备份作用. 在MongoDB中,一个复制集就是一组mongod实例,一个mongod实例作为primary也就是所谓的master服务,接收所有的写操作,其他的mongod实例作为secondaries

第五部分 架构篇 第十九章 MongoDB Sharding 架构( mongos)

1.mongos mongos是用户和集群间的交互点,其职责是隐藏分片内部的复杂性并向用户提供一个简洁的单服务器接口,这个抽象层中也存在一些缝隙,不过大多数情况下mongos允许你把一个集群当做一台服务器. 使用集群时,应该连接一个mongos并向它发送所有的读写操作,无论如何,你都不应该直接访问分片(但如果想的话能做到). mongos会将所有用户请求转发到恰当的分片上,如果用户插入一份文档,mongos会查看文档的片键,对照数据块,并把文档发送到持有相应块的分片上. 举个例子,比如说我们要插

第五部分 架构篇 第十六章 MongoDB Sharding 架构(理解分片)

1.简介 这是一种将海量的数据水平扩展的数据库集群系统,数据分表存储在sharding的各个节点上,使用者通过简单的配置就可以很方便地构建一个分布式的MongoDB集群. 那么首先我们应该理解何为分片(sharding)以及它的基本工作模式. 2.什么是分片 分片(sharding)是MongoDB用来将大型集合分割到不同服务器(或者说一个集群)上所采用的方法,尽管分片起源于关系型数据库分区,但它(像MongoDB大部分方面一样)完全是另外一回事. 和你可能使用过的任何分区方案相比,MongoD

第五部分 架构篇 第十五章 MongoDB Replica Sets 架构(动态增加删除结点)

1.Replica Set增加结点 MongoDB Replica Set不仅提供高可用性的解决方案,它也同时提供负载均衡的解决方案,增减Replica Sets结点在实际应用中非常普遍,比如当应用的读压力暴增时,3台结点的环境已经不能满足需求,那么就需要增加一些结点将压力平均分配一下,当应用的压力小时,可以减少一些结点来减少硬件资源的成本,总是是一个长期且持续的工作. 官方给我们提供了2个方案用于增加结点,一种是通过oplog来增加结点,一种是通过数据库快照(--fastsync)和oplog

第五部分 架构篇 第十三章 MongoDB Replica Sets 架构(成员深入理解)

在学习复制的概念之前,首先接着前面一章节的还有点未完结的内容做个简单的介绍,主要是自动故障转移.异步复制.以及附加功能,这些在此只做简单的介绍,在以后的相关章节中会专门深入学习. 1.自动故障转移 当Primary服务和架构中其他成员中断通信超过10秒,Replica Set将尝试选举其他成员成为一个新的Primary服务,获得多票数的Scondary将成为Primary. 架构如下: 说明: 在一个Replica Set架构中,如果Primary不可达,则会在除Primary之外的其他成员中自

第五部分 架构篇 第二十章 MongoDB Sharding 架构( 片键选择)

1.选择片键 选择一个好的片键非常关键,如果选择了一个糟糕的片键,它可以立马或者在访问量变大时毁了你的应用程序,也有可能潜伏着,等待着,没准什么时候突然毁了你的应用程序. 另外一方面,如果你选择了一个好片键,只要应用程序还在正常运行,而且只要发现访问量提高就赶紧添加服务器,MongoDB就会确保一直正确地运行下去. 正如在前面所学的,片键决定了数据在集群中的分布情况,因此你会希望存在这样一个片键,它既能把读写分散开来,又能把正在使用的数据保持在一起,这些看似互相矛盾的目标在现实中却往往是可以实现