Sharding 分片

Sharding 分片

分片机制的概念

Sharding is a method for distributing data across multiple machines. MongoDB uses sharding to support deployments with very large data sets and high throughput operations.

  1. 分片(Shard)
    • 每个分片(Shard)是 MongoDB 的一个节点或副本集,存储部分数据。所有分片组合在一起形成一个逻辑数据库。
    • 数据分片的好处是可以分布存储,减轻单个节点的存储压力,同时通过分布式并行处理提高查询性能。
  2. 分片键(Shard Key)
    • 分片键是指定数据如何分配到各分片的依据。
    • 分片键可以是一个字段或多个字段的组合,要求能有效地划分数据,保持分片间负载均衡。(分片集1:2w,分片集2:2w)
    • 常见分片策略:
      • 范围分片(Range Sharding):基于分片键值的范围进行划分。
      • 哈希分片(Hash Sharding):基于分片键值的哈希结果进行划分。
  3. 数据块(Chunk)
    • 数据块是分片机制中的基本存储单元,一个 Chunk 包含一定范围的数据记录。64MB
    • MongoDB 会动态监控 Chunk 的大小并在必要时进行 分裂迁移,以保持分片数据的均衡分布。
  4. 配置服务器(Config Server)
    • 配置服务器存储分片集的元数据,包括每个分片的 Chunk 分布信息。
    • 路由服务器(Mongos)依赖配置服务器提供的元数据来确定客户端请求应该路由到哪个分片。
  5. 路由服务器(Mongos)
    • 路由服务器是客户端与分片集交互的入口。它将客户端的查询请求路由到正确的分片。
    • 客户端只与 Mongos 交互,因此分片的分布对客户端透明。
MongoDB 中 Sharding 的优势

线性扩展性

  • 通过增加分片节点,可以轻松扩展存储容量和查询吞吐量。

  • 数据分布到不同的机器

    注意与Replication的不同,复制是生成副本,每一份都是完整的;分片是将一份数据分解成多个部分。

  • 拆分大数据集(横向容量扩展)

  • 分散负载压力(横向性能扩展)

负载均衡

  • 数据和查询请求可以分散到不同分片上,避免单点压力,提高系统的整体性能。

大数据支持

  • 单个 MongoDB 实例的存储受限于磁盘和内存,通过分片,MongoDB 可以轻松存储 PB 级数据。

高可用性

每个分片通常是一个副本集,具有数据冗余能力,在某个分片故障时仍能提供服务。

Sharding 的常见使用场景
  1. 数据量极大,单节点存储不足:如社交媒体、电子商务中用户或商品数据的存储。
  2. 高并发读写请求:如实时在线服务、日志分析系统等。
  3. 需要动态扩展的业务场景:如数据快速增长的企业。

通过 Sharding,MongoDB 实现了大规模分布式存储和高效处理能力,是 NoSQL 数据库架构中的重要组成部分。

为什么要采用分片集群?

  1. 水平扩展性:通过分片,可以将数据分散存储到多个节点上,从而提高系统容量。随着数据量的增加,可以简单地通过增加新的分片来扩展集群,而不需要对现有数据进行大规模迁移。
  2. 性能提升:分片集群可以将读写请求分担到多个节点上,减少单个节点的负载。因此,当有大量并发访问时,整体性能会得到显著提高。
  3. 高可用性:在分片集群中,通常每个分片可以有多个副本,这样即使某个节点出现故障,系统仍然可以正常工作,保证数据的高可用性。
  4. 数据管理灵活性:分片允许开发者根据不同的业务需求和数据结构选择合适的分片策略,例如按范围分片、哈希分片或地理位置分片,这样可以优化数据分布和查询性能。
  5. 降低单点故障风险:通过将数据分散在多个节点上,分片集群有效降低了单点故障的风险,提高了系统的可靠性。
  6. 更好的资源利用:分片集群可以根据负载动态调整资源,确保计算和存储资源得到更高效的利用。

分片集群的架构

  1. Shard (分片)= Sharded ReplcaSet (分片集)

    由副本集构成的一组存放分片数据的节点

  2. Config Server (配置集)

    由副本集构成的一组存放分片元数据的节点,即存放数据是如何分片的元数据的节点

  3. Router (Mongos) 路由节点

    访问一个分片集集群的路由服务器,作为客户端访问的接口。Router从Config Server中读取数据分片的信息来代理客户访问后台Shard上的数据。

