MongoDB的一大特色就在于其原生的横向扩展能力,具体体现就是分片集。本篇,我们来了解一下MongoDB分片集的机制及其原理。

1 为什么要分片?

我们都知道,在关系型数据库如MySQL中,当数据量过大造成事务执行缓慢的时候,减少每次查询数据总量是解决之道。因为,数据量一旦过大,索引也会相应增大,这时对索引的维护成本也会增加,进而降低事务执行性能。这时,我们的总体解决思路一般都是 分表。

在MongoDB中,当数据容量日益增大访问性能日渐降低时,单库已有巨大数据量如10TB时,我们的解决思路其实也是 分表,只不过在MongoDB中,这叫 分片集。

分片集是MongoDB提供的一个原生的横向扩展能力,无需引入其他的中间件就可以轻松实现。

未分片:

两个分片集:

当使用分片之后,单个分片集的数据量就有了限制,从而保证了查询的性能。更为重要的是,增加一个分片,使用的时间可控,这就为横向扩展提供了良好的基础。

2 引入分片集的部署架构

首先,我们来看看MongoDB常见部署的架构,如下图所示:

可以看到,MongoDB可以单机运行、可以复制集运行 也可以 分片集群运行。复制集可以保证数据的高可用,而分片集群则可以保证横向扩展性。

其次,我们来看看一个完整分片集群到底长什么样,它如下图所示:

从上图所知,整个分片集群会包括如下几个组成部分:

(1)mongos

mongos是路由节点,它承上启下,作为mongodb集群的单一入口,它主要转发应用程序端的请求 并 选择合适的数据节点进行读写,最后合并多个数据节点的返回。mongos是无状态的,一般建议至少部署两个节点,推荐三个。

(2)config

config是配置(目录)节点,你可以理解为它存储了如何分片的规则,这些规则就是元数据,类似于下表所示的数据:

(3)replica set 复制集

复制集节点就是最终的数据存储节点了,以复制集为单位,横向扩展。MongoDB允许最大有1024个分片,每个分片的数据不重复,所有分片在一起才可以完整工作。在实际应用场景中,最佳实践是每个分片的数据量尽量不超过3TB,尽可能保持在2TB内一个分片,可以提供最佳的读写性能。

这里再介绍一下,一个分片集群内部到底包含哪些东西?

一个集群(Cluster)包括多个分片(Shard),每个分片包含多个块(Chunk),每个块包含多个文档(Document),每个文档包含了一行含有片键(Shard Key)的数据,而这个片键就是文档中的一个用来进行分片的字段。

最后,MongoDB分片集群到底有什么特点?

(1)对于应用程序端,它完全透明,不需要额外的特殊处理,只需要对接mongos节点就行。

(2)mongos对数据自动均衡,应用程序端不需要像Memcached一样做客户端负载均衡。

(3)分片集可以做到动态扩容,无须对已有MongoDB服务下线。

因此,基于分片集的这些机制和特点,建议生产环境尽量使用分片集群,当然前提是你有足够的硬件资源如CPU、内存 和 磁盘。

3 分片集的数据分布策略

MongoDB分片集提供了三种数据分布的策略:

(1)基于范围(Range)

(2)基于哈希(Hash)

(3)基于zone/tag

基于范围分片

首先,基于范围的数据分片很好理解,通常会按照某个字段如创建日期来区分不同范围的数据存储。

其优点是分片范围的查询性能足够好,缺点是存在热点数据问题,数据的分布可能会不够均匀。

基于哈希分片

其次,基于Hash的分片策略也比较好理解,通常会按照某个字段的哈希值来确定数据存储的位置。

其优点是数据的分布会比较均匀,缺点则是范围查询的效率会较低,因为可能会涉及在多个节点读取数据并聚合。

基于Zone/Tag分片

最后,基于zone/tag的数据分片则有点不太好理解,它不是一般我们所熟知的分片方式。所谓基于zone/tag的数据分片,一般是指在两地三中心或异地多活的应用场景中,如果数据存在地域性的访问需求,那么就可以自定义Zone来进行分片。

通过打tag的方式,可以实现将为某个地域服务的数据存储到指定地域的数据分片上(比如CountryCode=NewYork),最终实现本地读和本地写的目的。

4 分片集群的搭建

由于MongoDB分片集群的搭建偏运维,我这里就不做实践了。

网上有很多相关的操作指南,有兴趣的童鞋也可以看看这篇:MongoDB 4.4.1 分片集搭建

5 总结

本文简单介绍了MongoDB分片集的机制及原理,最后介绍了MongoDB数据分片的三种基本策略。

下一篇,我们会总结MongoDB应用开发的最佳实践,它也会是本系列的最后一篇文章。

参考资料

唐建法,《MongoDB高手课》(极客时间)

郭远威,《MongoDB实战指南》(图书)

△推荐订阅学习

作者:周旭龙

出处:https://edisonchou.cnblogs.com

本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文链接。

