写点什么

Crittercism: 在 MongoDB 上实现每天数十亿次请求

2014 年 3 月 25 日

MongoDB 的扩展能力可以满足你业务需求的增长——这也是为什么它的名字来源于单词 humongous(极大的)的原因。当然,这并不是说你在使用 MongoDB 的路上并不会碰到一些发展的痛点。Crittercism 是一家专门为手机应用程序提供技术支持的初创公司,该公司在过去两年间发展迅猛,其运营总监 Mike Chesnut 于最近发表了一篇博文,描述了公司在快速发展的过程中遇到的一些 MongoDB 陷阱以及从中学到的经验。在今年 6 月将会举行的 MongoDB World 大会上,Mike Chesnut 将会介绍 Crittercism 是如何在 MongoDB 上实现每秒 30,000 次请求的。

背景

Crittercism 提供了世界上首个领先的移动应用性能管理(mAPM)解决方案。其 SDK 被嵌入了成千上万的应用中,在全世界有近十亿用户。该公司致力于收集性能数据,例如错误报告、崩溃诊断细节、面包屑(breadcrumbs,指导航记录)、设备 / 载体 /OS 统计和用户行为等。这些数据大部分是非结构化的,并且随着应用程序、版本、设备和使用模式的不同变化很大。

Crittercism 将所有的这些数据存储在 MongoDB 中以便于收集原始信息供用户以各种方式使用,同时还提供了将数据概括到易消化、可操作的维度所需的分析功能。在过去的 18 个月中,Crittercism 每天的请求量增长了超过 40 倍,主要的 MongoDB 集群现在存储的数据量超过了 20TB。

路由

MongoDB 文档显示,最常见的拓扑结构是在每一个客户端系统上包含一个路由器——一个mongos 进程。Mike Chesnut 表示他们开始的时候就是这样做的,并且在很长的一段时间内这种方式工作的很好。

但是随着生产环境中前端应用程序服务器的数量从十几台增长到几百台,Crittercism 发现mongos 路由和mongod 分片服务器之间建立了几百、有时候甚至是几千个连接,负载非常重。这意味着每当 chunk 平衡(MongoDB 分片集群为了保持数据均匀分布所必须使用的平衡措施)发生的时候传送存储在配置数据库中的chunk 位置信息都需要花费相当长的时间。这是因为每一个mongos 路由都必须清楚地知道每一个chunk 都存在于集群中的哪些位置。

对于这一问题Mike Chesnut 表示:

我们发现将__mongos__ 路由合并到少数几台主机上能够减轻这个问题。我们产品的基础设施在__AWS__ 上,所以我们在每个可用区域内部署了__2__ 台__mongos__ 服务器。这样每个区域都有冗余,同时还为客户端提供了到__mongos__ 路由的最短网络路径。我们也担心请求路径中会增加额外的驿站,但是通过__Chef__ 配置所有的客户端让它们仅与自己区域内的__mongos__ 路由通信能够最小化这个问题。

这种拓扑结构的变化极大地减少了__mongos__ 路由和__mongod__ 分片服务器之间的连接的数量(这一点可以通过 MMS衡量),并且没有明显地降低应用程序的性能。此外我们还对 __MongoDB__ 做了一些改进,让它能够更有效地完成 __mongos__ 更新和内部一致性检查。借助于这些措施以及新的网络拓扑结构,我们现在能够在不引发性能问题的情况下平衡集群中的 __chunk_。_

分片替换

Crittercism 公司遇到的另一个场景是需要动态地替换 mongod 服务器从而迁移到更大的分片上。Mike Chesnut 表示:

对于这一问题我们再次采用了文档中推荐的最佳部署实践,将__MongoDB__ 部署到使用大型__RAID 10__ 磁盘阵列并且运行着__xfs__ 的服务器实例上。我们使用了有__16__ 块磁盘的__AWS m2.4xlarge__ 实例。处于性能方面的考虑,我们使用了基本的__Linux mdadm__,但是这样也牺牲了磁盘配置灵活性。这样做的结果是当我们需要为分片分配更多容量的时候,我们需要执行一个迁移程序,有时候这会花费几天的时间。这意味着我们不仅需要提前做出合适的计划,还需要了解整个流程从而对其进行监控并在出现错误的时候做出响应。

_ 当所有副本的磁盘利用率大致相等的时候我们会开始一个复制集。首先我们会创建一个新的服务器实例,为它分配更多的磁盘,然后使用 __rs.add()_方法将其添加到这个复制集中。

新副本将进入 __STARTUP2__ 状态并在该状态保持一段时间(在我们的情况下通常是 __2__ 到 __3__ 天),在此期间它首先会复制数据,然后会通过操作日志(oplog)复制赶上进度并构建索引。索引的构建通常会停止复制过程(注意,这个行为在 MongoDB 2.6_ 中必定会改变),所以严格来说复制延迟时间并不是一直在缩短——在一段时间内它会稳步缩短,然后当一个索引构建发生的时候复制便会暂停,延迟时间会再次延长。一旦索引构建完成,那么复制将会再次恢复。值得注意的是,当索引构建发生的时候,_mongostat__ 以及其他任何需要读锁的操作都将被阻塞。

