13-MongoDB写入安全

本文介绍了MongoDB中不同级别的写入安全策略,包括非确认式、确认式、日志写入及副本集确认式写入等。每种策略都有其适用场景和优缺点,如性能与数据一致性的平衡。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Mongodb写入安全

  • 客户端保存数据到MongoDB,对于数据写入安全有不同的级别,比如Mongodb集群要全部收到,或者只有部分节点收到之类的,这个和Kafka类似,其他的分布式组件估计也会有类似的配置。

一、分类

1.1 Unacknowledged

  • 非确认式写入。客户端发出请求丢到socket的时候就收到响应,客户端不需等待服务器的应答,不能收到服务端的异常响应 。

1.2 Acknowledged

  • 确认式写入。客户端会等待服务器给的确认,这种方式一定能确保服务器收到了客户端的请求,并且服务器异常时能够响应客户端。

1.3 Journaled

  • 日志写入。Journaled方式相比Acknowledged的方式是要保证服务器端已经写入Journaled文件了。Acknowledged方式有可能收到请求后的一瞬间宕机导致数据丢失,但Journaled方式服务器保证写入到磁盘后再响应客户端,即使宕机了也不会数据丢失。

1.4 Replica Acknowledged

  • 副本集确认式写入。适用于Replicasets模式,可以要求有多台机器收到写入请求后再响应客户端,或者直接指定大多数收到后再响应。更安全但是导致了客户端耗时增加,所以要结合自己的场景设置合适的策略。

  • 按照参考文章[2],我们知道journal日志保存到磁盘默认的频率是100ms一次,在没有开启journal的情况下,MongoDB落盘频率是1min每次。

二、设置方式

2.1 服务端

  • 查看MongoDB服务端设置默认的策略。
//副本集
//获取,再设置,再读取
cfg = rs.conf()
rs_shard_server1:PRIMARY> cfg.settings.getLastErrorDefaults
{ "w" : 1, "wtimeout" : 0 }
rs_shard_server1:PRIMARY> 
rs_shard_server1:PRIMARY> cfg.settings.getLastErrorDefaults={ w: "majority",j:true, wtimeout: 5000 }
{ "w" : "majority", "j" : true, "wtimeout" : 5000 }
rs_shard_server1:PRIMARY> cfg.settings.getLastErrorDefaults
{ "w" : "majority", "j" : true, "wtimeout" : 5000 }
rs_shard_server1:PRIMARY> 


//单机
//获取,再设置,再读取
> db.getWriteConcern()
> db.setWriteConcern({w:1,j:true,wtimeout:3000})
> db.getWriteConcern()
WriteConcern({ "w" : 1, "j" : true, "wtimeout" : 3000 })
  • writeConcern函数参数。writeConcern有三个配置,下面给出解析。
参数类型取值范围含义
w整数0/1/大于等于2/majority0表示非确认写入,1表示确认写入,大于等于2表示2个(或者更多)节点写入,majority表示大多数(副本集模式)
j布尔true/false是否写入journal日志
wtimeout整型整数超时时间
W选项:
0:非确认式写入 {writeConcern:{w:0 } }
1:确认式写入;{writeConcern:{w:1 } }说明:这个级别下,对副本集只对主库做确认写入
2:副本级确认式写入;{writeConcern:{w:2 } }说明:这个级别下,副本级第一个slave写入成功后就响应给client
majority:复制级多数节点写入成功后,再响应给client {writeConcern:{w:majority} }

j选项
true/false:表示是否使用Journaled日志写入
{writeConcern:{w:1,j:true,wtimeout:5}}

wtimeout选项
超时设置,超时时间内未响应则返回错误

2.2 客户端

  • MongoDB客户端
db.wirte_concern.insert(doc1,{writeConcern:{w:1,j:true,wtimeout:5}})

2.3 Java客户端

  • Java客户端在初始化MongodbClient的时候通过参数传入,如下:
MongoClientOptions options = MongoClientOptions.builder()
                .writeConcern(WriteConcern.UNACKNOWLEDGED)
                .build();
MongoClient client = new MongoClient(serverAddresses, Collections.singletonList(createCredential), options);

public static final WriteConcern UNACKNOWLEDGED = new WriteConcern(0); //Unacknowledged
public static final WriteConcern ACKNOWLEDGED = new WriteConcern((Object) null, null, null, null);//Acknowledged
public static final WriteConcern JOURNALED = ACKNOWLEDGED.withJournal(true); //Journaled
public static final WriteConcern REPLICA_ACKNOWLEDGED = new WriteConcern(2); //副本级确认式写入
public static final WriteConcern MAJORITY = new WriteConcern("majority"); //大多数确认
模式Java客户端MongoDB客户端
非确认式写入(Unacknowledged)UNACKNOWLEDGED = new WriteConcern(0){writeConcern:{w:0 } }
确认式写入(Acknowledged)ACKNOWLEDGED = new WriteConcern((Object) null, null, null, null){writeConcern:{w:1 } }
日志写入(Journaled)JOURNALED = ACKNOWLEDGED.withJournal(true){writeConcern:{w:1,j:true,wtimeout:5}}
Replica Acknowledged(指定节点)REPLICA_ACKNOWLEDGED = new WriteConcern(2){writeConcern:{w:2 }}
Replica Acknowledged(多数节点)MAJORITY = new WriteConcern(“majority”){writeConcern:{w:majority }}
Replica Acknowledged多数节且日志写入WriteConcern.MAJORITY.withJournal(true){writeConcern:{w:majority,j:true,wtimeout:5}}
  • 在Replica Acknowledged模式下,可同时指定确认的节点数量和日志写入,比如{writeConcern:{w:3,j:true,wtimeout:5}就表示需要3个节点确认且需要写入Journale日志。Java中表示如下(fsync表示暴力将数据刷到磁盘):
    WriteConcern writeConcern = new WriteConcern(3);
    System.out.println(writeConcern.toString());
    WriteConcern writeConcern1 = writeConcern.withJournal(true);
    System.out.println(writeConcern1.toString());
        
    //打印
    WriteConcern{w=3, wTimeout=null ms, fsync=null, journal=null
    WriteConcern{w=3, wTimeout=null ms, fsync=null, journal=true
    
    
    //多数节点,并且开启Journal
    WriteConcern.MAJORITY.withJournal(true)

三、小结

  • WriteConcern用于控制写入安全的级别,可以分为应答式写入以及非应答式写入,它是一个性能和数据强一致性的权衡,应根据业务场景进行设定,对于强一致性场景,建议w>1或者等于majority以及journal为true,否则w=0
  • 在副本集的情形下,建议通过配置文件来修改w以及设置wtimeout,以避免由于某个节点挂起导致无法应答

四、参考

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值