• 2021-09-06

    关于多写入点数据库集群的一些想法

    Views: 23242 | No Comments

    在分布式数据库系统领域, 多主(多写入点, Leader-less)是一个非常诱人的特性, 因为客户端可以随机请求任何一个节点. 这种可随机选择访问点(写入点)的特性, 使得系统的高可用唾手可得, 因为当客户端发现某个节点出故障时, 更换另一个节点重试就可以了, 只要系统没有完全宕机, 几次重试之后一定成功, 也就可以达到百分之百高可用.

    传统的 Basic Paxos 常常被误认为是 Leader-less 的, 也即多主, 但 Basic Paxos 只能用于确定一个实例的共识, 真正落地还需要结合日志复制状态机, 如果复制组(多节点)不指定 Leader 的话, 那么就会出现争取同一个位置的日志的情况, 也就是在尝试达成这个位置的日志的共识时出现活锁. 这种多节点争取同一个位置的情况, 在实践上将导致系统不可用, 因为, 通常自称采用 Paxos 的多副本数据库系统, 依然要显式指定 Leader, 并不是真正 Leader-less 的.

    Continue reading »

    Posted by ideawu at 2021-09-06 20:51:04 Tags: ,
  • 2021-09-05

    什么是分布式一致性

    Views: 20084 | No Comments

    在工程实践上, 分布式一致性和多副本有关系, 如果没有多副本, 就没有分布式一致性的问题.

    多副本的定义: 多副本可以放在多台机器上, 也可以放在同一个进程内的不同内存地址内, 或者一个副本在内存, 一个副本在硬盘. 只要同一个对象出现在多处, 或者在多处被引用, 就是多副本.

    各个副本的写入操作序列必须先经过共识, 按同样的顺序写入, 因此所有副本的状态将是最终一致的(相同). 但是, 有可能单独地读取某个副本, 这就导致读操作在不同副本上发生的顺序并不相同, 这显然会导致最终结果不一致(符合预期), 因为我们本能地知道, 顺序决定结果.

    例如, 先写后读与先读后写, 显然读出来的结果不一样, 这个很显然. 因为日志序列的复制和执行必然是异步的, 绝对不可能所有副本在同一个时间点同时写入, 必然有一个时间差, 这也是很显然的. 因此, 如果轻率地去读取不同副本, 将可能导致读取的结果不同, 因为某个写入操作可能只在某个副本上执行了, 而在另一个副本上还没有执行, 所以读取的结果不同, 这是很显然的.

    Continue reading »

    Posted by ideawu at 2021-09-05 10:49:53 Tags: ,
  • 2021-09-04

    记一次关于系统性能的有趣讨论

    Views: 14677 | No Comments

    有个同事问我:"你开发的分布式数据库系统, 如何避免 scan 扫描操作返回了 pending 事务状态的数据?"

    我说:"把数据扫描出来, 然后逐个判断过滤掉 pending 状态的数据."

    我感到奇怪, 对于他的问题, 解决方案非常显然啊. 解决方案非常直观, 兵来将挡水来土掩, 我相信他也能想到, 不想要的数据当然要剔除掉, 否则呢? 那么, 他的问题的点在哪?

    没错, 他接着问了:"我 scan 的时候只想返回 key, 但是, 要判断状态, 是不是还得去读取 value 解析出状态信息?"

    我当时是黑人问号脸:"当然要知道状态信息才能根据状态过滤呀, 不然呢?"

    他终于祭出了那个经典的让人哭笑不得的问题:"读取 value, 是不是性能会下降啊?"

    Continue reading »

    Posted by ideawu at 2021-09-04 10:29:04
  • 2021-09-02

    Binlog 和 Redolog 的区别

    Views: 14669 | No Comments

    在开发分布式数据库的过程中, Binlog 和 Redolog 是非常重要的两个概念, 两者的作用似乎相同, 但实际上各有各的使用场景. 从多副本复制一致性的角度看, Binlog 用于强一致性, Redolog 用于最终一致性.

    Binlog 可包含非幂等的指令, 例如 incr 指令. Redolog 只能包含幂等的指令, 例如 set 指令.

    全球跨地域同步最终一致, 能不能复制 Binlog 呢? 绝对不行! 使用 incr 和 set 指令的组合, 在不同的地域写入数据, 很容易就能发现可造成数据不一致(相同)的场景, 而且几乎无法避免(除非副本带有回滚功能). 而如果同步的是 Redolog 的话, 通过复合时间戳, 是可以实现多副本的最终一致的.

    对于强一致的多副本, 能不能复制 Redolog 呢? 似乎是可行的. 例如, 收到 incr 指令, 可以先转换成对应的 set 指令. 但是, 共识过程可能耗费较长时间, 如果这时再来一个 incr 指令, 则必须将这个指令阻塞(因为两个指令有依赖), 否则生成的 set 指令将是错误的. 而如果复制的是 Binlog, 则没有这个问题, 两个 incr 指令可以并发地进行共识流程.

    Continue reading »

    Posted by ideawu at 2021-09-02 21:29:51
  • 2021-08-27

    企业级SSD硬盘fsync速度

    Views: 13448 | No Comments

    小数据测试, 以便对硬盘 fsync 的速度有一个大概的了解. 结果:

    rate latency 备注
    4044/s 0.247ms Intel SATA SSD
    19720/s 0.051ms Intel NVMe SSD

    结论: SATA 盘的 QPS 是 4000, NVMe 的 QPS 是 20000.

    如果要开发一个分布式 KV 数据库, 那么对于每一个客户端请求, 至少进行 1 次日志 fsync. 为了提高吞吐量(QPS), 日志模块必须进行 batch 持久化.

    如果 batch 大小是 25 的话, 普通 SATA SSD 盘能达到 10w qps, 而 NVMe SSD 只需要 batch 是 5 即可达到 10w qps.

    Posted by ideawu at 2021-08-27 20:42:53
  • 2021-08-26

    C++ Latch 实现

    Views: 14458 | No Comments

    Latch(Binary Semaphore) 不同于信号量(Counting Semaphore), 也不同于条件变量, 它是一种合并信号成一个标记的通信方式, 可用于实现 Batch 操作. 例如, 两个线程围绕一个标记, 一个设置(生产者), 一个复位(消费者). 如果标记已设置, 则消费者立即复位然后返回. 如果标记未设置, 则消费者等待标记被设置.

    在生产者消费者编程模式中, 生产者产生任务, 任务被加入队列中, 同时通过 Latch 告知消费者. 使用 Latch 的话, 可能多个任务产生之后, 消费者才会获知消息, 于是, 便可以将多个任务合并处理, 也即所谓的 Batch(批量)操作. 同时, 只要有任务, 标记就一定会被设置, 消费者不会漏掉任务.

    如果使用条件变量, 那么消费者可能漏消息. 因为, 如果消费者在忙于处理任务时, 生产者的通知将会被丢弃.

    如果使用信号量, 那么消费者进行 Batch 操作之后, 后续的堆积的信号会导致空操作, 因为任务已经处理完了, 但信号还在.

    Continue reading »

    Posted by ideawu at 2021-08-26 21:10:33
|<<<123456789>>>| 1/138 Pages, 825 Results.