MongoDB的分片集群(一) : 基础知识

转载说明:如果您喜欢这篇文章并打算转载它,请私信作者取得授权。感谢您喜爱本文,请文明转载,谢谢。


 

目录导读

1. 什么是MongoDB分片
2. MongoDB分片集群介绍
    2.1 MongoDB分片集群架构
    2.2 MongoDB分片集群优势
3. 分片键的选择
    3.1 选择基数大的分片键
    3.2 选择分布均匀的分片键
    3.3 避免单调增加或减少的分片
    3.4 分片键涵盖最常用的查询模式
4. 分片的策略
    4.1 哈希分片
    4.2 范围分片(远程分片)
    4.3 分区分片
5. 分片前的注意事项

1. 什么是MongoDB分片

分片是一种将数据分布在多个机器,MongoDB使用分片来支持具有非常大数据的部署集和高吞吐量操作。

具有大型数据集或高吞吐量应用程序的数据库系统会给单个服务器的容量带来挑战。例如,高查询率可以耗尽服务器的 CPU 容量;工作集大小大于系统的 RAM 会给磁盘驱动器的 I/O 容量带来压力。
有两种方法可以解决系统增长问题:垂直和水平缩放。
垂直扩展:增加单个服务器的容量,例如 如使用更强大的 CPU、添加更多 RAM 或增加 存储空间。但单个服务器的CPU、RAM终有天花板值,不能无限扩张。因此,垂直缩放有一个实际最大值。
水平扩展:划分系统数据集并加载多台服务器,根据需要增加服务器节点数量以增加容量。虽然单台机器的整体速度或容量可能不高,但每台机器处理整体工作负载的子集,可能提供更好的比单个高速高容量服务器的效率。扩展部署容量只需要根据需要添加额外的服务器, 这可能比单台机器的高端硬件更低的总成本。代价是基础设施和维护的复杂性增加部署。

2. MongoDB分片集群介绍

2.1 MongoDB分片集群架构

一个MongoDB分片集群由以下组件组成:

shard每个分片包含一个分片数据的子集。每个分片都可以部署为副本集。

mongos:查询路由器,是个无状态应用。负责接收客户端的请求并将其路由到正确的分片上,进行读写合并多个数据节点的返回。本身不存储数据,也不维护任何与客户数据相关的状态信息。建议部署2个及以上节点。从MongoDB4.4开始,可以支持hedged reads 以最大程度地减少延迟。

config servers:confi服务器负责存储和管理分片集群的元数据信息,如分片键范围、分片集群配置等。官方建议最少部署3个config服务器且部署为副本集。另外,因投票选举机制,config服务器数量建议为奇数。

hedged reads技术是一种优化读取操作的方式,以最小化延迟。hedged reads技术是通过同时向多个分片服务器发出查询请求,然后使用最先返回结果的服务器来响应查询请求,从而实现最小化延迟的。这种技术通常用于高负载的环境中,以提高查询性能和响应时间。

MongoDB在collection级别对数据进行分片,通过集群中的分片分发collection数据。

2.2 MongoDB分片集群优势

1)读写

MongoDB 在分片集群中的分片之间分配读写工作负载,允许每个分片处理集群操作的子集。读取和写入工作负载都可以通过添加更多分片在集群中水平扩展。

对于包含shard key或复合shard key前缀的查询,mongos可以针对特定的shard或shard集合进行查询。这些有针对性的操作通常比广播到集群中的每个分片更有效。

从MongoDB4.4开始,可以支持hedged reads 以最大程度地减少延迟。

2)存储容量

分片将数据分布在集群中的多个分片上,允许每个分片包含集群总数据的一个子集。随着数据集的增长,额外的分片会增加集群的存储容量。

3)高可用性

config server服务器和副本集式部署的分片提供了高可用性:

即使一个或多个分片复制集完全不可用,分片集群也可以继续执行部分读写操作。也就是说,当不可用分片上的数据不能被访问时,对可用分片的读写仍然可以成功。

注意:不是所有的集群都适用于分片集群。比如数据量小的场景,就完全没必要用分片集群了

3. 分片键的选择

