通用架构设计归纳

介绍软件工程领域一些通用的设计方案。

Lease

通过 Lease 可以解决或者缓解下面的一些问题:

  1. 减少 invalidation 检查的开销
  2. 减少惊群带来的大量无效计算

Backoff

Cache

Partial Ordering

通常面临这样的场景,很多个命令构成了全序关系,但其实它们可以被拆成多组彼此 concurrent 的偏序关系:

  1. 在 NewSQL 的事务层+共识层的架构中,将 (start_ts, commit_ts) 的事务拆到多个共识组中,多个共识组之间可以并发 apply。对于共识组中不相交的事务,可以通过并行 apply 继续提高并发度。
  2. CPU 中的 superscalar 技术

GC

我们往往在异步线程中预处理一些对象,并最后将它们 link 到主干上,或者从主干上 unlink 对象,并最后 gc 掉。如果这中间发生重启,那么这些对象就会游离在存储中。如何区分被 unlink 但尚未被回收的对象,和刚被创建但还没有被 link 的对象呢?这里的通用思路是在重启后对比主干和存储中的对象,所有不出现在主干中的对象就需要被删掉。然后依赖重放来解决第一种情况。

Trade off

读和写

锁和非锁

锁意味着串行逻辑,通常用来避免写写冲突。
非锁的方案往往涉及多个版本:

  1. CAS 的方案本质上是异步完成新版本的构建,再原子替换上去。它并不是避免冲突,而是在冲突时退出。
  2. MVCC 的方案本质上是让读不会阻塞写,解决读写冲突。

类似的思想出现很多:

  1. TiDB 中使用乐观锁或者悲观锁处理写写冲突,通过 MVCC 处理读写冲突。
  2. Masstree 中使用锁解决写写冲突,引入版本号解决读写冲突。
  3. Snapshot Isolation 中,读不会被写影响。