一次线上事故,我顿悟了MongoDB的精髓
wptr33 2025-05-02 13:51 19 浏览
大家好,我是哪吒,最近项目在使用MongoDB作为图片和文档的存储数据库,为啥不直接存MySQL里,还要搭个MongoDB集群,麻不麻烦?
让我们一起,一探究竟,继续学习MongoDB分片的理论与实践,实现快速入门,丰富个人简历,提高面试level,给自己增加一点谈资,秒变面试小达人,BAT不是梦。
三分钟你将学会:
- 一次MongoDB线上事故的快速解决
- 什么是MongoDB分片?
- MongoDB如何分片?
- 何时分片?
- 搭建MongoDB分片服务器
- MongoDB如何追踪分片集群数据?
MongoDB拒绝连接?显然是MongoDB服务又挂了。
连接MongoDB服务器,一探究竟。
通过ps -aef|grep mongo查看mongo服务是否还在?不出所料,都不在了。
大概率是因为磁盘满了。
df -TH查看磁盘空间。
磁盘100%如何解决?
cd到log目录下,通过rm -rf *删除所有日志,再重启MongoDB。
mongodb启动异常:about to fork child process, waiting until server is ready for connection
由于MongoDB是集群部署的,启动时,会进行数据同步,可能会比较耗时,性子急的我,怎么能忍,直接Ctrl C,强制停止,然后再重新启动。
通过ps -aef|grep mongo查看一下进程,两个一样的进程赫然在列。
通过ps -aef|grep mongo | grep -v grep | awk '{print $2}' | xargs kill -9强制停止所有mongo进程。
将data目录下的 mongod.lock 和 diagnostic.data文件删掉,再重启MongoDB,启动脚本mongos_start.sh(mongod --config data/mongodb.conf),完美解决。
MongoDB服务器的部署目录中都是什么含义呢?它们之间又有什么关系呢?下面简单介绍一下MongoDB的分片。
一、什么是MongoDB分片?
分片是指跨机器拆分数据的过程,也可以叫做分区。
MongoDB支持手动分区,使用这种方法,应用程序会维护到多个不同数据库服务器端的连接,每个服务器端都是完全独立的。应用程序不仅管理不同服务器上不同数据的存储,还管理在适当的服务器上查询数据。但当从集群中添加或删除节点,或者面对数据分布或负载模式的变化时,难以维护。
MongoDB支持自动分片,这种方式试图将数据库架构从应用程序中抽离出来,并简化系统管理。MongoDB自动均衡分片上的数据,使节点的添加和删除变得更容易。
MongoDB的分片机制允许你创建一个由许多分片组成的集群,并将集合中的数据分散在集群中,在每个分片上放置数据的一个子集。这允许应用程序超出单机服务器或副本集的资源限制。
分片组成的集群对应用程序来说就像一台单机服务器,分片前运行一个或多个称为mongos的路由进程,mongos维护着一个“目录”,指明了每个分片包含哪些数据。应用程序可以正常连接到此路由服务器并发出请求。路由服务器知道哪些数据在哪个分片上,可以将请求转发到适当的分片。如果有对请求的响应,理由服务器会收集它们,并将它们合并,然后再返回给应用程序,对应用程序而言,它只知道自己连接到了一个单独的mongod。
二、MongoDB如何分片?
在单台机器上快速建立一个集群。首先,使用--nodb和--norc选项启动mongo shell:mongo --nodb --norc。
使用ShardingTest类创建集群。运行如下代码:
st = ShardingTest({
name:"one-min-shards",
chunkSize:1,
shards:2,
rs:{
nodes:3,
oplogSize:10
},
other:{
enableBalancer:true
}
});
- name:分片集群的标签;
- shards:制定了集群由两个分片组成;
- rs:将每个分片定义为一组3个节点的副本集;
- enableBalancer:在集群启动后启用均衡器;
ShardingTest是为了支持服务器端测试套件设计的,它在保持尽可能低的资源占用以及建立体系结构相对复杂的分片集群方面,提供了很多便利。当运行ShardingTest后,它会创建一个包含两个分片的集群,每个分片都是一个副本集。同时会对副本集进行配置,并使用必要的选项启动每个节点以建立复制协议。它会启动一个mongos来管理跨分片的请求,这样客户端就可以像与一个独立的mongod通信一样与集群进行交互。最后,它会为用于维护理由表信心的配置服务器启动一个额外的副本集,以确保查询被定向到正确的分片。
分片的主要使用场景是拆分数据集以解决硬件和成本的限制,或为应用程序提供更好的性能。
当ShardingTest完成集群设置后,将启动并运行10个进程,你可以连接到这些进程:两个副本集(各有3个节点)、一个配置服务器副本集(3个节点),以及一个mongos。默认情况下,这些进程会从20000端口开始。mongos会运行在20009端口上。
三、何时分片?
通常情况下,分片用于:
- 增加可用RAM;
- 增加可用磁盘空间;
- 减少服务器的负载;
- 处理单个MongoDB无法承受的吞吐量;
四、搭建MongoDB分片服务器
1、配置服务器 config进程
配置服务器是集群的大脑,保存着关于每个服务器包含哪些数据的所有元数据,因此必须首先创建配置服务器。配置服务器非常重要,运行时必须启动日志功能,并确保它的数据存储在非临时性驱动器上。
配置服务器必须在任何一个mongos进程之前通过mongod -f config.conf启动,因为mongos需要从配置服务器中提取配置信息。
当对配置服务器进行写入时,MongoDB会使用“majority” 的 writeConcern级别; 当对配置服务器进行读取时,MongoDB会使用“majority” 的 readConcern级别;
这确保了分片集群元数据在不发生回滚的情况下才会被提交到配置服务器副本集。它还确保了只有那些不受配置服务器故障影响的元数据才能被读取。这可以确保所有mongos路由节点对分片集群中的数据组织方式具有一致性。
在服务器资源方面,配置服务器应该具有充分的网络和CPU资源,配置服务器只保存了集群中数据的目录,因此只需要很少的硬盘存储资源。
由于配置服务器的重要性,在进行任何集群维护前,都应该先对配置服务器的数据进行备份。
2、mongos进程
mongos 是路由服务器,供应用程序连接使用。通过mongod -f config.conf启动路由服务器,mongos进程需要知道配置服务器的地址,因此需要在config.conf中配置 configdb=configReplSet/配置服务器的三个地址,通过配置logpath,保存MongoDB的日志。
应该启动一定数量的mongos进程,并尽可能将其放在靠近所有分片的位置,这样可以提高查询性能。
3、将副本集转换为分片
在依次启动配置服务器、路由服务器后,可以添加分片了,如果之前已经存在副本集,那么这个副本集就会成为第一个分片。
从MongoDB 3.4 开始,对于分片集群,分片的mongod实例必须配置 --shardsvr 选项,也就是在config.conf中添加shardsvr=true,将副本集转换为分片的过程中,需要对副本集的每个成员都重复以上动作。
将副本集作为分片添加到集群后,就可以将应用程序的连接从副本集改为mongos路由服务器了,并通过设置防火墙,切断应用程序与分片的直接连接。
4、数据分片
(1)如何数据分片
假如有一个test数据库,并在name键上对worker集合进行分片。
- 先对数据库进行分片,> sh.enableSharding("test");
- 再对集合进行分片,sh.shardCollection("test.worker",{"name":1});
如果worker集合已经存在,则必须在name字段上有索引,否则,shardCollection会返回错误。如果分片的集合不存在,mongos会自动在name片键上创建索引。
shardCollection命令会将集合拆分成多个数据块,MongoDB会在集群中的分片间均匀的分散集合中的数据。
五、MongoDB如何追踪集群数据?
1、数据块
因为MongoDB的数据量巨大,MongoDB一般会将文档以数据块的形式进行分组,这些数据块是片键指定范围内的文档,MongoDB一般会用一个较小的表来维护数据块与分片之间的映射关系。
需要注意:
- 块与块之间不能重叠;
- 一个块中的文档数量过大时,会自动拆分成两个文档;
- 一个文档总是属于且仅属于一个块;
2、块范围
- 新分片的集合中只有一个块,块的边界是负无穷到正无穷;
- 随着块的增长,MongoDB会自动将其拆分成两块,范围从负无穷到value,value到正无穷。范围较小的块包含比value小的值,范围较大的块包含value和比value大的值;
因此,mongos可以很容易的找到文档在哪个块。
3、拆分块
各个分片的主节点mongod进程会跟踪它们当前的块,一旦达到某个阈值,就会检查该块是否需要拆分,如果需要拆分,mongod就会从配置服务器请求全局块大小配置值,然后执行块拆分并更新配置服务器上的元数据。配置服务器会创建新的块文档,并修改旧块的范围。
当客户端写入一个块时,mongod会检查该块的拆分阈值。
如果已经达到了拆分阈值,mongod就会向均衡器发送一个请求,将最顶部的块进行迁移,否则该块会留在此分片上。
因为具有相同片键的两个文档一定会处于相同的块中,所以只能在片键值不同的文档之间进行拆分。
下面文档如果以readTime分片,是可以的。
但是,如果我读书读的比较快,所有书籍在一个月的时间里都读完了,readTime就会是一样的了,那就无法分片了。
因此拥有不同的片键值在分片时,显得尤其重要。
{"name":"哪吒编程","book":"Java核心技术","readTime":"October"}
{"name":"哪吒编程","book":"Java编程思想","readTime":"October"}
{"name":"哪吒编程","book":"深入理解Java虚拟机","readTime":"October"}
{"name":"哪吒编程","book":"effective java","readTime":"November"}
{"name":"哪吒编程","book":"重构 改善既有代码的设计","readTime":"November"}
{"name":"哪吒编程","book":"高性能MySQL","readTime":"December"}
{"name":"哪吒编程","book":"Spring技术内幕","readTime":"December"}
{"name":"哪吒编程","book":"重学Java设计模式","readTime":"December"}
{"name":"哪吒编程","book":"深入理解高并发编程","readTime":"January"}
{"name":"哪吒编程","book":"Redis设计与实现","readTime":"January"}
分片的前提条件是所有的配置服务器必须启动并可以访问。如果mongod不断接到对一个块的写请求,则它会持续尝试拆分该块并失败,而这些拆分尝试会拖慢mongod。mongod反复尝试分片却无法成功分片的过程被称为拆分风暴。
六、均衡器
均衡器负责数据的迁移。均衡器会定期检查分片之间是否存在不均衡,如果存在,就会对块进行迁移。在MongoDB 3.4 以上的版本上,均衡器位于配置服务器副本集的主节点成员上。
均衡器是配置服务器副本集主节点上的后台进程,它会监视每个分片上的块数量。只有当一个分片上的块数量达到特定迁移阈值时,均衡器才会被激活。
相关推荐
- MySQL进阶五之自动读写分离mysql-proxy
-
自动读写分离目前,大量现网用户的业务场景中存在读多写少、业务负载无法预测等情况,在有大量读请求的应用场景下,单个实例可能无法承受读取压力,甚至会对业务产生影响。为了实现读取能力的弹性扩展,分担数据库压...
- 3分钟短文 | Laravel SQL筛选两个日期之间的记录,怎么写?
-
引言今天说一个细分的需求,在模型中,或者使用laravel提供的EloquentORM功能,构造查询语句时,返回位于两个指定的日期之间的条目。应该怎么写?本文通过几个例子,为大家梳理一下。学习时...
- 一文由浅入深带你完全掌握MySQL的锁机制原理与应用
-
本文将跟大家聊聊InnoDB的锁。本文比较长,包括一条SQL是如何加锁的,一些加锁规则、如何分析和解决死锁问题等内容,建议耐心读完,肯定对大家有帮助的。为什么需要加锁呢?...
- 验证Mysql中联合索引的最左匹配原则
-
后端面试中一定是必问mysql的,在以往的面试中好几个面试官都反馈我Mysql基础不行,今天来着重复习一下自己的弱点知识。在Mysql调优中索引优化又是非常重要的方法,不管公司的大小只要后端项目中用到...
- MySQL索引解析(联合索引/最左前缀/覆盖索引/索引下推)
-
目录1.索引基础...
- 你会看 MySQL 的执行计划(EXPLAIN)吗?
-
SQL执行太慢怎么办?我们通常会使用EXPLAIN命令来查看SQL的执行计划,然后根据执行计划找出问题所在并进行优化。用法简介...
- MySQL 从入门到精通(四)之索引结构
-
索引概述索引(index),是帮助MySQL高效获取数据的数据结构(有序),在数据之外,数据库系统还维护者满足特定查询算法的数据结构,这些数据结构以某种方式引用(指向)数据,这样就可以在这些数据结构...
- mysql总结——面试中最常问到的知识点
-
mysql作为开源数据库中的榜一大哥,一直是面试官们考察的重中之重。今天,我们来总结一下mysql的知识点,供大家复习参照,看完这些知识点,再加上一些边角细节,基本上能够应付大多mysql相关面试了(...
- mysql总结——面试中最常问到的知识点(2)
-
首先我们回顾一下上篇内容,主要复习了索引,事务,锁,以及SQL优化的工具。本篇文章接着写后面的内容。性能优化索引优化,SQL中索引的相关优化主要有以下几个方面:最好是全匹配。如果是联合索引的话,遵循最...
- MySQL基础全知全解!超详细无废话!轻松上手~
-
本期内容提醒:全篇2300+字,篇幅较长,可搭配饭菜一同“食”用,全篇无废话(除了这句),干货满满,可收藏供后期反复观看。注:MySQL中语法不区分大小写,本篇中...
- 深入剖析 MySQL 中的锁机制原理_mysql 锁详解
-
在互联网软件开发领域,MySQL作为一款广泛应用的关系型数据库管理系统,其锁机制在保障数据一致性和实现并发控制方面扮演着举足轻重的角色。对于互联网软件开发人员而言,深入理解MySQL的锁机制原理...
- Java 与 MySQL 性能优化:MySQL分区表设计与性能优化全解析
-
引言在数据库管理领域,随着数据量的不断增长,如何高效地管理和操作数据成为了一个关键问题。MySQL分区表作为一种有效的数据管理技术,能够将大型表划分为多个更小、更易管理的分区,从而提升数据库的性能和可...
- MySQL基础篇:DQL数据查询操作_mysql 查
-
一、基础查询DQL基础查询语法SELECT字段列表FROM表名列表WHERE条件列表GROUPBY分组字段列表HAVING分组后条件列表ORDERBY排序字段列表LIMIT...
- MySql:索引的基本使用_mysql索引的使用和原理
-
一、索引基础概念1.什么是索引?索引是数据库表的特殊数据结构(通常是B+树),用于...
- 一周热门
-
-
C# 13 和 .NET 9 全知道 :13 使用 ASP.NET Core 构建网站 (1)
-
程序员的开源月刊《HelloGitHub》第 71 期
-
详细介绍一下Redis的Watch机制,可以利用Watch机制来做什么?
-
假如有100W个用户抢一张票,除了负载均衡办法,怎么支持高并发?
-
如何将AI助手接入微信(打开ai手机助手)
-
Java面试必考问题:什么是乐观锁与悲观锁
-
SparkSQL——DataFrame的创建与使用
-
redission YYDS spring boot redission 使用
-
一文带你了解Redis与Memcached? redis与memcached的区别
-
如何利用Redis进行事务处理呢? 如何利用redis进行事务处理呢英文
-
- 最近发表
- 标签列表
-
- git pull (33)
- git fetch (35)
- mysql insert (35)
- mysql distinct (37)
- concat_ws (36)
- java continue (36)
- jenkins官网 (37)
- mysql 子查询 (37)
- python元组 (33)
- mybatis 分页 (35)
- vba split (37)
- redis watch (34)
- python list sort (37)
- nvarchar2 (34)
- mysql not null (36)
- hmset (35)
- python telnet (35)
- python readlines() 方法 (36)
- munmap (35)
- docker network create (35)
- redis 集合 (37)
- python sftp (37)
- setpriority (34)
- c语言 switch (34)
- git commit (34)