一个mongodb问题分析

mongodb问题分析

现状

表的个数:

生产上常用的表就10来个。

sharding cluster + replica set方式部署:

9个shard server, 每个shard server 1主2从, 大量数据写入时或对大表创建索引时,可能有主从复制延迟问题。实测下来,20亿表的索引创建导致主从延时4小时,因为从表在建索引的时候会停掉主从复制。

一个shard server挂掉,恢复起来很慢,一般要半个小时。而且一个shard server挂掉,目前会导致整个集群不可用,此点需要定位。

一个shard server里的master挂掉,剩下2个从是可以选出一个master出来的,只不过选举中间不能写,只能读。另外,一个shard server里的三个节点是分散在3个AZ的,所以断AZ的情况下,可靠性是有保障的。

平时做需求会有加索引的要求,但是你对一张百亿级别的表做索引,这个耗时是很长的,哪怕放到晚上做,也要5~6个小时之久。万一晚上没做完,第二天就可能影响replica set里从节点的复制操作。

还有,业务上大量使用事务,加剧了主从复制延迟情况下的集群负担,造成mongodb连接池和处理线程的耗尽,并波及到incoming request的处理,最后导致整个docker都处于不健康状态。

我们的业务特点是:读优先,写慢一点、不及时都可以容忍。

问题清单

一个shard server挂掉,可能导致整个集群不可用;

是我们使用的方法问题,还是shard server真的就完全不可用了?因为shard server内部是一主二从,且为多AZ分布,理论上完全可以通过降低C(一致性)来保证A(可用性),不会说完全不可用。在这个基础上,我个人认为双活的意义可能不是很大,双活只是为了提高可用性。

数据量继续以每月千万级的规模增长下,如何保证业务查询效率不降低?

增加分片,但增加分片时尽量不要引发大量的数据均衡。

业务逻辑大量使用事务,有没有问题?

mongo的事务本质上是一个分布式事务,效率不高,遇到异常,大概率要成为瓶颈。需要从业务层面评估是否确实需要事务,能不能通过修改表结构,减少事务的使用。

因业务需要对大表加索引,如何降低对集群的影响?

索引是提升查询效率的重要手段,属于以空间换时间,这种行为是不可避免的。那么,如何降低建索引对集群的影响。

核心要素:主从复制延时

主从复制延时应该是不可避免的,因为本身从机把oplog拉到本地redo就是异步的,在正常情况下,这个时间差不会很大,好像就1~2s。但如果有以下几点:

  • 因为大量写入导致的主机cpu、io负载很高
  • 网络异常,时延增加
  • 从机在忙着干其它事(比如创建索引)

这个时延就可能扩的很大。

大量写入及随后的自动均衡、针对大表建索引,都会导致第一个情况发生。

主从时延大对于强调一致性的系统来说,影响很大,不仅仅是各节点数据不一致的问题(这个要看业务是否有强一致性诉求),还会影响读写操作本身。因为对这样的系统而言,写入成功的标准往往不是单点写入成功就行,而是要半数以上的节点写入成功,主从延时大可能会导致写操作挂住或失败!而大量的写失败或挂住又会影响读的可用性,一方面是连接数和线程数的消耗,另一方面是读可能依赖于写(比如readConcern里的majority,为避免脏读,要求读的是大部分节点写入的数据)。

突破口

主从复制延时的解决

要考虑几点:

  • 尽量减少主从复制延时发生的概率;
  • 降低主从复制延时对业务的影响;
  • 主从复制延时后的恢复时间要尽可能短。

解决思路:

  • mongodb备份/ 新增分片的数据均衡/ 大表建索引/ 大量数据不均衡写入/ 慢SQL 这些因素的混合影响,前三者如何把时间错开
  • 修改readPreference做到读写分离,由此带来的数据非最新、不全、不同人做相同的查询结果可能不一样等等,要有心里准备。另外,如果开启了自动均衡,由于还未结束或者异常终止的chunk迁移,secondary返回的可能是有缺失或者多余的数据 。但这里有个问题:读写分离是不是就能降低主从复制延时的影响?需要测试
  • 设置writeConcern的wtimeout,事务失败后的重试保证?
  • 恢复手段:将从节点隐藏,使事务尽快结束;

事务的必要性

首先,假如用嵌套文档解决了表与表之间的关联性,因为mongo里记录级的修改都是原子的,是不是就可以不需要事务了?

第二,如果后面要改成从机读,这样读到的数据本身就没法保证一致性(取决于主从复制的速度) ,当前这么广泛的事务使用还有必要吗?

高可用

我理解,跟ES一样,要考虑几个点:

  • 异常情况下的master选举要能启动,否则集群只读;
  • replica要够,确保异常情况下数据尽量不丢失;
  • shard受损的情况下的行为是怎样的;
  • AZ恢复后的双master脑裂风险

参考该文。

相关推荐
时间售卖铺18 小时前
触发器与函数实战:MySQL高效编程秘诀
运维·数据库·mysql·云原生
qetfw19 小时前
UOS MariaDB 数据库:安装、最小权限与备份验证
linux·数据库·mariadb·uos
数智园区合作社19 小时前
问数平台怎么把同一个指标锁成一个数
大数据·数据库·人工智能·ai
lbb 小魔仙20 小时前
Windows搭建PaddleOCR+飞书Webhook自动打卡通知机器人:识别、推送与远程触发完整教程
数据库·人工智能·prometheus·时序数据库
captain37621 小时前
MyBatis操作数据库(入门2)
java·数据库·spring boot·后端·spring·mybatis
心中有你021421 小时前
Java实现Dijkstra最短路径算法(邻接表 + 优先队列)
java·数据库·算法
龙亘川1 天前
综合素质评价业务建模:从过程性评价到成长档案全链路闭环
数据库·智慧城市·数据可视化
数据库小组1 天前
NineData 实战教程:MySQL 5.5 数据迁移同步到 MySQL 8.0(跨版本升级)
数据库·mysql·mysql优化·数据库开发·数据库迁移·版本升级·数据复制
zhangjw341 天前
1-5 PostgreSQL 数据类型全集:基础类型、字符串、数值、时间类型
数据库·postgresql
王中阳Go1 天前
5.27 分钟干完后端和全部测试:一场三小时笔试的五个失分点,四个不在代码上
大数据·数据库·人工智能·后端·大语言模型