mongodb的ACID特性与mysql,redis简单比较
从事务角度看redis更接近mysql,从支持的查询功能看,mongo更接近mysql。
定义:
Atomicityan operation is atomic if it either completes entirely or not at all
Consistency all actions cause the table to transition from one valid state directly to another (eg a row will not disappear during an update, etc)
Isolationan operation is isolated if it appears to complete independently of any other concurrent transaction
Durability any update that reports "successful" to the client will not be lost
Visibility an update is considered visible if any subsequent read will see the update as having been committed
原子性保证:All write operations in MongoDB are atomic on the level of a single document.
批量写,bulkwrite语法:针对同一个集合多个cud操作。不支持类似mysql的事务。无回滚。
默认按顺序执行,出错返回未执行的操作。
可以指定无序批量,mongo会并行执行,出错不会终止执行。
bulkWrite() supports the following write operations:
insertOne
updateOne
updateMany
replaceOne
deleteOne
deleteMany
持久化:
写有同步与异步模式。通过参数调整在持久化与性能之间平衡。
{ w: <value>, j: <boolean>, wtimeout: <number> }
w:majority:写请求已被传播到多数节点,(含主节点)才确认。日志是否已持久化看参数j
j:true w指定数量节点或多数节点日志已持久化才确认。
读和写模式密切相关。写日志持久化与否影像到读的一致性。
当j:false时,日志并未持久化到硬盘,只是在内存中,所以此时failover都有可能出现读不一致。
读:
readPreference
控制从复制集的哪个节点读取数据,这个特性可方便的实现读写分离、就近读取等策略。默认primiry。readConcern 用来控制读一致性,用户可以在性能和一致性之间取舍
The readConcern option is available for the following operations:
-
findcommandaggregatecommand and thedb.collection.aggregate()methoddistinctcommandcountcommandparallelCollectionScancommandgeoNearcommandgeoSearchcommand
为简化讨论,下面讨论基于w:majority,j:true,readPreference:primiry
常见场景:遍历find返回的cursor。
-
- local 默认,总是读取最新的数据,表明客户端可以看到还未被持久化的数据。集群环境下,可能只有primiry完成写,而不是多数节点完成。这时primiry failover后再上线会回滚数据。(会出现读未提交。)
- majority 返回已被多数节点写成功的数据。注意多数确认写成功可能不是最新的(因为最新的可能只有primiry成功了,而不是多数成功)。(隔离并发的未提交写)
- linearizable ,返回已被多数节点确认为写成功,且早于本次读之前修改的数据(所有并发写都被隔离)。
- mysql 提供多语句打包事务语法(begin,commit)事务是并行的,通过隔离级别来提供一致性,提供行锁来保证资源不会被并发修改。
- redis提供多语句打包事务语法(multi,exec)事务是串行执行的,不会并发修改,不提供锁,但是通过watch机制保证在事务执行前资源被修改终止当前事务执行。另外因为串行事务的隔离界别,不会有并发修改。
- mongo 无多语句事务语法。另外单条update涉及多文档时也非原子执行。find涉及多文档时可以通过
readConcern进行并发修改隔离。不支持mysql中常见的多表多行的事务,也不支持单表多行事务,其批量语法可能部分成功,只能使用补偿机制,达到最终一致性。 - mongo针对update涉及多文档时,提供的
$isolated可以保证update多文档不会有并发访问。但是不提供回滚。(不支持分片集群。) - mongo的 two-phase commits 提供transaction-like semantics.
- mongo建议使用唯一索引和版本控制并发。这在mysql中也很常见。
浙公网安备 33010602011771号