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上,所以我们在每个可用区域内部署了2mongos服务器。这样每个区域都有冗余,同时还为客户端提供了到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状态并在该状态保持一段时间(在我们的情况下通常是23天),在此期间它首先会复制数据,然后会通过操作日志(oplog)复制赶上进度并构建索引。索引的构建通常会停止复制过程(注意,这个行为在MongoDB 2.6中必定会改变),所以严格来说复制延迟时间并不是一直在缩短——在一段时间内它会稳步缩短,然后当一个索引构建发生的时候复制便会暂停,延迟时间会再次延长。一旦索引构建完成,那么复制将会再次恢复。值得注意的是,当索引构建发生的时候,mongostat以及其他任何需要读锁的操作都将被阻塞。

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

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

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

结论

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

(转) Crittercism: 在MongoDB上实现每天数十亿次请求的更多相关文章

  1. C# mongodb [上]

    概述 MongoDB是一个高性能,开源,无模式的文档型数据库,使用C++开发.是一个介于关系数据库和非关系数据库之间的产品,是非关系数据库当中功能最丰富,最像关系数据库的.他支持的数据结构非常松散,是 ...

  2. Android填坑系列:在小米系列等机型上放开定位权限后的定位请求弹框

    背景: 近期因实际项目需要,在特定操作下触发定位请求,取到用户位置及附近位置. 问题: 经初步选型,最终决定接入百度定位,按照百度定位SDK Android文档,接入过程相对顺利.但随后发现,在小米系 ...

  3. Java中使用HttpPost上传文件以及HttpGet进行API请求(包含HttpPost上传文件)

    Java中使用HttpPost上传文件以及HttpGet进行API请求(包含HttpPost上传文件) 一.HttpPost上传文件 public static String getSuffix(fi ...

  4. django MongoDB上传文件

    django上传文件,查询到的资料都是用的django自己的models.Model类,去定义一个FileField类型的存储文件,并且在里面加一句upload_to,如下所示:   但是如果用mon ...

  5. springboot实现mongodb上传下载

    1.上传: private static Logger log = LoggerFactory.getLogger(MongoDbFSUtil.class); private static final ...

  6. MongoDB上的索引

    1. 将索引建在number键上名为nameIndex并且为正序索引({number:-1}为倒序索引) 如: db.list名.ensureIndex({number:1},{name:" ...

  7. 在 MongoDB 上模拟事务操作来实现支付

    我们的产品叫「学海密探」,属于在线教育行业,产品需要有支付功能,然而支付最蛋疼是什么?有人会说是支付宝和微信等支付接口的接入开发!没错,但支付接口的开发算是比较简单的了,我觉得凡是跟钱有关系的操作最重 ...

  8. MongoDB副本集配置系列十:MongoDB local库详解和数据同步原理

    1:local库是MongoDB的系统库,记录着时间戳和索引和复制集等信息 gechongrepl:PRIMARY> use local switched to db local gechong ...

  9. 百万级高并发mongodb集群性能数十倍提升优化实践

    背景 线上某集群峰值TPS超过100万/秒左右(主要为写流量,读流量很低),峰值tps几乎已经到达集群上限,同时平均时延也超过100ms,随着读写流量的进一步增加,时延抖动严重影响业务可用性.该集群采 ...

随机推荐

  1. git使用具体介绍

    1. Git概念  1.1. Git库中由三部分组成         Git 仓库就是那个.git 文件夹,当中存放的是我们所提交的文档索引内容,Git 可基于文档索引内容对其所管理的文档进行内容追踪 ...

  2. 算法代码[置顶] 机器学习实战之KNN算法详解

    改章节笔者在深圳喝咖啡的时候突然想到的...之前就有想写几篇关于算法代码的文章,所以回家到以后就奋笔疾书的写出来发表了 前一段时间介绍了Kmeans聚类,而KNN这个算法刚好是聚类以后经常使用的匹配技 ...

  3. Git Cmd

    http://my.oschina.net/sunboy2050/blog/55749

  4. UML Distilled - Development Process

    Iterative(迭代) and Waterfall(瀑布) Processes One of the biggest debates about process is that between w ...

  5. T4 文本模板编写准则

    如果要在 Visual Studio 中生成程序代码或其他应用程序资源,遵守以下一般准则可能非常有帮助. 它们并不是一成不变的规则. 设计时 T4 模板准则 设计时 T4 模板是在设计时在 Visua ...

  6. 今天分享一个抽奖的类Lottery

    /* * Copyright (C) 2014 Jason Fang ( ijasonfang@gmail.com ) * * Licensed under the Apache License, V ...

  7. C++_快速排序

    void quick_sort(int s[],int l,int r) { if(l<r) { int i=l,j=r,x=s[l]; while(i<j) { while( i< ...

  8. selenium python 环境搭建(64位 windows)

    之前写了同样的文章,可是后来自己按照给文章再次搭建环境当搭建环境成功后却发现还是无法用.使用from selenium import webdriver,在run的时候却出现ImportError: ...

  9. Socket的使用

    import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.IOException; import jav ...

  10. javascript 编写的贪吃蛇

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...