免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 1282 | 回复: 0
打印 上一主题 下一主题

[MongoDB] 谈谈给Mongo买保险 [复制链接]

求职 : Linux运维
论坛徽章:
203
拜羊年徽章
日期:2015-03-03 16:15:432015年辞旧岁徽章
日期:2015-03-03 16:54:152015年迎新春徽章
日期:2015-03-04 09:57:092015小元宵徽章
日期:2015-03-06 15:58:182015年亚洲杯之约旦
日期:2015-04-05 20:08:292015年亚洲杯之澳大利亚
日期:2015-04-09 09:25:552015年亚洲杯之约旦
日期:2015-04-10 17:34:102015年亚洲杯之巴勒斯坦
日期:2015-04-10 17:35:342015年亚洲杯之日本
日期:2015-04-16 16:28:552015年亚洲杯纪念徽章
日期:2015-04-27 23:29:17操作系统版块每日发帖之星
日期:2015-06-06 22:20:00操作系统版块每日发帖之星
日期:2015-06-09 22:20:00
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2016-09-05 15:03 |只看该作者 |倒序浏览

小贴士:
在MongoDB中,知不知道为何通常搭复制集推荐至少要选1主2从,而不是1主1从?
事实上,道理很简单,避免单点故障。有人说了1主1从不是就是为了避免单点故障吗?何必多此一举?乍一看是这么回事,但是细细想一下,有哪套系统不需要停机维护,利用MongoDB的副本集可以进行滚动维护,1主1从这时就有点悬了,从节点维护时,不就出现单点故障了吗?所以从严格意义上讲,1主1从不是一个最佳选择。

如何快速建立副本集?命令行?脚本?显然不是,正解当然是企业版MongoDB OpsManager,这才是自动化运维利器!

随笔正文该不该买保险?

本人是很讨厌保险的,原因是自己数学虽还不错,但是斗不过精算师啊!当然啦,这不是根本原因,真要高收益回报,买保险是不行的。讨厌保险源自国内卖保险的销售实在太烂,完全是连蒙带骗太不靠谱。但是香港AIA买过一次保险后,香港本地保险代理人的职业素养还是让我对保险的态度有所改观的,所以要买保险真心该到香港去买,加上本人长期看淡人民币,从投资角度来说也该去香港买,毕竟港币是挂钩美元的。

Mongo里的保险

话归正传,继续偶的科普随笔。今天谈的是MongoDB的保险,不是广告推销AIA保险。所以,首先要牢记一点,在MongoDB里面缺省情况下是基本上是可以理解为不买保险的,所以无论你用什么MMAP还是WT引擎往数据库里塞数据,数据库一旦发生异常,就存在倒霉蛋会丢数据 。为什么?想想非关系型数据库为何而生,最初是为了处理大量数据的同时还要确保速度,所以在高速处理的指引下设计的缺省无保险原则也就顺理成章。
可是,场景铺开了,并非每个场景的数据都是只要量不要质的。所以必须赋予使用者一个选择权,至于说你买不买保险是你的事情,这才民主么!在MongoDB中,其中的一个民主权就是WriteConcern,另外一个是他的兄弟ReadConern。

“写保险”

先来谈谈WriteConcern,直译太别扭,所以本人就把他叫做“写保险”吧。

先需要解释一下数据进入MongoDB的过程:首先写操作是会进入到服务器内存中的,内存中有两类结构,一个是数据库缓存,以WiredTiger为例,叫WT Cache,定期会和磁盘同步,确保数据的持久性;另一个结构是journal,可以理解为先行日志,记录到底写操作更新了什么。只要journal被同步到磁盘上,那么万一数据库崩了,起码可以通过journal恢复数据。所以简单来说,journal是个备胎。
缺省情况下如果不做任何配置修改,是w=1,j=0。什么意思呢?实际上代表买了基本没有保险,或者说买了个超级基础保险,w=1表示数据被写到了1台服务器的内存中,而且确保在内存中的操作是成功的,这时数据库就返回成功标志,应用认为写操作完成。注意到此时数据是在内存中,未必被同步到磁盘上;同时j=0表示写操作确认是不用管journal是否被同步到磁盘中的。换而言之,备胎机制是不生效的,异常情况下不能找备胎来哭诉。

既然出事了没有保障,为何叫做初级保险呢?因为毕竟MongoDB还是保证了你每个写操作是有一个确认的动作的,只要数据库正常运作,数据一定会被同步到磁盘中,只是时间问题而已。事实上,还可以更加生猛,不买保险:w=0, j=0。一个劲的写,不管写是不是成功。有人问了,这个貌似完全没有用?事实上确实有,场景可以用,比如网络页面的计数器,日志记录等等,数据丢了就丢了么,无伤大雅,反过来以计数器为例如果每次加1的动作都要确认,万一来个网络延迟,完全得不偿失。

一般而言,用MongoDB,你还是需要买个基本险的,也就是w=1, j=1,这样每次写成功代表了journal一定被同步到了磁盘上,起码出问题时数据可以恢复。

那如果我们现在有个推荐1主2从的复制集时候,该如何买保险呢?显然这时候买一份保险就不够了,继续w=1,j=1的问题在于如果主节点彻底挂掉,从节点变主节点时如果有一部分数据还没同步到这个新的主节点时,那么就会有数据丢失现象。所以,起码我们要买2份保险,w=2,j=1,这时数据会被确保在主节点并同步另外一个从节点上后才认为写操作完成,显然主节点崩掉时,至少有一个从节点还有刚才最新的数据,它自然会被升级成新主节点。值得注意的是,这个同步是只到内存中的,换而言之并不保证从节点的journal是否已经被保存到磁盘上。所以真的遇到倒霉蛋,还是有可能丢数据的,当然同时挂掉多台服务器是超小概率事件。

更多实战中,是会把这份保险变成一个加强版的,w=’majority’,好比民主投票时搞定多数人就ok了。当然喽,特别谨小慎微的可以考虑买个w=3 (all),让所有副本集都齐步走,这下就绝对安全可靠了。

平衡点

当然保险不是免费的,给最多保障的一定是花费你最多的(也就是最耗时的)。站在数据库的角度来说,w=0基本上是面向无连接的,完全没有开销,而w=3 (all)显然时间开销最大,需要等待网络同步,到底花几个钱买哪类保险是仁者见仁,智者见智的问题。

分期付款?

说完了保险品种,我们来看看如何买法?我们知道买保险可以买一次性的,也可以买1年的,还可以买一生的,这个在MongoDB中亦是如此。你可以针对一个连接设置保险系数,也可以针对一个Collection设置,还可以针对一个复制集来设置,灵活度绝对没有问题。以一个连接来看,下面是一个例子供参考:

XXX.MongoClient (host=”mongodb://localhost:27017”, replicaSet=”danielrs”, w=3, wtimeout=1000, j=True)

组合险

最后谈谈组合保险,使用MongoDB更多时候是在和MongoDB的驱动打交道,也就是写代码调用API。由于代码可以非常灵活处理你想要的,所以可以在速度和可靠性间取个平衡,于是可以插入数据的时候,每隔一段时间做个可靠性保证,既确保速度,又顾及数据的持久性。下面就是一个简单的例子,每200次数据插入确保数据插入是majority入库,其他就不用上保险了。

最后提一句,可以利用标签(Tag),为服务器打上标签,w参数后跟上,来确保写入操作被写入到对应的标签机器上,这可以实现数据定向写入。

好吧,关于“写保险”应该差不多了,有空再谈谈ReadConcern“读保险”吧。


您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP