zoukankan      html  css  js  c++  java
  • 分布式系统基础总结

    一直在搞分布式系统,Hadoop, Spark, Kafka, ZooKeeper之类的都玩过,然而以前只是简单地用用各个开源组件实现,并没有系统地学习其中的原理和算法。最近在跟着MIT 6.824课程学习分布式系统的各种理论原理,这里就来简单总结下分布式系统中的一些基础内容吧~

    CAP Theory

    CAP Theory阐述了分布式系统中的一个事实:一致性(Consistency)、可用性(Availability)和分区容错性(Partition Tolerance)不能同时保证。三个只能选择两个

    CAP Theory

    假设有两台机器A、B,两者之间互相同步保持数据的一致性。现在B由于网络原因不能与A通信(Network Partition),假设某个client向A写入数据,现在有两种选择:

    • A拒绝写入,这样能保证与B的一致性,但是牺牲了可用性
    • A允许写入,但是这样就不能保证与B的一致性了

    Network Partition是必然的,网络非常可能出现问题(断线、超时),因此CAP理论一般只能AP或CP,而CA一般较难实现。

    • CP: 要实现一致性,则需要一定的一致性算法,一般是基于多数派表决的,如Paxos和Raft
    • AP: 要实现可用性,则要有一定的策略决议到底用哪个数据,并且数据一般要进行冗余备份(replication)

    当然,在上面的例子中,A可以先允许写入,等B的网络恢复以后再同步至B(根据CAP原理这样不能保证强一致性了,但是可以考虑实现最终一致性)。

    一致性哈希

    分布式Key-Value Store中的key映射问题。

    • 传统hash(x) % N算法的弊端:不利于架构的伸缩性
    • 一致性哈希将哈希值映射到一个哈希环上,然后将数据进行哈希处理后映射到哈希环上,再把节点进行哈希处理映射到哈希环上,数据将选择最近的节点存储
    • 伸缩性:节点删除时,原有的数据将会就近迁移,其他数据不用迁移;节点增加时也相似
    • 保证负载均衡:虚拟节点

    拜占庭将军问题

    最复杂的情况:自己发的包被截;对方发的包自己收不到;内部有节点捣乱,造成不一致。

    FLP Impossibility

    Impossibility of Distributed Consensus with One Faulty Process 这篇论文提到:

    No completely asynchronous consensus protocol can tolerate even a single unannounced process death.

    假设节点只有崩溃这一种异常行为,网络是可靠的,并且不考虑异步通信下的时序差异。FLP Impossibility指出在异步网络环境中只要有一个故障节点, 任何Consensus算法都无法保证行为正确。

    Lease机制

    Lease(租约)机制应用非常广泛:

    • 可用作授权来进行同步等操作(如Append)
    • 可用作读锁/写锁(分布式锁)

    租约的一个关键点就是有效期,过了有效期可以续约。如果不可用就收回租约,给另一台服务器权限。

    实际应用:

    • GFS: Master grant to ChunckServer

    思考:Lease == Lock?

    Quorum机制

    多数表决机制在分布式系统中通常有两个应用场景:

    1. Leader Election
    2. Replication (NWR机制)

    理论基础:鸽巢原理

    Consensus问题

    Consensus条件

    • Termination: 最终必须决议出结果
    • Validity:
    • Integrity
    • Agreement

    2PC/3PC

    2PC在proposer和某个voter都挂掉的时候会阻塞(原因:别的节点没有对应voter的消息,只能阻塞等待此voter恢复)

    3PC添加了一个 prepare-commit 阶段用于准备提交工作,这里面可以实现事务的回滚。

    缺点:效率貌似很低。。。分布式事务用2PC会特别蛋疼

    Paxos

    推演:

    • First Accept/Last Accept都不可以(结合时序图)
    • 一个阶段不行,自然想到两个阶段:发起决议以及提交决议
    • One Proposer -> One Acceptor 挂了就gg了
    • One Proposer -> Many Acceptors (规则:先到先投)
    • Many Proposers -> Many Acceptors (很容易乱。。。)

    Paxos引入了Log ID (num, value),共有三个角色,两个阶段。

    • Proposer: 决议发起者,需要等待多数派表决
    • Acceptor: 决议投票者,对收到的Propose进行表决并返回
    • Learner: 最水的角色,学习到投票的结果即可

    分布式一致性算法(Paxos, Raft, Chubby, Zab)待详细总结。。。

    时序问题

    Lamport Timestamp

    一般我们不关心分布式系统中某个过程的绝对时间,而只关注两个事件之间的相对时间。
    在一个系统的事件集合E上定义一种偏序关系->,满足:

    • 如果a与b发生在同一个进程中,且a先于b发生,则有a -> b
    • 进程间通信,a代表进程Pi发出消息m,b代表另一个进程Pj接收消息m,则有a -> b
    • 传递性:若a -> b, b -> c,则a -> c

    定义并发:a -> bb -> a均不成立则为并发情况

    引入Lamport逻辑时钟。一个时钟本质上是一个事件到实数的映射(假设时间是连续的)。对于每一个进程Pi,都有其对应的时钟Ci。

    分布式系统中的全局信息实际上是对各个实体信息的叠加(Q:重合怎么办?)

    可以看到Lamport Timestamp必须要求两个事件有先后顺序关系,因而在时序图上不好表示concurrent。由此引入Vector Clock。

    Vector Clock

    Vector Clock是对Lamport Timestamp的演进。它不仅保存了自身的timestamp,而且还保留了根节点的timestamp。

    Vector Clock(Version Vector)只能用于发现数据冲突,但是想要解决数据冲突还要留给用户去定夺(就好比git commit出现conflicts,需要手工解决一样),当然也可以设置某种策略来直接解决冲突(保留最新或集群内多数表决)。

    结合时序图理解会更好(图来自维基百科):

    可能出现的问题:Vector Clock过多。解决方案:剪枝(如果超过某个阈值就把最初的那个给扔掉;要是现在还依赖最初的那个clock的话可能就会造成一些问题(思考:如何解决?)

  • 相关阅读:
    Linux系统教程:设置GRUB菜单密码
    vimdiff的常用命令
    Zero-Copy实现原理
    解决业务代码里的分布式事务一致性问题
    用好这6个APP,学英语SO EASY!
    线程池调优
    理解select,poll,epoll实现分析
    时序图
    性能监控-TP理解
    sshd_config OpenSSH SSH 进程配置文件配置说明
  • 原文地址:https://www.cnblogs.com/nongchaoer/p/6476539.html
Copyright © 2011-2022 走看看