`

【转】MongoDB分片中片键的选择

 
阅读更多

当MongoDB整个架构已经部署好以后,真正考验架构者能力的时候就到了:该如何选择片键。

如果选择了一个不恰当的片键,他可能会在访问量变大的时候,使你的整个应用系统崩溃,同样好的片键可以构成一个良性的生态系统,根据需要增删服务器,MongoDB会确保系统一直正确的运行下去。

咱们先看看几种不恰当的片键

1,小基数片键

    假设我们有一个存储用户信息的应用程序,每个文档有一个continent的字段,存储用户所在地区,其值有:africa,antarctica,asia,australia,europe,north america,south america。考虑到我们在每个州都有一个数据中心,并且想从人们所在地的数据中心为其提供数据,我们决定按该字段分片。

     集合开始于某个数据中心的一个分片的初始块(-∞,∞),所有的插入和读取都落在这一块上,一旦他变得足够大,就会被分成两个块(-∞,europe)和[europe,∞),这样一来,所有来自africa,antarctica,asia和australia的文档都会被分到第一块,其他的都会被分到第二块,随着更多的文档被添加到数据库,集合最终会变成7个块,如下

   (-∞,antarctica)

   [anrarctica,asia)

   [asia,australia)

   [australia,europe)

   [europe,north america)

   [north america,south america)

   [south america,∞)

然后呢?

MongoDB不能再进一步分割这些块了,快会越来越大,虽然暂时不会出问题,但是当服务器硬盘空间被用完的时候,你就没办法了,只能购买新的硬盘,悲剧的是硬盘是有极限的。

  由于片键数量有限,因此这种片键称为小基数片键,如果选择了一个基数很小的片键,到头来肯定会得到一堆巨大无法移动也不能分割的块,这时候做维护做扩展是什么感觉,你懂得。

 如果是因为需要在某个字段上做大量查询而采用小基数片键,那就需要使用组合片键了,一个片键包含两个字段,并确保第二个字段有非常多不同的值供MongoDB用来进行分割,比如大部分的查询都和时间关联,可以用时间字段做第二个字段,又可以减轻负载。

2,升序片键

从RAM中读取数据要比磁盘取快,所以目标是尽可能多的访问内存中的数据。一次,如果有些数据总是被一起访问,我们就希望能够把他们保持在一起。对大部分应用来说,新数据被访问的次数总比老的多,所以往往会使用如时间戳或者objectId一类的字段来分片,但是这并不想我们期望的那样可行。

 比如我们有一个类似微博的服务,其中每个文档都包含一条消息,发送人和发送时间,我们按时间来分片,让我们看看MongoDB会如何运行

  首先还是一个大块(-∞,∞),文档会全部插入到这个分片上,然后开始分裂,比如(-∞,1294516901),[1294516901,-∞)----(使用的是时间戳),由于是从片键中点把块分开,所以在分割开快的那一刻开始,说有数据都会插入到第二个块上,不会在插入带第一个块上,一旦块二被插满,他会在分割成两块,但同样的只会在最后一块插入数据,这种情况会一直持续下去,这就造成了一个单一且不可分散的热点。在网站高峰期可见这个点上的压力。

3,随机片键

    有时为了避免热点,会采用一个取值随机的字段来做分片,采用这种片键一开始还不错,但是随着数据量越来越大,他会越来越慢。

     比如我们在分片集合中存储照片缩略图,每个文档包含了照片的二进制数据,二进制数据的md5散列值,以及描述等字段,我们决定在md5散列值上做分片。

    随着集合的增长,我们最终会得到一组均匀分布于各分片的数据块。目前一起正常。现在假设我们非常忙而分片2上的一个块填满并分裂了,配置服务器注意到分片2比分片1多出了10个块并判定应该抹平分片间的差距,这样MongoDB就需要随机加载5个块的数据到内存中并发给片1,考虑到数据序列的随机性,一般情况下这些数据可能不会出现在内存中,所以此时的MongoDB会给RAM带来更大的压力,而且还会引发大量的磁盘IO。

   另外,片键上必须有索引,因此如果选择了从不依据索引查询的随机键,基本上可以说浪费了一个索引,另一方面索引的增加会降低写操作的速度,所以降低索引量也是非常必要的。

那么怎么样的片键才是好的片键呢?

从上面的分析可得出一个好的片键应该具备良好的数据局部性,但又不会因为太局部而导致热点出现。

1,准升序键加搜索键

     许多应用程序都是访问新数据更频繁,所以我们希望数据大致按时间排序,但是同时也要均匀分布,这样一来既能把我们正在读写的数据保持在内存中,又可以均衡的分散在集群中。

     我们可以通过像{coarselyAscending:1,search:1}这样的组合片键来实现,其中coarselyAscending的每个值最好能对应几十到几百个数据块,而search则应当是应用程序通常都会一句其进行查询的字段。

  举个例子:有个分析程序,用户定期通过他访问过去一个月的数据,而我们希望能尽量保持数据易于使用,因此可以使用{month:1,user:1}来做分片,现在来说说运行过程

   首先一个大数据块((-∞,-∞),(∞,∞)),当他被填满,MongoDB将自动分割成两块,比如:

     ((-∞,-∞),("2012-07","susan"))

    [("2012-07","susan"),(∞,∞))

假设现在还是7月,则所有写操作会被均匀的分布到两个块上。所有用户名小于susan的数据被写入块1中,所有大于susan的数据被写入块2,然后整个生态系统就良性运行了,等到8月,MongoDB又开始创建2012-08的块,分布还是均衡的(这里不是时时均衡,肯定有个抹平的过程),等到9月,7月的数据无人访问就开始退出内存,不再占用资源。

 

--------------------------------------------------------------------------------------------------------------------------------------

当然场景不同,应用就不同,上面也只是基本的东西,具体选择片键还应该根据自己的程序来做,选键的时候多考虑以下问题。

   1,写操作是怎么样的,有多大?

   2,系统没小时会写多少数据,每天呢,高峰期呢

   3,那些字段是随机的,那些是增长的

   4,读操作是怎么样的,用户在访问那些数据

   5,数据索引做了吗?应不应该索引呢?

  6,数据总量有多少

 总的来说,在进行分片前,你需要清楚的了解你的数据。

 

 以上内容参考了“深入学习MongoDB” 一书,如果需了解更多MongoDB优化的知识,这本数绝对值得一读,这本书还列出了50例MongoDB优化,维护等等需要注意的地方

 

转自 http://www.cnblogs.com/spnt/archive/2012/07/27/2611540.html

分享到:
评论

相关推荐

    MongoDB分片介绍

    分片策略的选择和调整非常重要,因为不恰当的分片可能会导致负载不平衡或查询效率低下。MongoDB允许动态调整分片,如添加、移除分片,或者重新分片集合以优化数据分布。此外,根据业务需求,可以使用范围分片、哈希...

    k8s 安装 mongodb 分片(Sharding)+ 副本集(Replica Set)

    k8s 安装 MongoDB 分片(Sharding)+ 副本集(Replica Set) k8s 安装 MongoDB 分片(Sharding)+ 副本集(Replica Set)是结合 Kubernetes(k8s)和 MongoDB 实现高可用性和高性能的解决方案。本解决方案通过使用 ...

    mongodb分片备份

    本文将详细介绍MongoDB的分片备份以及复制集的备份方法。 **1. 分片备份** MongoDB 分片是将大数据集分散到多个物理节点上,以提高查询性能和存储容量。分片备份主要涉及配置服务器(Config Server)的备份。配置...

    mongodb分片设计

    部署教程(Sharded Cluster Deployment Tutorials)中包括了建立分片集群(Deploy a Sharded Cluster)、选择分片键(Considerations for Selecting Shard Keys)、使用哈希分片键(Shard a Collection Using a ...

    实验五 MongoDB分片部署与启动

    ### 实验五 MongoDB分片部署与启动 #### 实验综述 本次实验旨在深入学习MongoDB的分片机制,理解并掌握如何部署一个基于多服务器的MongoDB分片集群。分片是MongoDB的一项重要特性,它允许将数据分散存储在多个物理...

    mongodb分片集群增加acl

    本文将详细介绍在MongoDB 3.6版本中如何增加分片集群的ACL(访问控制列表)权限,以及在搭建分片集群过程中可能遇到的一些问题及其解决方案。 ### MongoDB分片集群简介 MongoDB分片集群是一种分布式数据存储结构,...

    MongoDB分片副本级

    MongoDB分片副本级 详细的讲述了MongoDB分片副本级配置

    MongoDB4.2分片及副本集群搭建

    MongoDB4.2分片及副本集群搭建 MongoDB集群 MongoDB分片 MongoDB副本 MongoDB副本集群

    13、MongoDB分片集群&高级集群架构详解-ev.rar

    13、MongoDB分片集群&高级集群架构详解_ev.rar13、MongoDB分片集群&高级集群架构详解_ev.rar13、MongoDB分片集群&高级集群架构详解_ev.rar13、MongoDB分片集群&高级集群架构详解_ev.rar13、MongoDB分片集群&高级集群...

    mongodb中文API及分布式分片实例详解

    5. 分配数据:MongoDB会根据分片键自动分配新插入的数据到各分片。如果需要手动迁移数据,可以使用`sh.moveChunk`命令。 6. 负载均衡:MongoDB的平衡器会定期检查数据分布,当某分片负载过高或空闲时,会自动迁移...

    mongodb分片

    5. 分片键的选择至关重要,应该根据业务需求和数据分布特性来选取,以保证数据的均匀分布和最佳性能。 **分片测试与管理:** 1. 可以通过`db.collection.stats()`查看集合状态,`db.printShardingStatus()`检查分片...

    mongoDB分片技术处理方案

    1. 选择合适的分片键:分片键直接影响数据分布,应避免选择值过于集中或稀疏的字段。 2. 数据平衡:定期监控和调整数据分布,防止某些分片过载。 3. 查询优化:尽量设计查询语句以利用分片键,避免全集合扫描。 六...

    mongodb分片linux安装文档

    MongoDB 分片是大型数据库系统中用于横向扩展存储能力的关键技术。在 CentOS 7 上部署 MongoDB 分片集群是一项复杂但必要的任务,特别是当处理大量数据并需要高效读写性能时。以下是一个详细的步骤指南,涵盖了从...

    mongodb分片与副本集详细配置方案

    MongoDB 是一个高性能、分布式、开源的文档型数据库,它支持分片(sharding)和副本集(replica sets)来实现水平扩展和高可用性。分片是将数据分散到多个物理节点上,以处理大数据量和高并发场景;副本集则是为了...

    MongoDB分片详细教程

    ### MongoDB分片技术详解 #### 一、MongoDB分片概念 MongoDB 分片是一种将数据分布在网络中的多个服务器上的方法。它通过水平分割数据来提高可伸缩性和性能,适用于处理大量数据和高并发访问场景。分片的核心组件...

    mongodb分片集群安装包

    5. **设定分片策略**:在Mongos上定义分片策略,包括选择分片键(决定数据如何分布到分片上)和启用分片的集合。 6. **添加分片**:向集群添加分片,指定其ID和连接信息。之后,MongoDB会自动将新数据分布到各个分...

    MongoDB分片实例.pdf

    MongoDB 分片是数据库扩展的一种策略,用于处理大数据量和高...总之,MongoDB的分片技术是应对大规模数据存储和高性能需求的关键手段,通过合理的分片配置和片键选择,可以有效地管理和优化大数据环境下的数据库系统。

    centos7下mongodb4.0.6分片集群搭建(psa)-用户认证关键问题汇总

    公司单节点升级到分片下,搜索了一圈大多数MongoDB集群的部署方案都是分片+副本集,没有讲述如何从单节点升级到分片+复制集的方法,亲自试验后记录整个过程以及中间的参考内容和疑难解决,以备后查。内容包含复制集+...

Global site tag (gtag.js) - Google Analytics