极牛技术实践分享活动
极牛技术实践分享系列活动是极联合顶级VC、技术专家,为企业、技术人提供的一种系统的线上技术分享活动。
每期不同的技术主题,和行业专家深度探讨,专注解决技术实践难点,推动技术创新,每两周的周三20点正式开课。欢迎各个机构、企业、行业专家、技术人报名参加。
本期大纲
MongoDB是啥?特点及适用场合?
高可用如何做?
性能调优?
监控与排错?
嘉宾介绍
魏佳,先后就职于IBM创新技术研究院、新浪微博平台架构部及新浪微博技术评审委员会、Mico联合创始人及CTO,现任LinkedIn中国技术主管。对企业级应用技术、虚拟化技术以及分布式消息中间件有深入的研究。对大规模分布式系统、高并发Web系统,主流通信系统的技术栈和协议有丰富的工程经验。 同时具备扎实的计算机科研技能,著有多篇中外技术专利。从技术架构层面支撑其从0到千万级注册用户,日均百万级活跃用户,日均千万级消息量的发展和演进。
MongoDB的话题
今天的话题主要围绕以下几个方面吧:1. What? 2. Why? 3. How?
首先MongoDB作为NoSQL兴起时的一个代表,最近这些年发展非常迅速,同时使用也很广泛。一两句来说MongoDB是什么?有10gen公司来开发和维护,由C++开发,支持众多的语言。feature层面,它是document-based,同时是DDL free的,不说schema free是因为很多场景中还是需要schema的。重要的是它easy tounderstand/learn and use,同时支持server-side script。此外,spatial index,GridFS以及有限度的MR的支持,也拓宽了它的使用场景。
为什么选择MongoDB呢?
首先说到选型问题,我认为技术决策和选型的过程首先要抛弃先入为主的狭隘思维。没有万能的工具,只有最合适的工具。“不考虑场景的唯XX论”的观点我个人很不认同。
具体到几方面:
社区活跃和支持程度。MongoDB的mailing list和community非常得活跃,同时响应很迅速。
生态完善程度,包括文档、辅助工具,以及是否方便得与既有基础设施或工具集成。
这些方面使得学习和掌握的过程变得容易。
场景方面:
对于大部分startup,需要的是快速的业务迭代,这往往意味着需求的不稳定性,映射到产品和技术层面,可能就是模型的频繁变化,所以DDL(schema)-free是个诱人的优势。
非强事务的场景,对于ACID要求严格的场景那肯定是传统的RDBMS更为合适。
对spatialindex的支持很好,适合现在很多流行的空间查询场景,比如类似“周围的XX”,“多边形关系”等。
开箱即用的一些分布式能力支持,这个对于startup初期,尽量减少devops的时间和精力还是很有必要的。
高可用如何做?
MongoDB具备开箱即用的复制集能力,通过典型的Primary+Secondary+Arbiter拓扑来构建复制集。
基本的结构就如这幅图:
搭建非常容易,参考官方的手册即可。复制集通过preference的设置,即可以达到读写分离的要求。MongoDB的选举依赖bully算法,类似其他分布式算法,这方面需要注意的是“奇数实例数”、复制集最多12节点,其中7节点参与选举在3.x版本变化比较大,后面讲到。复制过程依赖oplog,类似MySQL里的binlog,所以设置大小合适的oplog很重要,特别是在复制延迟比较高的场景里。容易产生复制失败而不得不进行全量的resync。
性能调优方面
先来说index相关的。
因为MongoDB查询时先扫index再扫数据,所以查询时如果只要个别字段,而字段又恰恰有index的话,那就可以直接返回这些字段,而省去扫数据的过程。
复合索引的次序问题,这个问题类似用多个漏斗筛东西,尽可能将小漏斗放在前面(左侧),极大地减少后续扫索引的量,可以提高查询的效率。除此之外,插入数据时,也可减少去更新索引树的变化程度。
生产环境建议不要使用sparse index,浪费空间。
对已有数据做创建索引操作,如果是复制集环境,建议离线来做,避免由于建索引的长耗时导致追不上而产生resync过程。
对于索引字段的数据类型的选择,string类型的>>int类型的,所以尽可能减小index的size,确保尽可能将index都放入内存,应该选择合适的索引数据类型。
对于document层面:在满足业务场景的情况下,尽量使用nested document,也就是说建模时尽可能的反范式。一方面减少doc的总数量,同时减少查询时磁盘IO的次数。
此外,doc中field的名字用尽可能短的,这也是为了减小doc的size大小如果业务场景中,doc内有很多text内容同时不会做文本内容的检索,那建议都使用bindata来存。
对于statement方面:用好explain很重要,它是做进一步优化的指导数据。
比如这样的事例:
这部分可以进一步参考官方手册,系统层面,由于是per connection的粒度来创建线程,所以也要关注链接数,和对应操作系统的stacksize。
监控和排错
监控和排错监控的重要性不言而喻,如果已有各类监控基础设施,那集成非常简单。如果暂时没有,推荐munin,或者也可使用官方的mms服务(需要部署agent)。
MongoDB自带的一些监控命令非常有用,比如mongostat和mongoshell中的db.stats。这里需要重点关注pagefault %和lock %,这二者,如果page率高,那需要关注读场景的效率以及数据量和内存的情况。如果lock率高,则要关注写场景。比如合并写,或者异步写的方式。
IO繁忙的时候,数据文件(xyz.n)预分配会堵塞其他操作,这种情况下非常容易造成雪崩效应,所以可以pretouch的方式去创建数据文件。
对于数据碎片化的情况,建议离线的去repair database。通过profile,需要重点关注运行时full scan和update的场景,进而进行进一步的优化,特别是update,如果大部分情况产生了moved,则需要通过填充占位数据的方式去避免。通过explain,需要关注covered indexes和index usage的情况,有针对性的创建或修改索引。
3.x版本是MongoDB非常重要的里程碑,其中有些feature非常有价值。比如提供更高压缩率的压缩方式,zlib和snappy,能有30%~50%的提高,相当于用压榨cpu来换取内存中数据的使用率。
此外,是复制集的改进,明显缩短选举的过程。同时对于心跳检测的过程复用复制的通道,而且可以单独控制选取的超时,这个有利于网络环境差时的选举过程。
对index的改进主要时支持partial index,特别适合索引中目标数据的值在全部数据中占比很小的情况,能极大的减小index的size。
最前面说到有些场景需要schema,所以3.x中支持schemavalidator可以加强schema校验拒绝无效数据。
Q&A
Q1:MongoDB现在的存储引擎是否还存在断电等极端情况的数据安全性无法保障问题 ?
A1:如果是复制集的环境,当前primarycrash了写请求会路由到新的primary上,如果是shard的环境,影响得是局部shard,但是没shard也应是HA的结构。除此之外,对于这种极端情况,应用层也是需要做容错,换做其他组件这种场景也一样。
Q2:创业初期业务多变,选型了MongoDB,随着公司发展,业务也渐趋稳定,也在考虑从MongoDB迁往MySQL,什么阶段迁移比较合适,再者迁移的过程有什么坑没?
A2:首先迁移数据是折腾人的事儿,先想清楚迁移的目的和收益。从性价比角度来说是伪命题,从运维经验掌控程度角度说,也是事在人为的。最后回答你的问题,通常就是应用层双写,之后异步迁老数据,数据对其后,tcpcopy重放的方式来校验数据,都没问题了,就完事儿了。
*此分享由LinkedIn中国技术主管魏佳在极牛线上技术分享群里所分享
【下期重磅预告】
<主题>
【如何守护企业核心数据安全】
<讲师>
陈宇森,北京长亭科技有限公司联合创始人、总裁。
<大纲>
1.介绍黑客入侵的常见思路、手段、目的。
2.通过大量案例分析企业是在哪些关键环节出了疏漏导致发生了入侵事件。
<时间>
下周三(10月26日)晚8:00
有意加入的技术朋友,请在极牛公众号(ji-niu)里回复“技术分享”
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。