分布式系统需要解决的几大问题

架构演进中单体架构的高难度演进和技术升级我可能没有经历过,目前很多场景很多需求,都需要分布式系统去解决,不过大多数情况下我们可能不需要使用分布式相关的服务,但是业务的发展可能需要我们提前了解相关的技术作为技术储备,随时迎难而上。本篇文章作为分布式理论的一篇随笔完全自己手敲去理解分布式系统需要解决的问题,后面可能会深入某些分布式系统做一些理论上的阐述。

一、节点信任

分布式系统的特性导致每个处于分布式系统中的节点都可能时刻处于不同的状态,因此如果需要设计一个分布式系统或者需要学习研究一个分布式系统,其首要问题就是要解决
或者了解每个节点之间如何保证互相能够访问到,直接来说就是集群节点之间能否相互ping通,当节点之间需要就某一个问题或者某些数据做一致性的处理的时候就需要解决这个问题,
也就是说当a,b两个节点要提交同一条修改记录的时候需要使用分布式锁去保证a,b两个节点中只有一个能提交成功,而分布式锁的作用也可以看做节点协调的功能。另一个例子,
比如节点a需要访问b,c,d,当b挂了的时候,或者b由于网络变慢出现问题,节点a要很快知道,否则a可能无法工作,如果将a,b两个节点看做两个分区,当a,b处于一个分区同时由于网络问题变成
两个分区的时候,怎么对a,b两个分区进行处理其实也是一种节点信任,比如a分区节点数量多a分区继续提供服务,b节点数量少b中的节点停止服务。
实现节点之间的信任严重网络和数据传输,一旦出现问题则节点信任就可能无法完成。
第三个例子,我们可以从分布式id生成器来阐述这个问题,比如当a节点向分布式id生成器系统请求一个id,那么当a请求成功的时候b不可能再请求到同一个id,不管时间如何变化,
同一时刻节点a和节点b都不能同时拿到同一个id,也就是说a,b两个节点已经根据分布式id生成器系统做了一个默契的相互信任。
第四个例子,跟数据库事务有关,比如分布式情况下如何保证数据事务的ACID特性,以及如何保证对一个分布式事务做一致性的处理,由于有不同的集群节点参与。那么,
一旦事务提交或者事务回滚,后面需要处理相应数据的节点需要很快知道结果,如果事务回滚了一半或者事务执行了一半导致其他节点拿到不一致的错误数据那么分布式的事务就做的很烂。
也就是说节点之间要对数据,对状态做相互的信任。保证相关节点拿到的数据,知道的状态都是尽量一致的。

二、节点协调

当我们了解了节点信任是怎么回事之后,节点协调大概也就懂一些了,节点协调需要有一定的角色存在,也就是节点协调是表达了一种分布式系统的运行模式,中心化,还是无中心化,主从,
还是双主;比如redis,就是学习节点协调的很好的例子,因为redis有主从模式,cluster模式,哨兵模式等。在节点信任的基础上,节点协调是分布式系统需要解决的第二个问题,
构建或者学习一个分布式系统需要了解每个集群模式的特点,比如中心化的优势和劣势,一主多从的模式下如何解决业务问题。当运行模式敲定以后,节点可能就分为主节点,从节点,观察节点,数据节点,备份节点,
服务节点等角色,当不同角色出现以后节点如何基于信任的基础上做相互的协调和同步就是本节需要讨论的问题。拿中心化的集群运行模式举例,中心化的集群有一个主节点作为协调者或者仲裁者
协调哪些节点响应数据,哪些节点存储数据,哪些节点可以做新的协调者或者仲裁者。可以对比现实世界中的组织结构,团队结构。这里不会阐述中心化的优缺点,可以自行百度。
另一个例子就是无中心化的集群运行模式,无中心化的运行模式从局部看来可以认为很多节点都是同样的服务节点或者数据节点,从整体看来可以认为全部节点都是服务节点,都存储数据,都提供服务,任意一个
节点挂了不影响服务运行。实现节点协调的一个算法就是分布式一致性HASH算法。可以通过该算法理解节点协调是什么意思。最后,我们可以借助zookeeper的机制来简单阐述节点协调是什么意思,
zookeeper中有leader节点,follower节点,还有observer节点,这些不同角色的节点在集群选举,集群广播以及提供服务时有不同的作用,详情可以看zookeeper相关的书籍。