1.从零搭建分片集群

  1. 规划图

2.规划表(由于一个分片集群包含的节点较多,创建之前我们可以进行规划)

3.配置环境变量,创建9台服务器实例(server1~server9)

REM 0.配置环境变量(根据实际环境配置)
SET MONGOD_CMD=C:\mongodb4\bin\mongod.exe
SET MONGOS_CMD=C:\mongodb4\bin\mongos.exe
SET MONGO_CMD=C:\mongodb4\bin\mongo.exeREM 1.创建9台服务器实例(server1~server9)
mkdir server1 server2 server3 server4 server5 server6 server7 server8 server9

4.编写9台服务器的启动配置文件:手动完成server1.ini~server9.ini

#server1.ini
dbpath=.\server1
bind_ip=127.0.0.1
port=27011
logpath=.\server1\mongod.log
logappend=true
replSet=rs0
shardsvr=true
#server2.ini
#server3.ini#server4.ini
dbpath=.\server4
bind_ip=127.0.0.1
port=27014
logpath=.\server4\mongod.log
logappend=true
replSet=rs1
shardsvr=true
#server5.ini
#server6.ini#server7.ini
bind_ip=0.0.0.0
port=27017
logpath=.\server7\mongos.log
logappend=true
configdb=cfg0/127.0.0.1:27018,127.0.0.1:27019
#configdb参数可以通过mongo --help查看#server8.ini
dbpath=.\server8
bind_ip=127.0.0.1
port=27018
logpath=.\server8\mongod.log
logappend=true
replSet=cfg0
configsvr=true
#server9.ini

5.启动配置集、分片集的副本集实例

REM 配置集 cfg0
start "cfg0:server8:27018" %MONGOD_CMD% --config=.\server8.ini
start "cfg0:server9:27019" %MONGOD_CMD% --config=.\server9.ini
REM 分片集1 rs0
start "rs0:server1:27011" %MONGOD_CMD% --config=.\server1.ini
start "rs0:server2:27012" %MONGOD_CMD% --config=.\server2.ini
start "rs0:server3:27013" %MONGOD_CMD% --config=.\server3.ini
REM 分片集2 rs1
start "rs1:server4:27014" %MONGOD_CMD% --config=.\server4.ini
start "rs1:server5:27015" %MONGOD_CMD% --config=.\server5.ini
start "rs1:server6:27016" %MONGOD_CMD% --config=.\server6.ini

如果启动脚本中有中文,需要将utf-8编码修改为中文GBK-232

6.编写副本集初始化脚本for分片集和配置集
REM 手动完成rs0conf.js,rs1conf.js,cfg0conf.js