MongoDB 使用分片键来跨分片分发collection的文档。分片键由文档中的一个或多个字段组成。

在版本 4.2 及更早版本中,分片集合的每个文档中都必须存在分片键字段。

从版本 4.4 开始,分片集合中的文档可以是缺少分片键字段。在跨分片分布文档时,缺少的分片键字段将被视为具有空值,但在路由查询时则不被视为具有空值。

例如一条分片语句:

sh.shardCollection("your_database_name.your_collection_name", { "shard_key": "hashed" })
#如:
sh.shardCollection("dbtest.collectiontest", { "shard_key": "hashed" })

选择分片键(shard_key)要考虑的几个因素:

分片键的基数;

分片键值出现的频率,尽可能被更多的业务场景使用;

潜在的分片键是否单调增长/减小;

分片查询模式;

Shard Key限制;

在对集合进行分片时,选择合适的分片键:

在 MongoDB 4.2 及更早版本中,一旦对一个集合进行了分片,那么分片键的选择是不可变的。

从 MongoDB 4.4 开始,可以通过refineCollectionShardKey命令来优化分片键;通过refineCollectionShardKey命令向现有键添加一个或多个后缀字段,以创建新的分片键。

从MongoDB 5.0开始,可以通过使用reshardCollection命令更改分片键来重新分片collection。

文档的分片键value值决定了它在分片中的分布

在MongoDB 4.0及更早版本中,文档的分片键字段value值是不可变的。

从MongoDB 4.2开始,可以更新文档的分片键value值,除非使用的分片键字段是不可变的_id字段。

3.1 选择基数大的分片键

几个概念及关系:

1)集群 Cluster: 一个cluster 包含 n 个shard

2)分片 Shard:一个shard 包含 n 个 chunk

3)块 Chunk :一个chunk 包含 n 个doc

4)文档 doc :一个doc包含一个 shard key,该值决定了文档所属的Chunk及存储该文档的Shard。

5)分片键 shard key:文档中的一个字段

在任何给定时间,每个唯一的shard键值只能存在于一个块中。分片键的基数决定了平衡器可以创建的最大块数量。因为备选值有限,那么块的总数量就有限,随着数据增多,块的大小会越来越大,水平扩展时移动块会非常困难。因此,建议选择基数大的分片键。如果当前的数据模型需要对基数低的键进行分片,可考虑使用索引复合字段来增加基数。

例如:

如果根据性别来进行分片,则分片的基数为2。基数为2意味着在分片集群中不能有超过2个块(chunk),每个块存储一个唯一的分片键值。这也将集群中有效分片的数量限制在2个,添加更多的分片也不会带来更多的效用。

选择基数小的分片键,插入数据可能会产生这种效果:

3.2 选择分布均匀的分片键

分片键的频率代表了给定的分片键值在数据中出现的频率。如果这个频率分布不均匀,存储具有这些值的文档的块的数据量可能会急剧增大,这些块的压力随之增大。而数据均衡又以 chunk 为单位,这些压力巨大的chunk没有办法被别的chunk分担,所以可能成为集群中的瓶颈。

因此建议选择在数据中出现频率分布均匀的分片键。如果当前的数据模型需要对具有高频次出现的键进行分片,可考虑使用使用唯一值或低频值的复合索引。

例如:

存储一个城市所有小学5年级学生的数据,数据范围是9-16岁,以年龄整数进行分片,分片基数为8,有8个chunk。但根据我国小学入学条件规定,大部分小学五年级学生的年龄绝大部分集中在10岁和11岁,就会导致10岁的chunk和11岁的chunk的读写压力增大,成为瓶颈。而别的chunk可能一个数据都没有,没有读写压力。

选择频率出现高低不均的分片键,插入数据可能会产生这种效果:

3.3 避免单调增加或减少的分片键

分片键避免使用单调增加或减少的分片键。如果当前数据模型需要对单调变化的键进行分片,可考虑使用哈希分片。

一个值单调增加或减少的分片键更有可能将写入的数据分发到集群中的单个块上。

这是因为每个集群都有一个块,它捕获一个具有maxKey上限的范围。maxKey总是比所有其他值高。类似地,有一个块捕获minKey下界的范围。minKey总是比所有其他值低。

