介绍软件工程领域一些通用的设计方案。
Lease
通过 Lease 可以解决或者缓解下面的一些问题:
- 减少 invalidation 检查的开销
- 减少惊群带来的大量无效计算
Backoff
Cache
Partial Ordering
通常面临这样的场景,很多个命令构成了全序关系,但其实它们可以被拆成多组彼此 concurrent 的偏序关系:
- 在 NewSQL 的事务层+共识层的架构中,将 (start_ts, commit_ts) 的事务拆到多个共识组中,多个共识组之间可以并发 apply。对于共识组中不相交的事务,可以通过并行 apply 继续提高并发度。
- CPU 中的 superscalar 技术
GC
我们往往在异步线程中预处理一些对象,并最后将它们 link 到主干上,或者从主干上 unlink 对象,并最后 gc 掉。如果这中间发生重启,那么这些对象就会游离在存储中。如何区分被 unlink 但尚未被回收的对象,和刚被创建但还没有被 link 的对象呢?这里的通用思路是在重启后对比主干和存储中的对象,所有不出现在主干中的对象就需要被删掉。然后依赖重放来解决第一种情况。
Trade off
读和写
锁和非锁
锁意味着串行逻辑,通常用来避免写写冲突。
非锁的方案往往涉及多个版本:
- CAS 的方案本质上是异步完成新版本的构建,再原子替换上去。它并不是避免冲突,而是在冲突时退出。
- MVCC 的方案本质上是让读不会阻塞写,解决读写冲突。
类似的思想出现很多:
- TiDB 中使用乐观锁或者悲观锁处理写写冲突,通过 MVCC 处理读写冲突。
- Masstree 中使用锁解决写写冲突,引入版本号解决读写冲突。
- Snapshot Isolation 中,读不会被写影响。