10几年前,互联网还是个单体架构时代。

什么是单体架构?不是说系统所有服务都集中在一台机器上(当然这也是一种。。),简单来说,是系统所有服务都在一个进程里,所有模块、方法都是进程内调用,根本不用考虑现在什么网络延迟、数据同步问题。

随着互联网发展,业务量也开始爆发了,怎么办?扩呗。

先垂直扩容,换性能高的机器,优化参数。

再水平扩容,加机器、加集群。

但慢慢其他问题也出来了,比如随便加个功能,或者修个bug,整个系统都要升级一遍,对运维来说就是个灾难。

于是开始拆。

纵向怎么拆?分层。把接入层、业务层、数据层等等全拆开来。

横向怎么拆?分模块,把系统拆成多个子系统、子模块。可以按技术、可以按功能、可能按职责。

拆开之后,子系统之间就完全老死不相往来了吗?要互相通信、共享数据怎么办?

慢慢就出现了服务封装、服务注册、服务发现这些概念。

服务开始演进到了分布式架构,也叫soa、微服务等等。

今天单聊一下分布式架构中的数据一致性问题。

分布式架构有个重要的定理,叫cap。c是一致性(Consistency),a是可用性(Availability),p是分区容忍性(Partition tolerance)。

这个定理说,分布式架构中,只能同时满足c、a、p中的两个。

其中一致性是什么意思呢?它说的是,任何时刻,所有节点的数据都是一致的。

也就是,只要你往一个节点完成了写操作,那么其他节点的数据也一定能读到这个最新写入的值。

实现一致性的组件有很多,例如zookeeper、consul等。

像consul是怎么实现的呢?

consul集群分为server节点和client节点。client接收到请求后,就会把请求发给server节点。

server节点可能有很多,他们会组成一个Raft集群。Raft是一种一致性算法,可能有人好奇Raft全称,不好意思,它就是为了好记。

Raft集群里会进行leader选举,选出一个leader节点。leader节点负责处理所有的写请求。leader节点会定期给其他server节点发送心跳,如果leader挂了,其他server节点就会发起新的选举,直到选出新的leader。

leader收到请求后,就会转换成一个日志条目,追加到自己的本地日志里,然后发给其他server节点,其他server节点收到后,也会追加到自己的本地日志里,然后返回个确认消息。

当leader确认大多数server节点完成复制后,就会标记这个条目状态,将结果返回给客户端。

由此可见,国一日不可无君,家一日不可无主!(跑题了)

类似的,其他一致性手段也大同小异,可以参考着去理解。

这里抛一个简单问题,consul实现了自身的一致性,假如需要保证注册方和消费方一致性,例如注册了一个信息,希望消费方一定要完成消费,注册方又要怎么感知消费方是否完成了呢?


sre阿文
1 声望0 粉丝