如果分片键值一直在增加,那么所有新的插入数据都将以maxKey为上界路由到捕获maxKey上限的块中。如果分片键值一直在减小,那么所有新的插入数据都将以minKey作为下界路由到捕获minKey下界的块中。包含该块的分片就将成为写入操作的瓶颈。

为了优化数据分布,包含全局maxKey(或minKey)的块不会留在同一个分片上。当分割块时,具有maxKey(或minKey)块的新块位于不同的分片上。

下图展示了一个使用字段X作为分片键的分片集群。如果X的值单调增加或减小的场景下,则插入的分布可能类似于以下情况:

3.4 分片键涵盖最常用的查询模式

理想的分片键在整个分片集群中均匀分布数据,同时还支持通用查询模式。因此在选择分片键时,先考虑整个数据集中最常见的查询模式有哪些,给定的分片键是否涵盖了这些模式。

在分片集群中,如果查询包含shard key, mongos只会将查询路由到包含相关数据的shard。当查询不包含分片键时,查询将广播到所有分片进行评估。这些类型的查询称为分散-收集查询。对于每个请求涉及多个分片的查询效率较低,并且当向集群添加更多分片时不能线性扩展。这不适用于对大量数据进行操作的聚合查询。

在某些特殊情况下,分散-收集可能是一种有用的方法,它允许查询在所有分片上并行运行。

4. 分片的策略

MongoDB支持两种分片策略,用于跨分片集群分发数据。

4.1 哈希分片

哈希分片将数据通过哈希函数计算得到哈希值,然后根据哈希值为每个块分配一个范围。MongoDB在使用哈希索引解析查询时自动计算哈希值。应用程序不需要计算哈希值。

基于哈希值的分片有助于更均匀的进行数据分布,特别是在分片键单调变化的数据集中。比较适用于高并发场景。

然而,哈希分布意味着对分片键的查询不太可能针对单个分片,而是在更多的集群范围内进行广播操作,降低查询操作效率。

4.2 范围分片(远程分片)

范围分片(远程分片)根据分片键值将数据划分为不同的范围。然后根据分片键值为每个块分配一个范围:

一组分片键值接近的分片键更有可能分配在同一个块上。这就允许有某些针对性的操作,因为mongos可以将操作路由到包含所需数据的分片。

范围分片的效率取决于所选择的分片键。范围分片将数据按指定的范围进行划分,使得在进行范围查询时能够只在涉及的分片上执行查询操作,不需要访问整个分片集群,减少了数据在网络中的传输,提高了范围查询的性能。

但考虑不当的分片键可能导致数据分布不均匀,容易出现热点,可能导致性能瓶颈。

4.3 分区分片

分片集群跨多个数据中心时,区域可以帮助提高数据的本地性。

在分片集群中,可以根据shard key创建分片数据分区。可以将每个分区与集群中的一个或多个分片关联,一个shard可以与任意数量的zone相关联。

在balance集群时,MongoDB只会将一个区域覆盖的块迁移到与该区域关联的那些分片上。

每个区域包含一个或多个分片键值范围。一个区域覆盖的每一个范围总是包括它的下边界而不包括它的上边界。

5. 分片前的注意事项

分片集群基础设施的需求和复杂性需要仔细规划、执行和维护。如分片集群架构、服务器数量、配置等相关事项。

一旦对一个集合进行了分片,MongoDB目前没有任何方法来对这个被分片的集合进行反分片。虽然可以重新对集合进行切分,但务必仔细考虑切分键的选择,以避免出现可伸缩性和性能问题。

一个数据库(如db:test)可以混合使用分片集合(collection)和非分片集合(collection)。分片集合(collection)在集群中的多个分片之间进行分区和分布。未分片的集合(collection)存储在主分片上。每个数据库都有自己的主分片。

连接到分片集群:

连接到mongod的方式有两种:通过mongosh连接或者MongoDB驱动连接。这两种方式同样适用于连接到mongos。

以上即MongoDB分片集群的简要梳理总结。

参考文档:Sharding — MongoDB Manual

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/366715.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

排序(5)——归并排序