三、数据网络协议

由于是分布式系统,因此分布式系统必然需要有数据去承载业务,因此分布式系统的一个要考虑的问题就是如何基于网络做一些协议来传输数据,因此谈数据之前先把网络协议吃透,
很多分布式框架基于netty或者mina做网络通信组件,可以自定义数据传输协议,RPC中可以使用http或者基于netty做自研的二进制协议或者使用json等更易于操作的协议,当然,除此之外,
如redis,kafka,hadoop等都对其使用场景做了特别的数据协议和网络协议的研发和处理,这里一方面指的是数据本身的协议可以在不同的节点之间通用,在应用层上做解析封装等,另一方面指的是
网络协议,比如是基于TCP长连接的还是http长连接的,又或者是基于UDP协议的。分布式系统的协议方面如果不是特别的场景或者对数据传输效率,数据处理效率不太敏感则一般采用通用的或者公开的
协议做底层交互组件。当然大多数情况下一单达到分布式的系统的话,数据网络协议如果处理不好很容易拖后腿,造成性能,安全,稳定性等问题。需要针对特定场景做特定的数据处理,
举个例子,序列化与反序列化作为分布式系统的数据解析和封装的理论可以有很多种实现。如json,xml,hession以及自定义的二进制数据协议。

四、数据存储

我认为数据存储是分布式系统需要面临的最后一个问题,很多分布式系统面临的问题都有数据存储,由于单体系统无法解决海量数据,高并发的问题,导致数据存储不能存在于单库和单文件,单数据容器中。
数据存储,数据变更,数据发布都涉及分布式系统对其按规则做的一些处理,如果数据组织存储协议,数据存储中间件的选型不对或者不合适,那么对于其设计的出来的
分布式系统肯定无法提供更完善更健壮的服务。后期对其进行迭代也很困难。比如hadoop,hbase,以及kafka等,当然还有redis,mongodb.对其数据存储方面做了很多精妙的设计和技术改进来
适应更复杂的场景。当然,有些分布式系统可以不关注数据存储,但是也不能忽略。比如nginx,dubbo,mycat,等偏服务偏响应的框架也需要对其存在的元数据和配置数据等做存储,由于是分布式的,
这会导致数据存储存在很多情况,比如数据库层面的分片,分区,水平切分,垂直切分等。比如hadoop的大数据存储,另外数据存储的设计也决定着分布式系统能支撑多少量级的数据来满足业务需求。
比如redis,其定位是基于内存的nosql数据库,或者也可以当缓存数据库使用,由于是在内存,因此无法存储更多或者更复杂的数据,即使使用多个节点也不能存储tb级别的数据,即使可以,其他方面也会制约其
性能和稳定性。数据存储的另一个例子就是元数据,比如Hadoop依赖zookeeper的内置数据库做其ip等信息的存储,kafka依赖zookeeper做集群分区元数据的存储。
如果是自研的分布式配置服务,那么很多k-v的数据也需要考虑如何存储如何保证数据的一致性。

总结:这里只在宏观层面对分布式系统需要解决的问题做一些个人的理解和理论的总结,更多的情况下我们需要考虑相对细致垂直的方向,比如分布式下的事务,缓存,消息,数据配置
数据库等。以及集群的运行原理,内在的是单线程的还是多线程的,能处理多少并发,能存储多少数据等。每个方向上的方案和业界实现也有很多,但是重点是要以业务场景为基础进行方案设计
研发,技术选型等。有能力的可以自研,没能力的可以参考开源,八仙过海,各显神通。

你可能感兴趣的:(zookeeper,分布式理论&实践)