Heim > Fragen und Antworten > Hauptteil
RT,
听人说过:
20M的情况下插入1百万的数据进行分片,会丢数据
63M的情况下插入6千万条的数据进行分片也有丢数据的情况
不同的mongodb版本也有差异
大伙对这个值有经验吗?
高洛峰2017-05-02 09:20:15
“丢数据”和chunksize是两个不相关的东西,并没有直接的逻辑联系,不知道什么人会把这两个东西扯到一起说给你听。由于我也不知道具体指的什么样的特定场景出现丢数据,所以就我所知道的情况,给出一些可能会对你有用的答案。
看起来你关注的是丢数据的问题而根本不是chunksize,再者通常情况下chunksize保留默认值就没有什么问题,所以chunksize的问题我就略过了。
就“丢数据”做一些说明。对于任何一个数据库,无理由的丢数据都是不可容忍的。所以出现了丢数据的情况,要么是
出现了不可抗拒的因素,比如断电,硬件损坏,网络故障等
配置原因
软件出现严重bug。
对于1反正你也无能为力了,这点应该通过ReplicaSet的复制功能来尽可能减小影响。
第2点,如果你没有开journal(默认已打开),遇到断电或者程序crash的情况,可能会丢失30ms内的数据。如果数据非常重要不能容忍30ms的丢失,请打开j参数:
mongodb://ip:port/db?replicaSet=rs&j=1
(以上参数也可能通过代码按单次请求的粒度来指定,请查阅你使用的驱动文档)
这个参数确保数据写入时阻塞到journal写到磁盘上为止。
但是你以为数据落盘就算安全了吗?记住这是分布式环境,单台机器的数据安全并不能代表集群。所以在万一的情况下,journal虽然落盘,但是还没来得及复制到replica的其他结点上,然后primary
正当掉了,就会有其他结点通过选举成为新的primary
,这时候就会发生一个有意思的情况叫做rollback,有兴趣可以阅读一下。当然通常复制的速度是非常快的,发生rollback的情况非常稀有。好吧你可能还是觉得不够安全,那还有一个w参数可以使用:
mongodb://ip:port/db?replicaSet=rs&j=1&w=1
w参数可以确保写入操作被阻塞直到数据落到多个结点上(w=1/2/3...n)。
那这样就安全了吗?sorry,特别倒霉的情况下(真应该去买彩票),你把数据复制到了多于一个结点上,万一这组结点同时失效了怎么办?所以有了w=majority(大多数)。当集群失去大多数结点的时候会变为只读状态,所以不会有新数据写入,也就不会有rollback。当一切恢复之后,你的数据还在。
以上是一些会出现数据丢失的情况,可以想象w和j的配置在数据安全性得到保障的同时,肯定会很大程度上影响写入效率。这实际上应该是你根据你对数据丢失的容忍程度自己定制的策略,不算是bug。
另外想到一点,在社区经常遇到有人喜欢干这种事情:
kill -9 mongod
要我说简直太残暴了,干嘛一上来就用大炮打蚊子。这种情况下出现数据丢失只能说活该。实际上,
kill mongod
是安全的,但是-9就是你的不对了。
至于第3点,mongodb在开发过程中确实出现过导致数据丢失的bug,3.0.8-3.0.10是重灾区,避开这几个版本。话说回来,哪个软件开发过程中不出现点问题呢?3.0.10发现问题的当天就出了3.0.11,修复速度已经快得可以了。
好了,说了这么多,也不知道对题主有没有用。还是提醒一下,尽可能把问题描述清楚,不然只能像我这样猜测你到底在什么样的场景下遇到了什么样的问题,最可能出现的情况就是那句老话:
Garbage in, garbage out