六、归并排序 1.简介 归并排序也是一种很经典的排序算法,采用分治的思想方法进行数据的处理。归并讲究的是先拆后合,也就是分治中的分而治之。在拿到一组数据后,程序会将整个数据进行不断拆分直至有序,因为单个元素必然有序&…

【类和对象】4

日期类的拓展 c语言中的printf函数只能打印内置类型&#xff0c;为了弥补这一不足&#xff0c;c利用运算符重载可以打印自定义类型。 void operator<<(ostream&out);//声明在date.h中void Date::operator<<(ostream& out)//定义在date.cpp中 {out<<…

Flutter解析后台发来的jwt字段数据,了解jwt是否过期

前言 了解JWT是什么可以看这一篇博文 JWT&#xff08;JSON Web Token&#xff09;详解以及在go-zero中配置的方法-CSDN博客 流程 采用jwt_decoder库 添加至pubspec.yaml jwt_decoder: ^2.0.1 解析字段 查看是否过期 获取过期时间和token颁发的年龄

PythonStudio 控件使用常用方式(五)TListBox

PythonStudio是一个极强的开发Python的IDE工具&#xff0c;它使用的是Delphi的控件&#xff0c;常用的内容是与Delphi一致的。但是相关文档并一定完整。现在我试试能否逐步把它的控件常用用法写一点点&#xff0c;也作为PythonStudio的参考。 TListBox是列表框 常用属性 col…

【操作系统·考研】I/O管理概述

1.I/O设备 1.1 块设备 信息交换以数据块为单位&#xff0c;它属于有结构设备。 块设备传输速率较高&#xff0c;可寻址&#xff0c;且可对该设备随机地的读写。 栗子&#x1f330;&#xff1a;磁盘。 1.2 字符设备 信息交换以字符为单位&#xff0c;属于无结构类型。 字符…

LabVIEW叶片厚度远程监控

LabVIEW叶片厚度远程监控 随着网络技术的高速发展&#xff0c;远程监控广泛应用在各个领域。本文介绍了一种基于LabVIEW的植物叶片厚度远程监控系统&#xff0c;旨在实现对植物生长状况的精准监测和分析。 该系统利用LabVIEW软件开发工具&#xff0c;通过TCP网络协议实现数据…

关于反爬虫的的概述

目录 前言 一、验证码验证 二、IP限制 三、User-Agent限制 四、动态页面加载 总结 前言 反爬虫是一种防止网站被自动程序&#xff08;爬虫&#xff09;访问和抓取数据的技术手段。在网络爬虫的发展和使用过程中&#xff0c;有一部分爬虫是用于非法获取网站数据、侵犯隐私…

删除有序数组中的重复项 II[中等]

优质博文&#xff1a;IT-BLOG-CN 一、题目 给你一个有序数组nums&#xff0c;请你原地删除重复出现的元素&#xff0c;使得出现次数超过两次的元素只出现两次 &#xff0c;返回删除后数组的新长度。不要使用额外的数组空间&#xff0c;你必须在原地修改输入数组并在使用O(1)额…

Java基于SpringBoot+Vue的美容院管理系统,附源码,文档

博主介绍&#xff1a;✌程序员徐师兄、7年大厂程序员经历。全网粉丝12w、csdn博客专家、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精彩专栏推荐订阅&#x1f447;…

20240202在Ubuntu20.04.6下使用whisper.cpp的显卡模式

20240202在Ubuntu20.04.6下使用whisper.cpp的显卡模式 2024/2/2 19:43 【结论&#xff1a;在Ubuntu20.04.6下&#xff0c;确认large模式识别7分钟中文视频&#xff0c;需要356447.78 ms&#xff0c;也就是356.5秒&#xff0c;需要大概5分钟&#xff01;效率太差&#xff01;】 …

electron项目在内网环境的linux环境下进行打包

Linux需要的文件: electron-v13.0.0-linux-x64.zip appimage-12.0.1.7z snap-template-electron-4.0-1-amd64.tar.7z 下载慢或者下载失败的情况可以手动下载以上electron文件复制到指定文件夹下&#xff1a; 1.electron-v13.0.0-linux-x64.zip 复制到~/.cache/electron/目录下…

