• 2021-06-06

    可靠通信的三条基本定理(可靠通信三原则)

    Views: 8688 | 2 Comments

    "通信"是一个广义的概念, 不仅限于计算机网络通信, 任何抽象或者具体的对象间的交互行为, 都是一种通信. 对象间一旦进行通信, 便有可靠通信的需求. 可靠通信至少包括三项要求:

    1. 不丢包
    2. 不重复
    3. 完整性(原子性)

    为了达到这三项要求, 对应有三条定理(可靠通信三原则):

    • 定理一(重传定理): 确认和重传是解决丢包问题的唯一正确方法
    • 定理二(去重定理): 排队(串行化)是解决去重问题的唯一正确方法
    • 定理三(原子定理): 单点标记或者循环自校验是实现完整性(原子性)的唯一正确方法

    有些同学可能对排队理论有怀疑, 表示搞一个全局位图(标记集合)也能解决去重问题. 如果深究, 判断标记和修改标记是独立的两步操作, 这两步操作就遇到去重问题, 也即, 对标记集合的操作本身也需要排队. 当然, CAS 是一种解决方案, 但 CAS 的实现内部本质也是排队.
    Continue reading »

    Posted by ideawu at 2021-06-06 13:50:46
  • 2021-06-03

    分布式数据库系统如何做到平滑缩扩容?

    Views: 4332 | No Comments

    分布式数据库系统的缩扩容能力(后面也称迁移)是最基础最基本的特性, 但是, 要实现平滑扩容并不容易, 需要服务端和客户端共同完成, 这两者只要缺少任何一方的参与和配合, 便绝不可能实现平滑扩容.

    平滑迁移要解决的问题, 本质上就是故障容错(转移)处理.

    客户端请求重试

    请求重试是故障容错的最基础要求, 因为你永远无法避免遇到故障. 遇到故障时, 要么报错, 要么重试. 既然我们追求的是平滑, 那么, 一旦遇到故障, 绝对不能向上层反馈, 只能重试.

    重试要配合服务发现, 不然故障点一直不恢复的话, 重试也没用.

    重试策略的关键在于识别出可重试的故障, 对于某些故障, 如网络故障, 客户端无法确保请求到底有没有实际发出去, 或者已经被服务端处理, 冒然重试, 会导致非预期的后果.

    实际上, 所有的接口的结果不是一般人所理解的两态(成功或者失败), 而是三态(成功, 失败, 未知). 对于未知结果, 我们什么也做不了, 只能向上反馈(向业务层报错), 这种情况, 无法重试, 也就无法容错.
    Continue reading »

    Posted by ideawu at 2021-06-03 22:41:55
  • 2021-05-28

    分布式系统升级所遇到的问题

    Views: 6276 | No Comments

    常规的单机软件升级, 一般认为是一个原子操作, 也就是说, 软件会在"瞬间"完成升级, 即使不能在"瞬间"完成升级, 也要中断服务, 等升级完成后再提供服务.

    对于需要中断服务的情况, 在分布式系统中是不能接受的. 同时, 分布式系统的升级永远不可能在"瞬间"完成. 因此, 分布式系统升级会面临一个长时间的中间态, 新旧版本的软件同时运行, 这就涉及到兼容性问题.

    假如, 新版本的软件的数据格式改变了, 那么, 新版本写入的数据就无法被旧版本识别, 旧版本就会报错. 因为, 新版本的软件很容易做到向后兼容(新的兼容旧的), 但是, 向前兼容(旧的兼容新的)依赖预见性, 不可能预见全部未来.

    如果分布式系统无法做到向前兼容, 这时候, 应该怎么办呢? 难道要停服升级?

    一个常用的解决方案是在旧版本和新版本之间插入一个中间版本. 这个中间版本的主要特点是不写入新格式的数据, 但能识别新格式的数据.

    我们先逐步把旧版本替换为中间版本, 在这个过程中, 因为没有新格式的数据产生, 所以没有兼容问题. 等旧版本全部替换完毕后, 逐步升级为新版本, 在这个过程中, 虽然新旧格式的数据都有, 但新版本都能识别, 也没有兼容问题

    Posted by ideawu at 2021-05-28 21:09:45
  • 2021-05-21

    Raft 为什么不能直接 commit 前任的日志?

    Views: 5845 | No Comments

    有一些文章, 包括 Raft 协议的论文, 已经从反例的角度解释了为什么不允许 Leader 直接 commit 前任的日志, 而是必须追加本任期的一条日志, 以达到隐式地 commit 前任的日志. 我想从 Raft 的几项原则的角度, 在逻辑上解释这个问题.

    Raft 策略1: 节点的日志一旦 commit 便不可撤销

    某个节点的一条日志, 一旦 commit 它, 那么就会对状态机造成不可逆的改变. 也许某些状态机有回滚功能, 但在 Raft 的架构中, 假设状态机不可回滚. 因此, 日志一旦 commit, 便不可撤销.

    注意, 这里用的是"策略"一词, 表明这是人为规定的规则, 不是客观存在的定理.
    Continue reading »

    Posted by ideawu at 2021-05-21 23:07:29 Tags:
  • 2021-05-08

    Binlog, Redolog 在分布式数据库系统中的应用

    Views: 4674 | No Comments

    系统结构

           request
    client -------> server
    

    在一个系统中, 有 client 和 server 两个角色, client 向 server 发起请求(request), 这里的请求指写数据请求, 例如某条类似 "update table set a=1" 这样的 SQL 语句. 我们把 server 进行拆分, 得到下面这个更细化一些的系统结构:

           request         write
    client -------> server -----> database
    

    Server 的内部其实有一个数据库存储引擎, 例如可以使用 sqlite, 或者 LevelDB. 这个结构还可以继续拆分, 在分布式数据库, 需要有多副本, 所以会引入 binlog 技术(日志复制状态机), 把用户的请求保存下来(持久化), 然后复制到其它机器上. 因此, 系统的架构就变成:
    Continue reading »

    Posted by ideawu at 2021-05-08 22:42:19
  • 2021-05-08

    Raft 协议和区块链

    Views: 5065 | No Comments

    我还没有发现有人把 Raft 协议和区块链关联到一起讨论, 但是经过仔细分析, 穿透问题的本质之后, Raft 和区块链技术具有非常多的共同点. 可以整理出一个表格:

    Raft 区块链 通用
    日志 区块 Entry, Node, 节点, 记录
    日志序列 区块链 Chain, 链表(前向指针)
    选举: Leader 可产生日志 算力: 任意节点付出成本产生区块 Leader
    Term 分叉 Branch
    基于 Quorum 立即 Commit 立即相信最长的链条 Consensus, 共识
    一经 Commit, 不可撤销 随时转而相信新的最长的链条 Commit, Rollback

    Raft 和区块链的不同概念, 其实往往对应到通用技术里面的一个共同的概念.
    Continue reading »

    Posted by ideawu at 22:19:31 Tags:
|<<<123456789>>>| 4/9 Pages, 52 Results.