文档数据库服务实例采用多副本存储数据,其中一个副本的角色是 primary 接受数据写入,其他节点通过 oplog 同步数据变更。
如果 primary 节点在成功写入数据后就宕机了,但是数据还没有被其他 secondary 节点同步。此时后台会重新选举一个正常的 secondary节点为新 primary 节点,但是这个新 primary 节点不包含最新写入的数据。而原 primary 节点在修复完成并重新加入到副本集之后会成为 secondary 节点,之前最新写入的数据会进行 rollback。
为了避免 primary 节点意外宕机导致部分数据被回滚的情况,用户可以指定 write concern 设置写入级别,指定数据成功复制到多少个节点之后再返回。
Write concern 指定的格式如下:
{ w: <value>, j: <boolean>, wtimeout: <number> }
其中 w 指定了数据成功复制到多少个 mongod 节点之后再返回结果给客户端(包含 primary 节点自己),常用的配置包括:
- 数字。比如 0、1 等。
- "majority"。服务端会根据副本集当前有投票权的节点个数自动计算大多数节点的个数,比如 3 个 mongod 节点的副本集,每个 mongod 节点默认都有投票权限,则 "majority" 个数为 2。
参数 j 表示是否后台写完 journal 再返回成功,可以指定为 true 或者 false。如果 w 指定了 “majority”,则默认 j 为 true。
wtimeout 表示操作的执行超时,以毫秒为单位,在 w 大于 1 时生效。
对于 3 副本的节点,建议 w 指定为 "majority",并根据业务的实际需求指定 wtimeout。这样可以避免主节点在意外宕机后出现的部分数据丢失,通过能兼顾较好的可用性。使用示例如下:
db.coll.insert({a:1}, {writeConcern: {w: "majority", wtimeout: 1000}})