web前端--------渐变和过渡

线性渐变&#xff0c;是指颜色沿一条直线进行渐变&#xff0c;例如从上到下、从左到右。 当然&#xff0c;CSS中也支持使用角度来设置渐变的方向&#xff0c;角度单位为deg。 0deg&#xff0c;为12点钟方向&#xff0c;表示从下到上渐变。 90deg&#xff0c;为3点钟方向&…

海外社媒营销平台及运营规则,如何降低封号率?

社交媒体已经成为人们生活和日常习惯不可或缺的一部分&#xff0c;在跨境电商出海过程中&#xff0c;海外社媒营销平台可以起到非凡的助力&#xff1b;而平台的选择以及平台的运营技巧、规则都各有不同。很多海外社媒工作者经常会被封号&#xff0c;这也是难度之一&#xff0c;…

吸猫毛空气净化器哪个好?推荐除猫毛效果好的宠物空气净化器品牌

如今&#xff0c;越来越多的家庭选择养宠物&#xff0c;使家庭变得更加温馨。然而&#xff0c;养宠物可能会带来异味和空气中的毛发增多&#xff0c;这可能会成为一大困扰&#xff0c;并对健康造成问题。 为了不让家里充斥着异味&#xff0c;特别是来自宠物便便的味道&#xf…

无人零售模式下,“IoT+鸿蒙”实现零代码搭建自动售货机监控大屏的可能性摸索

前言 新零售模式下&#xff0c;对loT的探索与应用还在继续。 而数字时代&#xff0c;数字化转型在零售行业中蔓延&#xff0c;而对于新的消费方式的探索&#xff0c;也在如火如荼的进行中。于是&#xff0c;一种新零售的形式——无人零售逐渐形成概念。 如果说&#xff0c;人…

微信小程序新手入门教程二:认识JSON配置文件

在上一篇我们介绍了微信小程序的注册和基本使用方式&#xff0c;并且写出了一个简单的页面&#xff0c;但是依然没有解释目录中的各种.json文件是做什么的。这篇我们就来认识一下各种JSON配置文件及其配置项。 一 认识JSON 首先先来认识一下JSON是什么。 JSON 指的是 JavaScri…

25.泛型

泛型 1.泛型1.1 概述1.2 代码示例 2. 泛型类2.1 概述2.2 代码示例 3. 泛型方法3.1 概述3.2 代码示例 4. 泛型接口4.1 概述4.2 代码示例 5. 泛型特点5.1 概述5.2 代码示例 6. 泛型通配符6.1 概述6.2 代码示例 7. 综合案例8. 注意事项 1.泛型 泛型是Java编程语言的一项重要功能&…

故障诊断 | 一文解决,CNN-LSTM卷积神经网络-长短期记忆神经网络组合模型的故障诊断(Matlab)

效果一览 文章概述 故障诊断 | 一文解决,CNN-LSTM卷积神经网络-长短期记忆神经网络组合模型的故障诊断(Matlab) 模型描述 CNN-LSTM模型是一种结合了卷积神经网络(Convolutional Neural Network)和长短期记忆神经网络(Long Short-Term Memory)的组合模型,常用于数据故障…

FPGA解码MIPI视频:Xilinx Artix7-35T低端FPGA,基于MIPI CSI-2 RX Subsystem架构实现,提供工程源码和技术支持

目录 1、前言免责声明 2、相关方案推荐我这里已有的 MIPI 编解码方案本方案在Xilinx Artix7-100T上解码MIPI视频的应用本方案在Xilinx Kintex7上解码MIPI视频的应用本方案在Xilinx Zynq7000上解码MIPI视频的应用本方案在Xilinx Zynq UltraScale上解码MIPI视频的应用纯VHDL代码解…

vite和vue-cli实现原理和优化及区别

Vite&#xff1a; 1. 实现原理&#xff1a; Vite 是一个基于 ESModule 的构建工具。它利用原生 ESModule 的特性&#xff0c;将每个文件作为一个模块&#xff0c;通过浏览器去解析和执行&#xff0c;而不需要提前将文件打包成一个单独的 bundle。Vite 利用浏览器的原生 ESMod…