MVCC(Multi-version Cocurrent Control)多版本并发控制,用无锁的方式解决数据库的读写冲突。数据库中为数据同时保存多个版本的快照,每次写入数据都产生新的版本,而读数据只会读取到已经提交快照,这样读写操作不会互相阻塞,也避免了脏读的问题。
etcd 的 mvcc 这个包不像 wal 和 lease 那么简洁明了,有大量抽象的接口,接口之间还互相组合,刚看到这里的时候一头雾水,再深入看了一会一脸懵逼,经过一系列复杂的嵌套引用之后,不经陷入了人生三问
没办法我回去看了一下 etcdserver 中是怎么用的,在 etcdserver 中找到了最终使用的是 ConsistentWatchableKV
// mvcc/watchable_store.go
func New(lg *zap.Logger, b backend.Backend, le lease.Lessor,
ig ConsistentIndexGetter) ConsistentWatchableKV
这个 ConsistentWatchableKV 的定义如下(简化过后)
// ConsistentWatchableKV is a WatchableKV that understands the consistency
// algorithm and consistent index.
// If the consistent index of executing entry is not larger than the
// consistent index of ConsistentWatchableKV, all operations in
// this entry are skipped and return empty response.
type ConsistentWatchableKV interface {
KV
// NewWatchStream returns a WatchStream that can be used to
// watch events happened or happening on the KV.
NewWatchStream() WatchStream
// ConsistentIndex returns the current consistent index of the KV.
ConsistentIndex() uint64
}
type KV interface {
ReadView
WriteView
// Read creates a read transaction.
Read() TxnRead
// Write creates a write transaction.
Write() TxnWrite
// 此处省略了一些接口
...
}
如字面意思,ConsistentWatchableKV 有三层含义
对于 KV 我们 暂时 只关注其中的 Read
和 Write
操作,可以发现 KV 实现了
ReadView
和 WriteView
接口Read() TxnRead
和 Write() TxnWrite
这个 TxnRead
和 TxnWrite
接口里面又嵌套了 ReadView
和 WriteView
type TxnRead interface {
ReadView
...
}
type TxnWrite interface {
TxnRead
WriteView
...
}