副本最终会进入 __SECONDARY__ 状态并具备完整的功能。这时候我们可以 rs.stepDown() 一个旧的副本,关闭它上面运行的 __mongod__ 进程,然后通过 s.remove()方法将它从复制集中移除,让服务器做好退出的准备。

之后复制集中的每一个成员都会重复这个过程,直到这些成员都被使用更大磁盘的新实例替换为止。

虽然这个过程有点耗时,有点乏味,但是却可以让我们以一种优雅的方式增长数据库的足迹,不会对客户造成任何影响。

结论

和使用其他任何技术一样,运营大规模 MongoDB 也需要一些知识,有些知识你可以从文档中获取,而另一些则来自于经验。通过尝试一些不同的策略,例如上面提到的那些,你可以发现一些之前并不明显的灵活性。对于 Crittercism 的运维团队而言,合并 mongos 路由层无论是在性能方面还是在管理性方面都是一个巨大的成功,此外开发上面提到的迁移程序让我们能够持续地发展,在满足自己业务需要的同时不会影响我们的服务或者客户。


感谢程显峰对本文的审校。

给InfoQ 中文站投稿或者参与内容翻译工作,请邮件至 editors@cn.infoq.com 。也欢迎大家通过新浪微博( @InfoQ )或者腾讯微博( @InfoQ )关注我们,并与我们的编辑和其他读者朋友交流。

2014 年 3 月 25 日 20:124628
用户头像

发布了 321 篇内容, 共 102.2 次阅读, 收获喜欢 6 次。

关注

评论

发布
暂无评论
发现更多内容

从零开始搭建完整的电影全栈系统(四)——restfulApi用户的认证授权及用户注册

刘强西

RESTful API yii

大数据任务调度 - 有向无环图(DAG)之拓扑排序

海豚调度

数据结构 大数据任务调度 DAG 拓扑排序 Apache DolphinScheduler

架构师训练营第十四周

Melo

oeasy教您玩转linux 010211 牛说 cowsay

o

Pulsar Flink Connector 2.5.0 正式发布

Apache Pulsar

flink 开源 flink 消费 kafak Apache Pulsar

记一种spring框架的想当然但错误的用法

小明同学

源码分析 最佳实践 Spring Framework bug

LeetCode题解:232. 用栈实现队列,使用两个栈 入队 - O(1),出队 - 摊还复杂度 O(1),JavaScript,详细注释

Lee Chen

LeetCode 前端进阶训练营

USDT承兑支付系统,区块链跨境支付源码

13530558032

甲方日常 13

句子

工作 随笔杂谈 日常

[翻译]Scalable Go Scheduler Design Doc[Go可扩展调度设计文档]

卓丁

golang golang scheduler Go scheduler

澳门金沙玩赢了钱提现不了异常注单未更新有什么办法处理?

丛林里的余光

异常检测 澳门金沙 提现不了

如何利用Chrome DevTools优化网页性能

熊斌

学习

[翻译]Go Code Review Comments

卓丁

区块链支付通道系统搭建,USDT跑分承兑商系统

13823153121

多线程与高并发之锁

彭阿三

多线程 多线程与高并发

.NET委托,事件和Lambda表达式

AI代笔

云小课 |选定合适的证书,做“有证”的合规域名

华为云开发者社区

证书 课程练习 ssl

大项目写代码写到晕头转向?敏捷多项目框架解君愁

Philips

敏捷开发 程序设计 软件架构

区块链数字钱包开发,数字钱包app

13530558032

合约跟单模式系统开发,交易所合约跟单源码

13530558032

拥抱K8S系列-06-K8S如何解决docker部署的问题

张无忌

Docker Kubernetes 运维 service

这篇文章,把中国科技的真实底子讲透了

CECBC区块链专委会

中国 科技 产业竞争

不要以为Bug写的好就是好程序员,其实这只占不到15%

小Q

Java 学习 程序员 架构 面试

JavaScript引擎的事件循环机制是怎样工作的?

Walker

Java 前端 运行时栈帧 事件循环

从外卖员到拼多多30K+程序员,我付出了三年的青春

小Q

Java 学习 程序员 架构 面试

oeasy教您玩转linux010210管理应用aptitude

o

滴滴AR实景导航背后的技术

滴滴技术

人工智能 滴滴技术 实景导航 地图与公交事业群分享月

数字货币交易所开发方案,交易所源码

13530558032

MySQL最全整理(面试题+笔记+导图),面试大厂不再被MySql难倒!

Java成神之路

Java MySQL 编程 程序员 面试

朱嘉明:全球科技革命正在逼近“奇点”,区块链影响未来人类社会的走向

CECBC区块链专委会

人工智能 科技 科技革命

LeetCode题解:232. 用栈实现队列,使用两个栈 入队 - O(n), 出队 - O(1),JavaScript,详细注释

Lee Chen

前端进阶训练营

InfoQ 极客传媒开发者生态共创计划线上发布会

InfoQ 极客传媒开发者生态共创计划线上发布会

Crittercism: 在MongoDB上实现每天数十亿次请求-InfoQ