//rs0conf.js
var rsconf={_id:"rs0","members":[{_id:0,host:"127.0.0.1:27011",priority:2},{_id:1,host:"127.0.0.1:27012",priority:1},{_id:2,host:"127.0.0.1:27013",priority:0,arbiterOnly:true}]};
rs.initiate(rsconf)
//rs1conf.js
var rsconf={_id:"rs1","members":[{_id:0,host:"127.0.0.1:27014",priority:2},//P{_id:1,host:"127.0.0.1:27015",priority:1},//S{_id:2,host:"127.0.0.1:27016",priority:0,arbiterOnly:true}//仲裁节点Arbiter]};
rs.initiate(rsconf)
//cfg0conf.js
var rsconf={_id:"cfg0","members":[{_id:0,host:"127.0.0.1:27018",priority:2},{_id:1,host:"127.0.0.1:27019",priority:1}]};
rs.initiate(rsconf)

7.初始化配置集、分片集(Sharded ReplicaSet)的副本集实例

start "连接到分片1" %MONGO_CMD% --port=27011 --shell rs0conf.js
start "连接到分片2" %MONGO_CMD% --port=27014 --shell rs1conf.js
start "连接到配置集" %MONGO_CMD% --port=27018 --shell cfg0conf.js

8.启动路由节点/分片服务器,然后连接分片服务器 mongos

REM 等待11秒确保副本集完成选举
TIMEOUT /T 11
start "router0:server7:27017" %MONGOS_CMD% --config=.\server7.ini
REM 等待2秒确保路由节点完成启动
TIMEOUT /T 2
start "连接到分片服务器" %MONGOS_CMD% --shell addShards.js

启动脚本程序,如果mongos连接失败,需要打开一个新终端,并输入mongo进入mongos,启动脚本汇总如下:

REM 0.配置环境变量(根据实际环境配置)
SET MONGOD_CMD=C:\mongodb4\bin\mongod.exe
SET MONGOS_CMD=C:\mongodb4\bin\mongos.exe
SET MONGO_CMD=C:\mongodb4\bin\mongo.exeREM 1.创建9台服务器实例(server1~server9)
mkdir server1 server2 server3 server4 server5 server6 server7 server8 server9REM 配置集 cfg0
start "cfg0:server8:27018" %MONGOD_CMD% --config=.\server8.ini
start "cfg0:server9:27019" %MONGOD_CMD% --config=.\server9.ini
REM 分片集1 rs0
start "rs0:server1:27011" %MONGOD_CMD% --config=.\server1.ini
start "rs0:server2:27012" %MONGOD_CMD% --config=.\server2.ini
start "rs0:server3:27013" %MONGOD_CMD% --config=.\server3.ini
REM 分片集2 rs1
start "rs1:server4:27014" %MONGOD_CMD% --config=.\server4.ini
start "rs1:server5:27015" %MONGOD_CMD% --config=.\server5.ini
start "rs1:server6:27016" %MONGOD_CMD% --config=.\server6.inistart "连接到分片1" %MONGO_CMD% --port=27011 --shell rs0conf.js
start "连接到分片2" %MONGO_CMD% --port=27014 --shell rs1conf.js
start "连接到配置集" %MONGO_CMD% --port=27018 --shell cfg0conf.jsREM 等待11秒确保副本集完成选举
TIMEOUT /T 11
start "router0:server7:27017" %MONGOS_CMD% --config=.\server7.ini
REM 等待2秒确保路由节点完成启动
TIMEOUT /T 2
start "连接到分片服务器" %MONGO_CMD% --shell addShards.js

9.添加分片到分片集群

REM 手动编写脚本
REM // 添加rs0
sh.addShard("rs0/127.0.0.1:27011,127.0.0.1:27012,127.0.0.1:27013");
REM // 添加rs1
sh.addShard("rs1/127.0.0.1:27014,127.0.0.1:27015,127.0.0.1:27016");

  • 插入数据后查看
use zrdb
db.myc.insert({"name":"zhangsan"})

  • 查看添加分片信息
    在这里插入图片描述
image-20241118213733956

问题1:mongos连不上,需要在终端进行连接,输入mongo进入mongos【不是输入mongos】
在这里插入图片描述

2.分片集群操作

  1. 在mongos上创建一个数据库,默认存在主分片服务器上

在这里插入图片描述

  • partitioned:false表示非分片数据库,只能在一台服务器上。可以更换数据库的主分片,将"zr"数据库更换到分片集rs1上
db.adminCommand({movePrimary:"zr",to:"rs1"});

在这里插入图片描述

  • admin数据库是管理数据库,config是存放配置集的数据库

  • 查看分片信息,state表示状态,1表示可用,13和16是仲裁节点,不参与存储
db.shards.find()

  • 查看collections集合
db.collections.find()

_id: 集合的唯一标识。

lastmodEpoch: 记录分片配置变更的唯一标识符。

lastmod: 最近一次修改时间。

dropped: 如果为 false,表示该集合当前处于活动状态。

key: 分片键,当前为 { "_id": 1 }

unique: 分片键是否唯一,此处为 false

uuid: 集合的全局唯一标识符。

distributionMode: 表示该集合的分布模式,此处为 sharded,说明此集合已分片。

2.创建分片数据库(都在mongos中执行)

  • 对cqust数据库支持分片
sh.enableSharding("cqust")

在这里插入图片描述

  • 分片的对象是集合,不是数据库,所以接下来还需要手动对集合分片存储,物理上切块,集合默认情况下是存储在主服务器上

  • 使用范围索引片键值

    • 缺点:值比较集中在同一个chunk中,往往集中在一台服务器上,但每次只有一台服务器在工作。负载不均衡。
  • 使用哈希索引片键值

    • 哈希索引片键是一种将数据分布更均匀的分片策略。它基于字段的哈希值来确定数据分片的位置,而不是直接使用字段的原始值。
    • 哈希位数固定,值不固定,使用哈希索引能够让值平均分布

    • 优点:

      均匀分布数据: 哈希值会将数据随机地映射到不同的范围,这样即使数据本身分布不均匀(例如顺序插入的 ID 值),经过哈希后也能实现较为均匀的分布。

      避免热点问题: 当使用顺序值(如时间戳或自增 ID)作为片键时,插入的数据可能会集中在一个分片上,造成单点性能瓶颈。哈希片键可以有效避免这种问题。

  • 创建集合时分片

新建集合时就设置分片,那么此时集合分片均匀,只需要修改GenerateStudents.js中的一条语句。
在这里插入图片描述
在这里插入图片描述

  • 通过命令可以看到分配比较均匀
db.students.getShardDistribution()

  • 先导入数据,后分片

    • 如果直接加载,不会分片,数据全部在rs1中,rs0中无数据
    load("GenerateStudents.js")
    

db.students.getShardDistribution()

在这里插入图片描述

通过命令看到,该集合不是分片集

  • 对students集合中的sno创建哈希索引,如果是范围索引:{sno:1},哈希索引:{sno:“hashed”}

    创建索引的字段,最好是经常使用的字段,如此处的sno学号

db.students.createIndex({sno:"hashed"})
image-20241119100709586
  • 创建分片
sh.shardCollection("cqust.students",{sno:"hashed"})
  • db.stats()查看状态,目前仍然没有分片,以为一块是64MB,目前是15MB左右,还未达到对应的阈值。

  • 执行加载students集合多次,就会有两个分片,每个分片上有多个chunk

在这里插入图片描述
表示有两个分片rs0和rs1,每个分片上有2个chunks,实现负载均衡。

  • 不建议中途,将非分片集修改成分片集。

    导入8万条学生记录后,发现有一半的数据在分片集1中,有一半的数据在分片集2中。
    在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

使用API管理Dynadot域名,在账户中添加域名服务器(Name Server)

前言 Dynadot是通过ICANN认证的域名注册商,自2002年成立以来,服务于全球108个国家和地区的客户,为数以万计的客户提供简洁,优惠,安全的域名注册以及管理服务。 Dynadot平台操作教程索引(包括域名邮箱&…

http账号密码认证Http Basic Auth

1.1 Http Basic Auth 这是一种最古老的安全认证方式,这种方式就是简单的访问API的时候,带上访问的username和password,由于信息会暴露出去,所以现在也越来越少用了,现在都用更加安全保密的认证方式,可能某…

代码随想录算法训练营第六十天|Day60 图论

Bellman_ford 队列优化算法(又名SPFA) https://www.programmercarl.com/kamacoder/0094.%E5%9F%8E%E5%B8%82%E9%97%B4%E8%B4%A7%E7%89%A9%E8%BF%90%E8%BE%93I-SPFA.html 本题我们来系统讲解 Bellman_ford 队列优化算法 ,也叫SPFA算法&#xf…

系统性能定时监控PythonLinux

系统性能定时监控 1.系统监控概述 ⽤Python来编写脚本简化⽇常的运维⼯作是Python的⼀个重要⽤途。在Linux下,有许多系统命令可以让我们时刻监控系统运⾏的状态,如 ps , top , free 等等。要获取这些系统信息,Python…

软件测试面试之数据库部分

1.取第 4 到5 条记录 --按ID从小到大,查询第到第条数据 select top4 *from(select top5 * from qicheorder by ID asc ) as TA order by ID desc--按ID从小到大,查询第到第条数据 select top 2*from(select top 4 *from qicheorder by ID asc )as TA o…

2024年第十三届”认证杯“数学中国数学建模国际赛(小美赛)

↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓

移远通信携手紫光展锐,以“5G+算力”共绘万物智联新蓝图

11月26日,2024紫光展锐全球合作伙伴大会在上海举办。作为紫光展锐重要的合作伙伴,移远通信应邀参会。 在下午的物联网生态论坛上,移远通信产品总监胡勇华作题为“5G与算力双擎驱动 引领智联新未来”的演讲,深度剖析了产业发展的趋…

Microsoft Excel如何插入多行

1.打开要编辑的excel表,在指定位置,鼠标右键点击“插入”一行 2.按住shift键,鼠标的光标箭头会变化成如下图所示 3.一直按住shift键和鼠标左键,往下拖动,直至到插入足够的行

Leetcode322.零钱兑换(HOT100)

链接 代码&#xff1a; class Solution { public:int coinChange(vector<int>& coins, int amount) {vector<int> dp(amount1,amount1);//要兑换amount元硬币&#xff0c;我们就算是全选择1元的硬币&#xff0c;也不过是amount个&#xff0c;所以初始化amoun…

力扣 二叉树的层序遍历-102

二叉树的层序遍历-102 class Solution { public:vector<vector<int>> levelOrder(TreeNode* root) {vector<vector<int>> res; // 二维数组用来存储每层节点if (root nullptr)return res;queue<TreeNode*> q; // 队列用来进行层序遍历q.push(r…

kafka生产者和消费者命令的使用

kafka-console-producer.sh 生产数据 # 发送信息 指定topic即可 kafka-console-producer.sh \ --bootstrap-server bigdata01:9092 \ --topic topicA # 主题# 进程 29124 ConsoleProducer kafka-console-consumer.sh 消费数据 # 消费数据 kafka-console-consumer.sh \ --boo…

跨平台应用开发框架(3)-----Qt(样式篇)

目录 1.QSS 1.基本语法 2.QSS设置方式 1.指定控件样式设置 2.全局样式设置 1.样式的层叠特性 2.样式的优先级 3.从文件加载样式表 4.使用Qt Designer编辑样式 3.选择器 1.类型选择器 2.id选择器 3.并集选择器 4.子控件选择器 5.伪类选择器 4.样式属性 1.盒模型 …

阅读《基于蒙特卡洛法的破片打击无人机易损性分析》_笔记

目录 基本信息 1 引言 1.1 主要研究内容 1.2 研究必要性&#xff08;为什么要研究&#xff09; 1.3 该领域研究现状&#xff08;别人做了什么/怎么做的&#xff09; 2 主要研究过程&#xff08;我们做了什么&#xff09; 2.1 建立目标仿真模型 2.2 确定毁伤依据 2.3 无…

上海乐鑫科技一级代理商飞睿科技,ESP32-C61高性价比WiFi6芯片高性能、大容量

在当今快速发展的物联网市场中&#xff0c;无线连接技术的不断进步对智能设备的性能和能效提出了更高要求。为了满足这一需求&#xff0c;乐鑫科技推出了ESP32-C61——一款高性价比的Wi-Fi 6芯片&#xff0c;旨在为用户设备提供更出色的物联网性能&#xff0c;并满足智能设备连…

Qt Graphics View 绘图实例

Qt Graphics View 绘图实例 这个实例程序实现如下功能&#xff1a; 可以创建矩形、椭圆、三角形、梯形、直线、文字等基本图形。每个图形项都可以被选择和移动。图形项或整个视图可以缩放和旋转。图形项重叠时&#xff0c;可以调整前置或后置。多个图形项可以组合&#xff0c;…

JDK17源码系列-AbstractCollection接口源码解读

JDK17源码系列-AbstractCollection接口源码解读 1、AbstractCollection类图结构 2、AbstractCollection是实现Collection接口的顶级抽象类 3、模版方法&#xff0c;由子类实现 public abstract Iterator iterator()public abstract int size() 4、实现接口public boolean is…

深入浅出:JVM 的架构与运行机制

一、什么是JVM 1、什么是JDK、JRE、JVM JDK是 Java语言的软件开发工具包&#xff0c;也是整个java开发的核心&#xff0c;它包含了JRE和开发工具包JRE&#xff0c;Java运行环境&#xff0c;包含了JVM和Java的核心类库&#xff08;Java API&#xff09;JVM&#xff0c;Java虚拟…

任意文件读取漏洞(CVE-2024-7928)修复

验证CVE-2024-7928问题是否存在可以使用如下方法&#xff1a; https://域名/index/ajax/lang?lang..//..//目录名/文件名&#xff08;不带后缀&#xff09; 目录名是该项目的一个目录&#xff0c;这里目录位置为nginx设置站点目录为基准&#xff0c;网上两层目录。 文件名…

宠物领养系统的SpringBoot技术探索

摘 要 如今社会上各行各业&#xff0c;都在用属于自己专用的软件来进行工作&#xff0c;互联网发展到这个时候&#xff0c;人们已经发现离不开了互联网。互联网的发展&#xff0c;离不开一些新的技术&#xff0c;而新技术的产生往往是为了解决现有问题而产生的。针对于宠物领养…

2-深度学习入门(持续更新)

数据操作 1&#xff09;获取数据&#xff1b;&#xff08;2&#xff09;将数据读入计算机后对其进行处理。 n维数组&#xff0c;也称为张量&#xff08;tensor&#xff09;。 使用过Python中NumPy计算包的读者会对本部分很熟悉。 无论使用哪个深度学习框架&#xff0c;它的张…