V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
MySQL 5.5 Community Server
MySQL 5.6 Community Server
Percona Configuration Wizard
XtraBackup 搭建主从复制
Great Sites on MySQL
Percona
MySQL Performance Blog
Severalnines
推荐管理工具
Sequel Pro
phpMyAdmin
推荐书目
MySQL Cookbook
MySQL 相关项目
MariaDB
Drizzle
参考文档
http://mysql-python.sourceforge.net/MySQLdb.html
xiyy02
V2EX  ›  MySQL

既然 mysql 可以靠 binlog 达成多副本共识,那为什么还需要 Paxos、Raft 等共识算法?

  •  
  •   xiyy02 · 313 天前 · 4440 次点击
    这是一个创建于 313 天前的主题,其中的信息可能已经有所发展或是发生改变。
    RT ,最近在看 Paxos 、Raft 等共识算法,Paxos 没怎么看明白,Raft 看了整个流程,相较于 Paxos 好理解许多;
    有些疑问想要请教下 V 友们:
    我了解过 mysql 的副本同步机制,mysql 通过 binlog 来完成副本同步,为了保证 redolog 和 binlog 不发生一致性问题,还专门做了两段式提交:
    阶段一:主库写 redolog 但不提交;
    阶段二:主库写 binlog ,然后标记相关 redolog 为提交状态
    当且仅当 binlog 写成功时,redolog 里相关改动才算提交,这样可以保证多副本最终一定会按照 binlog 可靠的达成共识(一致?)

    在这个过程中,mysql 既没有实现 Paxos ,也没有依赖 Raft ,最终还是达成了多副本的共识(一致?),那为什么还专门提出来 Paxos 这类复杂的共识算法来完成多副本一致性呢?

    PS:在此期间还看到有人纠正:共识和一致不是一回事;但我理解共识算法的目的也是为了多副本就一份数据达成一致吧?所以一致性还是最终的目的,总之我被绕晕了😭
    41 条回复    2024-02-17 14:06:04 +08:00
    verrickt
        1
    verrickt  
       312 天前 via Android
    我只看过 raft ,mysql 不太了解。
    我觉得可能比较关键的点是,提供了什么样的一致性。
    比如 raft 提供了线性一致性保证( linearizability ),mysql 是否提供了相同的一致性,或是说只是提供了一个很模糊的最终一致性( eventual consistency )?
    另外提一点,这里的一致性指多个 replica 之间读写的一些保证,与事务( ACID )里的一致性是不同的概念
    verrickt
        2
    verrickt  
       312 天前 via Android   ❤️ 2
    共识和一致确实不是同一回事。lz 可以看看 design data intensive application 这本书,里面有专门的章节介绍一致性( consistency )和共识( consensus )
    https://dataintensive.net/
    liprais
        3
    liprais  
       312 天前
    binlog 达成不了强一致性
    billlee
        4
    billlee  
       312 天前   ❤️ 1
    1. Paxos 和 Raft 不是唯二的共识算法
    2. Paxos 性能太低了,一般只用来管理 group membership, 然后根据 group membership 退化到主从复制来处理数据。zookeeper 就是这样做的。
    3. MySQL 能保证一致性的是 group replication, 它的 group membership 确实依赖共识算法来管理: https://dev.mysql.com/blog-archive/the-king-is-dead-long-live-the-king-our-homegrown-paxos-based-consensus/
    tool2d
        5
    tool2d  
       312 天前
    我个人不太喜欢 binlog 同步,任何对数据库的小变动,都往这文件里写。我们服务器是老式硬盘,一直高强度写,有很大损耗的。

    任何方法都有一定局限性,写个同步算法,也可以有 3 ~ 4 种完全不同的思路。
    lazyfighter
        6
    lazyfighter  
       312 天前
    mysql 没法选主啊 , 主就是固定的
    rqzrqh
        7
    rqzrqh  
       312 天前
    paxos 和 raft 算法可以实现强一致性,容易理解就是复制状态机,所有的节点有相同的输入和输入顺序,只要大多数节点存活就能正常工作(更严谨是说法要满足共识算法的大多数节点以及大多数节点的状态),最原始的 paxos 算法里任何节点都可以提交 log ,但是这样效率太低,后来的共识算法都改为只有一个节点提交 log ,这个节点是可以通过算法选举出来的。
    binlog 是预先配置好的主+多个备,一旦主故障后,备是不能写入的,否则会导致数据和主不一致。
    jimrok
        8
    jimrok  
       312 天前
    双向复制的时候,怎么保证 binlog 的一致?应该听谁的?
    mightybruce
        9
    mightybruce  
       312 天前
    binlog 那是依赖一个主多个从, 当你集群有多个主和多个从节点, 要想达到一致性就不能靠这个了。
    mysql 集群 如果要允许多个主多个从 可以写入并达到一致性,就要依赖 paxos ,raft 。不同的公司都有一些实现,比如 facebook 的论文中就有通过 raft 来做一致性
    mightybruce
        10
    mightybruce  
       312 天前   ❤️ 1
    cheng6563
        11
    cheng6563  
       312 天前
    你想想,主库挂了会怎样
    vczyh
        12
    vczyh  
       312 天前
    存在 Leader 选举,才会用 Raft Paxos 这些东西。比如一开始有三个内容一样的副本(其中一个为 Leader ),修改内容的时候去 Leader 修改,然后同步到其他副本,如果 Leader 挂了,Raft 这时候就可以重新选举了,说白了他就是选举话事人的。

    MySQL 通过二阶段提交保证 binlog 和 redolog 的一致性,我觉得单靠这个也不能保证,比如阶段二中 binlog 刷盘之后,标记 redolog 提交状态之前挂了,这个时候 binlog 事务是提交的,redolog 中事务状态是未提交的,这个时候需要 mysql 启动的时候进行崩溃恢复,可以通过 binlog 判断出事务已经提交了,然后把 redolog 的事务标记为提交,这样就保证一致了。

    所以我觉得他们都属于共识算法,binlog 和 redlog 通过崩溃恢复达成了某个事务是否提交的共识,这个实现我觉得没有 Raft 这种更具有通用性,他只负责当前多副本只有一个老大,其他全部老老实实同步数据就行。
    qieqie
        13
    qieqie  
       312 天前
    保证了主库 binlog 和 redo 一致不代表可以保证集群的状态一致性,
    同步 binlog 最多只能保证最终一致性,强一致性需要分布式事务去支持。
    momocraft
        14
    momocraft  
       312 天前
    binlog 能用的前提是 MySQL 一直在跑,master 能一直活着负责做决定,其他节点只管跟随
    这不叫“分布式共识”
    lvlongxiang199
        15
    lvlongxiang199  
       312 天前
    如果向 master 内写了 x=1, 写成功之后 master 挂了(其它节点, 拿不到最新的 binlog). 这时候从其它节点读 x, 能读到 1 还是之前的值 ?

    raft 能提供这种线性一致性的保证
    xiyy02
        16
    xiyy02  
    OP
       312 天前
    @momocraft 可是共识算法中不也是 leader 负责做决定,Follower 跟随吗?唯一的区别是 leader 身份可切换
    mightybruce
        17
    mightybruce  
       312 天前
    共识算法是为了可用性, 服务器节点存在三个角色 :leader 、follower 、candidate
    主从模式中是只有主节点可以写入的。
    xiyy02
        18
    xiyy02  
    OP
       312 天前
    @liprais 可是 raft 也保证不了完全的强一致吧?比如:leader 写了一个数据,此时同步到 Follower ,「多半」 Follower 响应 leader 后 leader 将此信息传给客户端,告知客户端已经写成功,但如果此时客户端读这个数据的时候正好读到了还未将此数据标记为 commited 状态的那个 Follower 节点(「多半」意味着总会有落后的 Follower ),这不就造成读写不一致了吗?
    我看过 Quorum 规则,说客户端每次可以读半数以上的节点,以确保至少有一个节点可以读到最新的值,但这对于一个客户端来说操作似乎又太重了(一次请求那么多个节点显然不合适),就很晕😓
    liuhan907
        19
    liuhan907  
       312 天前
    @xiyy02 raft 协议只解决共识,不解决一致。而你的这个问题是一致问题,而不是共识问题。
    JasonLaw
        20
    JasonLaw  
       312 天前 via iPhone
    @xiyy02 #18 据我了解,在 Raft 协议中,client 的读写都是发生在 leader 的,不像 ZooKeeper 。MIT 6.824 课程有讲。
    yamasa
        21
    yamasa  
       312 天前
    @xiyy02 想强一致就 follower 转发 leader ,想一定程度牺牲一致性来换取性能和可用性就 follower read ,总是有取舍的。
    yamasa
        22
    yamasa  
       312 天前
    @liuhan907 你搞错了,Raft 读数据走 leader 即提供全局 linearizable read ,怎么可能不解决 data consistency ?只是想要线性一致性读必须走 leader ,这对于分布式系统的服务可用性和性能是个头疼的问题,所以即便是采用了 Raft 作为 data replication 共识算法的分布式数据系统一样要提供 follower read 提供给用户,典型如 CRDB 和 yugabyteDB
    yamasa
        23
    yamasa  
       312 天前
    MySQL 的这种做法不就是典型的 2PC ? 2PC 的缺陷不想在这里赘述了,几个知名的分布式数据系统( Spanner ,CRDB ,yugaByteDB )都采用了 paxos 或者 multi paxos 的方式来尽量解决 2PC 的缺陷,比如改进后的 2PC 不需要全局共识了而只需要 quorum 共识,以及 coordinator 可以根据 paxos 算法自动 failover ,这都是很大的改进了。
    liuhan907
        24
    liuhan907  
       312 天前
    @yamasa 但是 raft 读数据也可以不走 leader 不是么
    happyxhw101
        25
    happyxhw101  
       312 天前
    C A P 你是一点都不看啊
    yamasa
        26
    yamasa  
       312 天前
    @liuhan907 Raft source paper 可没让走 follower ,论文里就是让走 leader 可提供线性一致性读,后续的各类系统实现的时候走 follower 显然是为了性能的妥协,不能怪到 Raft 算法本身上去
    akira
        27
    akira  
       312 天前
    现在存算分离的数据库方案成熟了么,感觉可以直接规避掉这一大堆麻烦事情
    xiyy02
        28
    xiyy02  
    OP
       312 天前
    @happyxhw101 我理解 CAP 指的是在实现分布式一致性遇到网络分区( P )时的取舍方案( C or A ),而 Raft 协议是一种保证多副本共识而最终达到多副本强一致的策略,它们都是单独的理论,但在做工程实现时需要一起考虑:比如我有一个分布式系统通过 Raft 实现节点间的强一致,正常情况下,它确实是强一致的,而且运行的很好,但当发生网络分区时我需要结合 CAP 理论在可用性和一致性之间作取舍,如果要舍弃可用性,那就分区期间为了保证一致性让整个系统不可用(具体表现为客户端无法读或写),如果要舍弃强一致性,那就在分区期间也允许读写操作,但后果就是多节点间因为分区导致多 leader 写或单 leader 写的内容无法同步到没有 leader 的分区节点,导致各分区间的数据不一致。
    额。。只是个人理解,不知道对不对,CAP 和 Raft 都是我最近在研究的东西,感觉都很抽象😭
    lifanxi
        29
    lifanxi  
       312 天前
    @akira 成熟。但是分离以后存储也得是分布式的吧?分布式存储一样需要解决一致性的问题。没有规避掉这些麻烦事情,只是这些麻烦的事情交给了更底层去做。
    beneo
        30
    beneo  
       312 天前
    Mysql 依赖于单个主库来处理所有写操作,如果主库宕机,切换到从库作为新的主库,这个过程中可能会面临短暂的服务不可用,或者数据延迟问题。而 Paxos 和 Raft 就提供了对分布式而言更通用、更强大的算法,能够帮助设计和实现高可用、高一致性的分布式系统。
    mightybruce
        31
    mightybruce  
       312 天前
    2PC 几个回复写得有点问题,
    mysql 实现 2pc 不是 binlog 和 relog 达成共识,而是 XA 事务。XA 事务在很多数据库中是有实现。
    chenzw2
        32
    chenzw2  
       312 天前   ❤️ 1
    raft 算法演示,非常清晰了
    https://code.bqrdh.com/alg/raft/
    kuro1
        33
    kuro1  
       312 天前
    vczyh
        34
    vczyh  
       312 天前
    @mightybruce 谢谢提醒,我理解确实有点问题,把 XA 和崩溃恢复混在一起理解了。
    ywutiao
        35
    ywutiao  
       312 天前
    @xiyy02 CAP 理论不用太纠结现在很多人批斗这篇论文,因为说的太绝对了。况且分布式的东西你能舍弃 A 吗,共识算法算是保证了部分 A 半数可用,在这种情况下保证一致性。而你一开始提到 Mysql 同步机制,这哪里算是一致性,你这不就是勉强搞了个复制算法吗,同步、半同步、全同步这些东西(个人感觉共识协议是半同步的进化版本)。只能算是做了共识算法的一部分
    ywutiao
        36
    ywutiao  
       312 天前
    @akira 存算分离和共识完全是不同维度上的事
    shalk
        37
    shalk  
       312 天前
    1. mysql 副本同步机制,也就是复制机制。

    2. 比如有 1 主 3 从( A ,B ,C ,D ),如果 mysql 挂了切主,谁当主谁当从,都要达成共识,这是共识算法。

    3. 最后 A ,B ,C ,D 数据是不是相同,延迟多少,一致成什么效果,才叫一致性。
    iminto
        38
    iminto  
       312 天前   ❤️ 1
    不要编造名词,或者虚构理论。

    “既然 mysql 可以靠 binlog 达成多副本共识”,这是谁告诉你的呢。。。
    liuhan907
        39
    liuhan907  
       311 天前
    @yamasa 这倒是没错,不过现在的实现倒是都提供了非 leader 读。反正也没人按照原始论文来实现算法,都是改了又改的。
    Jasonhhh
        40
    Jasonhhh  
       301 天前
    因为数据库不仅有 MySQL ,还有 Redis 等其他数据库。Redis 的主从切换就使用了 Raft 共识算法。
    xiyy02
        41
    xiyy02  
    OP
       300 天前
    @Jasonhhh 之前看过这块内容,似乎 Redis 对于 Raft 的应用并不是直接作用到主从节点的,而是作用在 Sentinel 上的,而且基本上只是用 raft 的投票思想来做主节点客观下线和 Sentinel Leader 选举,被选举出的 Sentinel Leader 节点再去做故障转移(向同步数据 offset 最大的从节点发送 slaveof on one ,让其变成主节点,然后向其他从节点发送 slaveof 新主节点 ip+port 简历新的主从关系,从节点再发起 psync 同步,旧 master 若恢复就变成从节点,故障转移成功);
    所以这个过程中 redis 主从节点间的数据同步其实也是简单的复制同步( psync+挤压缓冲区);

    不过经过大家的回复我现在似乎已经理解了我所问的问题,感谢耐心回复~
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2207 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 23ms · UTC 04:25 · PVG 12:25 · LAX 20:25 · JFK 23:25
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.