乐趣区

关于mongodb:得物技术教你秒懂mongoDB之分片集群

背景

随着公司直播平台的全面凋谢,加上直播玩法的多样降级,最显著的感触就是:

① 数据增量显著。

② 并发量显著变大。

应答这两种变动,作为后端开发就须要在技术选型方面做一些抉择。以后直播量大的业务都是利用 mysql 进行了分表处理。然而察看一段时间下来发现以下几个问题:

① 局部业务的分表上存储的数据量不是很平衡,会存在一些大主播对应的分表数据量显著偏大。

② 上新业务或者一些新流动就要建几十张表以提前应答已知的数据量,操作繁琐且后续变更不不便。

所以在做技术选型的时候就联想到了 mongoDB 的分片集群。上面咱们来一探到底:

一、回顾一下 MongoDB 的特点

1 灵便的模型

区别于关系数据库最大的一个特点就是字段灵便变更,这就非常适合一些迭代频繁且数据模型多变的业务场景。例如咱们直播的流动业务场景,以后直播流动越来越多,玩的花色也是越来越多,其实就很适宜用 mongoDB 来做流动业务的数据存储。

2 json 数据格式

mongoDB 的数据存储都是 json 格局,非常适合微服务 Restful Api。

3 横向扩大能力

与 mysql 的分库分表不同,它能够在业务代码不变更的状况下做主动程度扩大。可能很好的解决上文形容的两个场景
① 分表数据不平均
② 分表数据过大要调整原有数据分布。

二、说一说 MongoDB 的分片集群的原理和机制

在正式形容分片集群之前,咱们先看一下以后 MongoDB 的架构部署形式如下图:

从上图咱们能够很清晰的看到罕用的架构模式气氛三种:
1、单机版:只用于开发和测试环境,没有高可用。
2、复制集:个别是一主二从,当然也能够配置更多从库。大部分用户的生产环境在应用,可能满足绝大多数业务场景,且是高可用。
3、分片集群:满足横向扩大能力且高可用。

分片的组成部分

如下图所示:

咱们把上图分为四个模块来讲:

1. 应用程序 + 驱动程序

2. 路由节点(mongos)

路由节点次要是用来管制散发到哪一个分区(shard),因为 mongos 他存储有一个映射表。这个映射表的数据就是 config 节点存储的映射数据同步过去的。个别是在 mongo 启动的时候 load 到 mongos 的内存。

从上图能够看到 mongos 有多个,其实这也是为了满足高可用的场景。

3. 配置节点(config)

数据节点次要存储了集群元数据的存储,数据分布映射关系表。

存储的数据表格局如下图展现:

4. 数据节点(shard)

上图最上面的区域就是分片的数据节点,每一个分片都满足高可用,个别都是一主二从。分片的个数最大能够到 1024 个。所有分片合到一起就是残缺的数据。不存在反复数据。

到此咱们对分片集群的组成部分大略形容完了。

你会不会有这样的疑难?

  1. 配置表里存的数据分布范畴是怎么定的?
  2. mongoDB 的分片集群到底是怎么做数据平衡的?

如果你有其余疑难能够在文末给我留言,在答复下面问题前我先解释几个概念,咱们看下图

如图所示咱们能够看到以下几个名词,分表是集群 > 片 > 块 > 文档。

一个集群是由多个分片组成,一个分片存储了多个块(备注:逻辑上的数据分块),一个块蕴含多个文档。文档不是最小单位,文档里存着一个个字段,一个字段或者多个字段能够组成为一个片键。

片键有什么用?片键决定了你的数据能够分成多少块。

到此基础概念介绍完了,我来答复一下下面的疑难。

对于数据分布,mongoDB 提供了三种形式

a. 基于范畴

如图所示,数据在逻辑上被分成了 4 个块:举个例子你的零碎存的是公司用户信息,如果你按年龄来分,假如公司年龄段在 18-60,且按一个年龄分一个块,那么最大能够分 43 个块。再把块分到多个分片下来。这时咱们查问某一个年龄段的数据,比方 22-25 之间的数据,个别很大可能是在同一个片或者两个片上。故而在范畴查问性能上体现较好。那么问题来了,这时咱们把数据有限放大,公司年龄在 22-25 之间的占比 80 以上,这时咱们会发现 22-25 岁的用户数据所在的片和别的片比起来就很显得特地大,这也就是咱们说的数据分布不平衡的状况。新增数据都是在 22-25 岁之间,这时也就导致了热点片的状况。

b. 基于 hash

如上图所示,片键不是间断的而是通过 hash 散列到不同的片区,这就很好的解决了数据不平均的状况。然而同时带来的问题就是,范畴查问的场景效率特地低,须要遍历全副的分片能力满足业务查问。举个例子用户的订单零碎,咱们依照下单用户 id 去做 hash,这样不同用户的订单数据就会被平均的散布到不同的分片。单查某个用户的订单数据是十分高效的,然而如果去依据工夫范畴去查则要去扫描全副分片。

c. 基于 zone

顾名思义,基于地区去划分。有时候咱们服务的可能是寰球用户,又因其地域性则能够人造的按地区去划分分片。这样很好的保障,在某固定地区能够拜访到最近的数据节点。

到此对于上文中的第一个疑难是否恍然大悟?上面咱们再来答复第二个问题:

简略来说,mongo 他提供了两个程序:

① 切割器

切割器能够对某个源分片的数据按 chunk(数据逻辑块)去做切割。

② 平衡器