MongoDB入门实战教程(13)的更多相关文章

  1. MVC5+EF6 入门完整教程13 -- 动态生成多级菜单

    稍微有一定复杂性的系统,多级菜单都是一个必备组件. 本篇专题讲述如何生成动态多级菜单的通用做法. 我们不用任何第三方的组件,完全自己构建灵活通用的多级菜单. 需要达成的效果:容易复用,可以根据mode ...

  2. duilib教程之duilib入门简明教程13.复杂控件介绍

    首先将本节要介绍的控件全部拖到界面上,并调整好位置,如图:  然后将Name属性改成其他名字,         不能是[控件名+UI+数字]这种,因为这是DuiDesigner默认的名字,它不会实际写 ...

  3. Kafka入门实战教程(7):Kafka Streams

    1 关于流处理 流处理平台(Streaming Systems)是处理无限数据集(Unbounded Dataset)的数据处理引擎,而流处理是与批处理(Batch Processing)相对应的.所 ...

  4. ZooKeeper入门实战教程(一)-介绍与核心概念

    1.ZooKeeper介绍与核心概念1.1 简介ZooKeeper最为主要的使用场景,是作为分布式系统的分布式协同服务.在学习zookeeper之前,先要对分布式系统的概念有所了解,否则你将完全不知道 ...

  5. Node+Express+MongoDB+Socket.io搭建实时聊天应用实战教程(一)--MongoDB入门

    前言 本文并不是网上流传的多少天学会MongoDB那种全面的教程,而意在总结这几天使用MongoDB的心得,给出一个完整的Node+Express+MongoDB+Socket.io搭建实时聊天应用实 ...

  6. MongoDB入门必读(概念与实战并重)

    MongoDB入门必读(概念与实战并重) 一.概述 MongoDB是一个基于分布式文件存储的数据库开源项目.由C++语言编写.旨在为WEB应用提供可护展的高性能数据存储解决方案. MongoDB是一个 ...

  7. Node+Express+MongoDB + Socket.io搭建实时聊天应用实战教程(二)--node解析与环境搭建

    前言 本来开始写博客的时候只是想写一下关于MongoDB的使用总结的,后来觉得还不如干脆写一个node项目实战教程实战.写教程一方面在自己写的过程中需要考虑更多的东西,另一方面希望能对node入门者有 ...

  8. mybatis实战教程(mybatis in action),mybatis入门到精通

    转自:http://www.yihaomen.com/article/java/302.htm (读者注:其实这个应该叫做很基础的入门一下下,如果你看过hibernate了那这个就非常的简单) (再加 ...

  9. mybatis实战教程(mybatis in action),mybatis入门到精通(转)

    转自:http://www.yihaomen.com/article/java/302.htm (读者注:其实这个应该叫做很基础的入门一下下,如果你看过Hibernate了那这个就非常的简单) (再加 ...

  10. mongodb入门教程二

    title: mongodb入门教程二 date: 2016-04-07 10:33:02 tags: --- 上一篇文章说了mongodb最基本的东西,这边博文就在深入一点,说一下mongo的一些高 ...

随机推荐

  1. 【Linux】3.10 进程管理(重点)

    进程管理 1. 进程管理基础 在Linux中,每个执行的程序(代码)都称为一个进程.每个进程都分配一个ID号 每一个进程,都会对应一个父进程,而这个父进程可以复制多个子进程.例如www服务器. 每个进 ...

  2. CoreOS 更新重启后, 所有容器服务全部停掉了

    今天有几个服务出问题了,上去看了下,这台 CoreOS 下的所有容器服务竟然全部停掉了,好奇怪,启动容器时明明加了--detach参数了呀. 问题原因 想了想,会不是是 CoreOS 更新重启导致的, ...

  3. 生命游戏Delphi实现

    生命游戏,康威生命游戏(Game of Life),剑桥大学约翰·何顿·康威设计的计算机程序. 生命游戏没有游戏玩家各方之间的竞争,也谈不上输赢,可以把它归类为仿真游戏.事实上,也是因为它模拟和显示的 ...

  4. nodejs读写json文件

    读json文件 'use strict'; const fs = require('fs'); let rawdata = fs.readFileSync('student.json'); let s ...

  5. Codeforces Round 971 (Div. 4)

    C. The Legend of Freya the Frog 因为是从x开始跳,贪心的取肯定是直接用max(a,b)/d向上取整然后再乘2,但是要注意,如果再x到达之前,y已经是到达了,也就是某次以 ...

  6. SpringSecurity5(14-Gateway整合)

    MVC 与 WebFlux 关系 SpringSecurity 设置要采用响应式配置,基于 WebFlux 中 WebFilter 实现,与 Spring MVC 的 Security 是通过 Ser ...

  7. ESP32+Arduino入门(四):OLED屏随机显示古诗

    前言 我觉得去做一些简单又好玩的案例是入门很好的选择. 在实践的过程中会碰到很多需求很多问题在解决这些需求这些问题的过程就是在学习的过程. 今天我来分享一个随机显示古诗的案例,如果对此感兴趣可以跟我一 ...

  8. Windows开机执行bat脚本

    1.编写好bat脚本 2.将脚本复制到: C:\ProgramData\Microsoft\Windows\Start Menu\Programs\StartUp

  9. JAVA 线程实现/创建方式

    每天记录一个知识点: 概要: java创建线程的方式: 继承Thread类 实现Runnable接口 通过Callable和Future创建线程 基于线程池的方式 java创建线程池的四种方式: ne ...

  10. python爬虫,beatifulsop获取标签属性值(取值)案例

    前面的案例里,均采用正则匹配的方式取值 title = re.findall('">(.*?)</a>', i, re.S)[0]#标题 url = re.findall( ...