一个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脑裂风险

参考该文

相关推荐
数据智能老司机1 小时前
CockroachDB权威指南——SQL调优
数据库·分布式·架构
数据智能老司机2 小时前
CockroachDB权威指南——应用设计与实现
数据库·分布式·架构
数据智能老司机2 小时前
CockroachDB权威指南——CockroachDB 模式设计
数据库·分布式·架构
数据智能老司机20 小时前
CockroachDB权威指南——CockroachDB SQL
数据库·分布式·架构
数据智能老司机21 小时前
CockroachDB权威指南——开始使用
数据库·分布式·架构
松果猿21 小时前
空间数据库学习(二)—— PostgreSQL数据库的备份转储和导入恢复
数据库
无名之逆21 小时前
Rust 开发提效神器:lombok-macros 宏库
服务器·开发语言·前端·数据库·后端·python·rust
s91236010121 小时前
rust 同时处理多个异步任务
java·数据库·rust
数据智能老司机1 天前
CockroachDB权威指南——CockroachDB 架构
数据库·分布式·架构
hzulwy1 天前
Redis常用的数据结构及其使用场景
数据库·redis