当某些分片数据不平均的状况下,平衡器就发挥作用了,他会收回一个命令让切割器去须要挪动的分片下来做数据切割,再把数据挪动到数据少的分片上。具体的步骤如下:

  • 平衡器向源分片发送 moveChunk 的命令
  • 源分片收到命令后,会启动本人外部的一个 moveChunk 命令,如果在数据挪动过程中有客户端发来读写申请的话,都会发送到源分片。(因为配置服务器上的元数据还没有扭转)
  • 指标片开始向源分片申请将要挪动的数据块的文档,筹备拷贝文档数据。
  • 当指标分片接管到据块的最初一个文档后,指标分片会启动一个同步过程来查看, 是否曾经拷贝齐全部的文档。
  • 当同步实现后,指标分片会连贯配置服务器,更新元数据列表中数据块的地址。
  • 当指标分片实现元数据更新后,源分片就会删除原来的数据块. 如果有新的数据块须要挪动的话,能够持续进行挪动。
  • 配置服务器会告诉 monogs 过程更新本人的映射表。

到此咱们对于上文的第二个问题,也做了较为详尽的形容。上面来演绎一下 MongoDB 的分片集群的特点:

  • 利用全透明,无非凡解决

对于开发很敌对,不须要做改变,mongo 架构部署变动不影响业务代码。

  • 数据主动平衡

再也不必放心某个分片过大的状况,然而这里要留神的是你的分块必须要做到不能太大,不然老天也帮不了你。因为太大的话,常常会呈现挪动失败的状况。

  • 动静扩容,毋庸下线

如果以后生产环境是 mongo 复制集的架构,能够在线上环境间接切到分片集群架构。如果你应用阿里云的 mongoDb 服务,阿里提供了两种形式:1 全量切 2 增量切(留神增量切是须要另外付费的)对于用户来说操作很不便。

三、说一说分片集群实用的场景

下面咱们把分片集群的概念,包含组成,实现机制,特点都形容完了。我置信大家也对分片集群有了一个较为残缺的意识。上面咱们聊一聊哪些场景咱们须要思考应用分片集群呢?

1. 数据容量日益增大,拜访性能升高

2. 新品上线异样火爆,如何撑持更多的并发用户

直播打榜流动热火朝天的举办,局部业务数据增量和并发也有显著回升,目前来看无需调整部署策略能够轻松应答,假如这个增量有限陡增,那么就能够思考应用分片集群,以解决数据库性能瓶颈。

3. 单库已有海量数据,出了故障如何疾速复原

这时候咱们须要提前预判危险问题,不能等出了故障再思考应用分片集群。海量数据 (假如数据已达 TB 级别) 去做数据恢复耗时很长。

4. 地理分布

数据起源不同地区,能够思考应用

四、在应用分片集群前须要思考的问题

1、正当的架构,须要思考以下几个问题

问题 1:是否须要分片

这个就须要联合本人的业务场景和以后的架构部署状况去做甄别。能够联合上文提到的实用场景去对号入座。

问题 2: 须要多少分片

这个别须要思考三个维度

① 你预估的业务在将来一年或者某一段时间,存储总量来计算,个别经验之谈 2TB 一个分片

② 依据你业务的最大并发量来计算

③ 依据你的硬件设施条件去掂量

这可能更须要 dba 去做一个评估来决定。

问题 3:数据分布规定

这是十分要害的一点,对于数据分布这个,如果你的数据分布不合理,间接导致你没方法横向扩大、查问效率低等等性能问题

2、应用正确的姿态

① 抉择你须要分片的表

mongo 的分片都是基于表的,这是一个大前提。只对须要做分片的表做分片。

② 抉择正确的片键

上文咱们曾经说过片键的作用,片键间接决定了你数据的分块。上面咱们着重对片键的抉择来论述什么才是正确的片键。

首先咱们须要恪守以下几个准则:

基数要大!

为了基数要大?如果你的根底小,例如上文举的例子,按年龄来分段, 那么你的数据分块最多分几十块,如果你的数据是 10TB,那么你每一块就算均匀散布每一块的数据就要几百 GB,这么大的块,是很难挪动的,间接导致平衡策略生效。

保障散布平均

为什么要保障散布平均,如果不平均咱们会呈现什么状况?

a、导致热片产生(能够回顾一下上文讲分片数据分布形式时候提的例子)

b、导致分片数据常常大小差别大,频繁进行数据平衡

要保障定向查问好

好的架构都是服务于业务的,如果你的某些查问业务比拟多,你必定不心愿你每次查问都要遍历所有的分片吧。

所以咱们须要尽可能让本人查问的数据落在同一个分片上。

3、咱们通过两个业务场景来聊聊

① 商家订单零碎

业务形容:假如平台每日下单量在百万级,不同商家须要常常统计不同周期的订单数据

针对这一业务场景,咱们依照下面思考的步骤考虑一下?

思考步骤一:要不要用分片?

答复:能够应用,因为数据量十分大,而且查问统计很频繁。

思考步骤二:应用什么做片键最合适?

答复:联合选片键的准则,最佳为商家 id 和下单工夫。如果只用商家 id 做片键,他确实满足基数够大,另外数据平均也没问题,然而查问某段间断工夫内的订单须要遍历所有的分片。所以要抉择商家 id 和下单工夫的组合片键,这样能力保障定向查问。

② 直播打赏记录

业务形容:  记录用户给主播打赏数据,,假如打赏记录日增百万,只存在查问近期数据

从业务形容来剖析,这个日志的历史数据没有查问的必要其实咱们能够对历史数据做归档解决。无需思考应用分片集群。

四、小结

看齐全文,我置信你们对于分片集群都有了肯定的意识。在工作中针对某些业务场景心愿能给你提供一个多的抉择。最初我终结两点:

  1. 分片集群能够无效解决性能瓶颈及零碎扩容问题
  2. 分片治理简单,老本高,能不分片尽量不必

文 / 荣荣
关注得物技术,带你走向技术的云端

退出移动版