替换 MongoDB 存储引擎的那几个不眠夜

Posted 云头条

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了替换 MongoDB 存储引擎的那几个不眠夜相关的知识,希望对你有一定的参考价值。

在过去的两年间,我们一直使用MongoDB 2.6,以MMAPv1作为存储引擎。它一向是我们系统中的稳定组件,直到后来我们升级到版本3.0,将辅助系统升格为主,WiredTiger配置成存储引擎。具体来说,我们在一台主服务器上每秒处理大约~18070次操作。我们在集群中有两套分片(shard),那样两台主服务器每秒可处理大约36140次操作。由于我们把大部分存储卸载到了一个专门定制的内存存储引擎,这只占我们入站流量中的一小部分。


吞吐量提高7倍至10倍的诱惑


WiredTiger承诺可以提供更高的吞吐量,辅以文档级并发机制,而不是MMAPv1中的集合级并行机制。我们在生产环境下升级之前进行了快速测试,结果发现性能提升了7倍。惊讶之余,我们决定在下个周末升级。我们分四个阶段来开展这项工作:


  1. 将集群元数据和Mongo二进制代码从2.6升级到3.0。

  2. 重新同步辅助系统,WiredTiger作为存储引擎,并将辅助系统升格为主系统。

  3. 将配置服务器改为WiredTiger。

  4. 升级现有的MONGODB-CR用户,以便使用SCRAM-SHA-1。


升级


第一个阶段:周六上午,二进制代码升级在一小时内顺利地执行完毕。在此期间,所有入站流量在升级后予以列队和处理。周一晚上,我开始重新同步辅助服务器,WiredTiger作为存储引擎。


到目前为止,一切顺利。


第二个阶段:周二,我们停掉了主节点,让WiredTiger驱动的辅助节点开始服务于生产流量。几分钟内,我们拥有了概况数据(profiling data),这些数据表明我们的吞吐量确实有了提升。


这时候,我们可以将多出7倍的流量扔给MongoDB来处理,而不影响吞吐量。WiredTiger完全兑现了它的承诺。在生产环境中运行了几小时后,我们决定重新同步旧的MMAPv1主节点,现在它们是辅助节点,存储引擎被设成WiredTiger。我们现在运行时,副本集(replica set)中只有一个单一实用的数据节点(主节点)。


一个小时候后,问题全暴露出来


短短几分钟内,MongoDB的吞吐量就骤降至每秒约1000次操作,让人觉得MongoDB陷入了停顿。这时我们开始终止刚用了不久的WiredTiger。为了尽快查明问题,我们的监控系统报告,Mongos节点宕机了。手动启动它们后,让人松了一口气,但这种情况也就持续了几分钟。Mongos日志似乎显示:


2016-MM-DDT14:29:55.497+0530 I CONTROL  [signalProcessingThread] got signal 15 (Terminated), will terminate after current cmd ends

2016-MM-DDT14:29:55.497+0530 I SHARDING [signalProcessingThread] dbexit:  rc:0


是谁/什么发送SIGTERM仍是个未知数。系统日志没有这方面的详细信息。几分钟后,Mongos决定再次退出。


这个节骨眼,我们都奔到了战略决策室――重新启动了Mongod节点以及Mongos。系统看起来运行稳定,我们有一段时间重新考虑到底出了什么岔子。又出现几次mongo锁锴后,我们根据遥测数据发现,每当WiredTiger的缓存达到100%,MongoDB就会锁死。我们的数据节点在r3.4xlarge(120GB内存)上运行。默认情况下,MongoDB分配50%的内存用作WiredTiger的缓存。随着时间的推移,缓存渐渐达到100%后,它就会陷入停顿。由于担心每隔几小时就会出现锁死、半夜里会出现几次锁死,我们迁移到了r3.8xlarge(240GB内存,这多亏了AWS)。有了120G的缓存,我们明白:就我们的工作负载和工作集而言,WiredTiger在98GB缓存下很稳定。我们在副本集中仍没有辅助节点,原因是启动重新同步过程会将缓存提高到100%,从而让MongoDB陷入停顿。度过又一个不眠夜之后,我们让MongoDB数据节点在x1.32xlarge(2TB内存)上运行。AWS不是很出色吗?有了1TB缓存,我们能够让辅助节点可以全面重新同步,存储引擎被设成MMAPv1,那样我们就能回过头去,摈弃WiredTiger及其缓存需求。虽然MMAPv1的吞吐量较低,但是很稳定,于是我们只好尽快回到MMAPv1。


汲取的惨痛教训


在升级时,将MMAPv1副本节点保留至少10天。


我们急不可待地就开始重新同步,存储引擎被设为WiredTiger;如果全面同步,我们就可以将运行MMAPv1的辅助系统升格为系统,那样可以避免所有的不眠夜。


根据工作负载,选择大小合适的操作日志(Oplog)。


由于频繁的更新和插入,我们的操作日志在正常的生产时间可能保存几小时的数据。只有在晚上,我们才有足够多小时的数据,能够重新同步、使用操作日志赶上来。这意味着,我们不得不在晚上重新同步。


WiredTiger大有前景,但是目前不易管控。


从我们遇到的情况来看,WiredTiger确实兑现了吞吐量提升7倍至10倍的承诺,但是当缓存达到100%就会锁死。我们使用最新版本(截至截稿时是3.2.9)同样会遇到这一幕,正在提交一份错误报告。我们承诺会提供更多的信息,帮助解决这个问题。按照目前状况,一旦工作集超过配置的缓存大小,作为最新版MongoDB的默认存储引擎,WiredTiger就不稳定。它会让生产环境陷入停顿。

配置服务器知道数据状态方面的太多信息。


事后一想,如果你在评估MongoDB或使用它,就要考虑灾难恢复。我们在忙于救火时认识到,如果你的数据在共享集群中,从文件系统快照备份来恢复或安装一个新的集群到底有多难。对每个节点约200GB的数据集而言,从每个节点导出所有数据,并导入到新的集群中极其缓慢。以我们为例,这个过程要花约36个小时。


  • 补充1:我们在表示列出的数据时犯了一个错误。它是文章开头提到的每秒/操作,而不是每分钟/操作(这其实是你所犯的最糟糕错误)。我已更新了这篇文章,体现了这一变化。

  • 补充2:在同等条件下,考虑到WiredTiger是Mongo 3.2版本之后的默认存储引擎,它至少拥有MMAPv1的稳定性。


每当我们重新启动数据节点,WiredTiger就会顺利运行几个小时,但之后就挂起。深入研究后我们注意到,当缓存达到95%的容量时,它就会挂起。所以很显然,某个缓存移出(cache eviction)问题在其中作梗。


云头条编译|未经授权谢绝转载


以上是关于替换 MongoDB 存储引擎的那几个不眠夜的主要内容,如果未能解决你的问题,请参考以下文章

opendatabase的那几个参数怎么用

mongodb三种存储引擎高并发更新性能专题测试

前端面试要注意的那几个点?

前端面试要注意的那几个点?

1024程序员日,聊聊人们对程序员的那几个偏见

1024程序员日,聊聊人们对程序员的那几个偏见