Skip to content

Instantly share code, notes, and snippets.

View ideawu's full-sized avatar
🎯

吴祖洋 ideawu

🎯
View GitHub Profile
@ideawu
ideawu / C++思维误区.md
Created December 11, 2020 04:36
C++思维误区

写 C++ 的程序员, 特别是那种只写 C++ 的程序员, 尤其是只写 C++, 还有点擅长的程序员, 会有很多思维误区.

例如, 抽象能力不足.

在做系统设计时, C++ 程序员往往在形式化上面进行抽象, 就跟 C++ 语言一样, 主要在语法层面提供特性, 因为 C++ 就是要在编译时解决问题. 但 Java 程序员, 或者使用其它面向对象编程语言的程序员, 一般是在本质层面进行抽象.

不是说, 关注本质的程序员就更好. 只是, 很悲哀的, C++ 程序员往往"浮于表面"而不自知, 反而认为自己专注底层, 做的是核心, 实则太过于追求形式化.

@ideawu
ideawu / 分布式事务与2PC.md
Last active December 11, 2020 10:21
分布式事务与2PC

分布式事务架构中, 存在一个独立于参与者之外协调者单点(Commit Point), 当参与者存在未决(In-Doubt)事务时, 需要向单点求证. 所以, 在两阶段(2PC)事务处理流程中, 除了写单点之外, 还必须保证参与者也有 Commit Point. 否则, 如果参与者缺失 Commit Point, 而此时协调者的 Commit Point 已经丢失, 在参与者进行日志回放时, 便无法处理 In-Doubt 事务.

因此, 有几个要点:

  • 分布式事务是由一个根事务(Commit Point)和多个参与者事务组成的树形结构
  • 根事务必须先于子事务进行提交, 子事务必须明确提交(Phase 2)
  • 子事务完成 Phase 1 之后, 处于 In-Doubt(Uncertain) 状态
  • 读操作遇到 In-Doubt 状态的参与者时, 必须向父节点求证其真实状态
  • 写操作遇到 In-Doubt 状态(Locking)的参与者时, 不能写
  • 子事务不要采用读修复技术, 必须经过明确的 Phase 2 明确提交, 也即子事务本身也要有 Commit Point
@ideawu
ideawu / Optimistic and Pessimistic Transaction.md
Created December 7, 2020 07:07
乐观事务和悲观事务

使用方式

悲观事务

begin
operations...
commit/rollback
@ideawu
ideawu / Share-Nothing.md
Created December 5, 2020 07:44
Share-Nothing

个体是单独存在的, 个体之间不知道其它个体的存在. 例如, 分布式数据存体系中的存储节点(Tablet Server, Region Server), 每一个节点都是独立运行, 每一个节点不知道其它节点的数据情况(当然, 如果它想知道也可以知道, 但它的运行不依赖知道与否, 知道也可以, 不知道也可以).

Shard Nothing 就是 Sharding.

@ideawu
ideawu / 3PC.md
Last active December 4, 2020 08:31
三阶段提交

两阶段提交有一个优点, 那便是 Prepare 的成本比较高, 资源执行时间较长, 失败概率较高. 而读流程遇到 Prepared 状态的资源, 需要向单点(Commit Point)查询求证资源的真实状态, 极大的拖慢了读流程.

第1步, 要求所有资源进入 Preparing 状态, 同时关联变更操作, 对于该状态, 读流程不需要向单点查询求证.

第2步, 要求所有资源进入 Prepared 状态, 这个操作成本极小.

第3步, 要求各资源清理状态.

@ideawu
ideawu / Transaction Implementation without Dedicated Commit Point.md
Last active December 12, 2020 10:16
一种不依赖事务管理中心实现事务原子性的方法: 参与者单向环
  • 在 Prepare 阶段, 将所有参与者以单向环的方式连接起来, 同时 Prepare 变更
  • 单向环一旦建立起来, 事务便已自动 Commit
  • 依次将所有参与者 Commit
  • 所有参与者都 Committed 之后, 依次解除单向环.

如果事务异常中断, 那么正常的读取流程读取到任意一个参与者时, 开始检测圆环. 若能检测到, 便能判断出事务的状态(Committed). 若圆环断开, 则事务处于 Aborted 状态.

@ideawu
ideawu / ACID - Consistency.md
Last active December 11, 2020 06:06
数据库事务的一致性

比较难理解. 是指事务完成后, 结果必须和预期一致, 不能产生非期望的后果. 例如, 期望将某个数据修改为 1, 但最后得到的结果却是 30, 不符合预期, 和预期不一致.

结果是可预测的, 唯一的. 无论重放多少次, 结果都一样.

@ideawu
ideawu / ACID - Atomicity.md
Last active December 3, 2020 05:00
数据库事务原子性
  • 问题: 多个独立的操作, 如何成为一个原子操作?
  • 答案: 依赖一个支持原子操作的地方(单点).

实现方案:

  1. 单点单标记, 指示中间态的数据(资源)的真正状态 - Commit Point
  2. 单点多标记, 保存所有资源的中间状态(需要用原子操作来保存事务涉及的多个资源的状态)
  3. 单点副本, 先在单点修改数据, 再异步地复制数据到最终的目的地 - Redo Log

经典的 2PC: 两阶段修改, 单点提交(确认). 属于方案1 - 单点单标记.

@ideawu
ideawu / 线性一致性定义.md
Last active December 2, 2020 04:35
线性一致性定义

线性一致性三大约束

  1. 写操作完成后, 后续的读操作一定会返回不早于该次写操作的新值
  2. 如果某一次读操作返回了新值, 则后续的读操作一定会返回不早于该值的新值
  3. 如果两次操作的时间区间有重叠, 则两次操作不区分前后
@ideawu
ideawu / 计算机入门 - CAS.md
Last active December 2, 2020 04:44
计算机入门: CAS

CAS(Compare And Set) 是一种避免错误地修改数据的手段. 举一个可以使用 CAS 的场景:

某工厂老板通过邮件告诉公司出纳, 要给某供应商打款. 因为工作流程失误, 有两个出纳都进行了打款. 款项被错误地打了两次. 如果工作流程没有问题, 或者公司的出纳只有一位, 依然可能出现打款两次的错误.

要解决这个问题, 可能你已经想到解决方案了: 给这次任务分配一次性的密钥, 拥有密钥的人才能打款, 密钥用完就失效.

CAS 的思路类似. 我们给数据加一把锁, 锁有密码, 只有拥有密码的人才能修改. 特别的, 密码是一次性的, 用过一次就会失效. CAS 一般用整数版本号来表示锁, 修改后, 版本号加1, 原来的锁自然就失效了.

任何一个系统, 如果实现了一次性写锁(密钥), 则这个系统拥有了 CAS 能力.