• 2021-06-03

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

    Views: 1332 | No Comments

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

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

    客户端请求重试

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

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

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

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

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

    数据库内核的并发控制

    Views: 1195 | No Comments

    大部分程序员最先接触并发编程, 一般是从编程语言里的多线程和锁开始. 但是, 并发控制是一种广义的技术思想, 千万不可将眼光局限于编程语言所提供的锁. 将编程语言里的并发控制技术推广, 就能得到任何层面的并发控制技术.

    以操作一个文件为例, 如果不做并发控制, 就会遇到数据完整性问题. 例如, 我们写入的一项数据, 对应着现实对象, 如果不做并发控制, 那么可能读到的是两项数据的混合体, 或者只读到一项数据的部分.

    互斥锁

    互斥锁是最简单的并发控制技术, 无论读还是写, 通通进行排队, 一次只处理一个请求(读或者写). 这种技术实现起来简单, 不容易出 bug, 如果为了快速实现, 可以采用此技术. 但是, 因为涉及到排队串行化, 所以在很多实际场景中, 这种技术会非常低效.

    以操作一个文件为例, 给文件加一把互斥锁(任何层面的锁, 未必和编程语言或者操作系统所提供的锁对应). 当想要往文件中写入数据时, 先获取锁, 然后写入. 同样, 想要从文件中读取数据时, 先获取锁, 然后读.
    Continue reading »

    Posted by ideawu at 2021-05-30 00:36:26
  • 2021-05-28

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

    Views: 1444 | No Comments

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

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

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

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

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

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

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

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

    Views: 1795 | 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: 1564 | 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: 1437 | 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:
|<<<2345678910>>>| 6/138 Pages, 825 Results.