龙空技术网

etcd技术架构以及其内部的实现机制

愿从心出发 167

前言:

如今大家对“租约机制的程序流程图”都比较珍视,兄弟们都想要知道一些“租约机制的程序流程图”的相关文章。那么小编在网摘上收集了一些有关“租约机制的程序流程图””的相关知识,希望各位老铁们能喜欢,你们一起来了解一下吧!

etcd是分布式的、可靠的、分布式存储K-V系统,用于存储分布式系统中的关键数据。

WALWrite-Ahead Logging 预写日志系统,数据库中一种高效的日志算法,对于非内存数据库而言,磁盘I/O操作是数据库效率的一大瓶颈。在相同的数据量下,采用WAL日志的数据库系统在事务提交时,磁盘写操作只有传统的回滚日志的一半左右,大大提高了数据库磁盘I/O操作的效率,从而提高了数据库的性能。BoltDBBoltDB 是一个 使用 Golang 开发的 Key/Value 模型的程序,为不需要完整数据库服务器(如 MySQL)的项目提供一个简单,快速,可靠的数据库。只需要将 BoltDB 连接到应用程序代码中即可使用它提供的 API 来存取数据,无需数据库管理语言。BoltDB 支持完全可序列化的 ACID 事务,可以处理复杂操作。通过COW技术,可实现无锁的读写并发,但是无法实现无锁的写写并发,这就注定了读性能超高,但写性能一般,适合读多写少的场景。snapshot快照,存储某一个时刻etcd所有目录的数据。gRPC发送到etcd服务器的每个API请求都是一个gRPC远程过程调用。

一个etcd集群中通常会有3个节点或5个节点组成,多个节点之间,通过raft算法的方式来完成分布式一致性协同。多个节点之间,算法会选举出一个主节点作为leader,由leader做数据的同步和分发。当leader出现故障以后,系统会自动选举另一个节点成为leader并重新完成数据的同步和分发。客户端在众多的leader中只需要选择其中的一个就可以完成数据的读和写。

quorum

quorum=(n+1)/2,3个节点容忍1个节点故障,5个节点容忍2个节点故障。

在etcd整个架构中 有一个非常关键的概念 叫做quorum,超过集群中半数节点组成的一个团体,在允许部分节点故障继续提供服务,这里面就需要解决一个非常复杂的问题:分布式一致性,这也是etcd集群高可用的关键。

该分布式一致性算法由raft一致性算法完成,基于这个算法的前提是任意两个quorum一定存在交集。

只要一个quorum存活,其中一定存在其中某一个节点 ,它包含了集群中最新的数据,正是因为这个假设,这个一致性算法就可以在一个quorum之间采用这个最新的数据来完成数据的同步,从而保障整个集群向前演进的过程中其数据保持一致。

可以通过etcd提供的客户端去访问集群的数据,也可以通过http的方式,通过类似curl的命令直接访问集群数据。

在etcd内部其数据表示也是比较简单的,直接把etcd的数据理解为一个有序的map,它存储的是有序的数据,同时etcd方便客户端去订阅数据即支持watch机制,可以通过watch可以实时的拿到etcd数据的增量更新 ,从而保持etcd中的数据同步。

etcd提供的api

watch实现增量数据的更新;事务Transactions指定某些条件,当条件成立的时候,执行某些操作,当条件不成立的时候,执行另外的操作;Leases接口是分布式系统中常用的的一种设计模式。

etcd数据版本号机制

term

全局单调递增,64bits,term代表整个集群leader的任期,当集群发生leader的切换,比如说leader节点故障 或者说leader网络出现了问题或者说将整个集群停掉之后,重新发起一个集群,都会发生leader的切换,当leader切换的时候,对应的terms就会加1。revision

全局单调递增,64bits,revrison代表全局数据的版本,当数据发生变更,包括创建、修改、删除的是时候 ,revision对应的都会加一。在整个任期内 revision都可以保证全局单调递增,正是由于revision的存在,才使得etcd可以支持mvcc,也可以支持数据的watch。KeyValue(create_revision、mod_revision、version)对于每个key-value数据,etcd中记录了三个版本, 当前key-value创建的时候其操作对应的版本号、数据被修改时候其操作对应的版本号、version是一个计数器(代表key-value被修改了多少次)

在同一个leader的任期内,所有的修改操作对应的term值都等于2,保持不变,而对应的revision值保持单调递增 。

当重启集群之后

所有的修改操作term值都变成了3,对应的rev值同样保持单调递增。

在多个任期内,其数据对应的rev值也会保持全局的单调递增。

在etcd中是支持对同一个key发起多次的数据修改,因为已经知道每次数据修改对应的版本号,多次修改也就意味着一个key对应多个版本。在查询数据的时候,可以不指定版本号查询,这时候查询的是该数据的最新版本,当指定版本号的时候,也可以获取到一个key的历史版本。

同样因为我们知道每次去修改数据的时候,都会对应一个版本号,因此我们可以在watch的时候,指定一个数据的版本。通过这种方式创建一个watcher并通过这个watcher提供的数据管道,能够获取到指定的revision之后所有的数据变更,如果指定的rev是一个旧版本,立即拿到从旧版本到当前版本所有的数据更新。

watcher机制会保证当前etcd中,该key的数据后续发生修改之后,依然可以从这个数据管道中拿到它增量的更新。

在etcd中所有的数据被存储在一个b+tree中,这个b+tree保存在磁盘中并且通过DMA的方式移植到内存加速查询操作。在这个b+tree中,如图所示的灰色部分 ,它维护着revision到value的映射关系,也就是说当我们指定了revision查询数据的时候,就可以通过b+tree直接的返回数据 ,当我们通过watcher来订阅数据的时候,也可以通过这个b+tree中维护的revision到value的映射关系,从而通过指定的revision之后,开始遍历这个b+tree而拿到所有的数据的更新了。

同时在etcd内部还维护着另外的b+tree,它管理着key-revisions的映射关系

当查询key的数据的时候,通过蓝色的b+tree,它将key翻译成revision,再通过灰色的b+tree,通过revision获取到对应的value,自此就能够满足客户端的不同的查询场景。

通过定期的Compaction来清理历史数据

在etcd数据运行的过程中,数据持续不断的发生修改,就意味着etcd内存中的数据以及磁盘中的数据都会持续不断的增长,对资源有限的场景是无法接受的,因此在etcd中会周期性的运行一个叫compaction的机制来清理历史数据,对于一个key的历史版本的数据 ,可以选择清理掉。

etcd事务机制

在if中可以提供多个比较操作,在etcd内部会保持整个事务操作的原子性,不会出现仅执行一半的情况发生。

通过etcd提供的事务操作,我们可以在多个监听中保证事务读写的一致性。

比如说k8s项目正是用了etcd的事务机制来实现了多个k8s apiserver,对同样一份数据修改的一致性。

etcd lease概念和用法

Lease是分布式系统中常见的概念,代表一个租约,通常情况下在分布式系统中需要检测一个节点是否存活,就需要租约机制。

首先创建一个10秒的租约,创建租约之后不做任何的操作,10秒之后这个租约就会自动过期。

把2个key-value绑定到这个租约之上,这样当这个租约过期的时候,etcd就会自动的帮我们清理掉key1和key2的数据。

如果希望这个租约永不过期,比如需要检测一个分布式系统中的一个进程是否存活,那么就会在这个分布式进程中去访问etcd并且创建一个租约,同时在该进程中去调用keep alive方法,去与etcd保持一个租约不断续约,如果这个进程挂掉了,这个时候就没有办法再去keepalive了,租约在进程挂掉的一段时间内就会被etcd自动清理掉,通过这个机制来判断节点是否存活。

将多个key绑定在同一个Lease对象,可以大幅下降Lease对象刷新的时间,如果有大量的key都需要绑定在某一个Lease对象上,如果每一个key都去更新这个租约,这些etcd产生非常大的压力,这样既不失灵活性,同时会大幅度改善etcd整个系统的性能。

启动一个etcd

插入数据并查看

批量插入10个k-v数据

也支持范围查询前缀查询查询数据并以json格式返回

这条数据包含了消息头和描述了etcd全局的信息,raft_term就是前面提到的etcd全局版本号,当前term值是2,当前所有的操作对应的term值都是2。此时全局的版本号revision当前是12,对数据进行修改,

全局版本号revision变成了13,key5对应的create_revision是8,mod_revision也是8,因为没有对key5修改,所以version为1。

对key5进行修改,

mod_revision并不是加1,而是采用当前操作对应的revision=14,key5的版本号变成了2,再次修改

再次修改key5的数据,集群全局的revision变成了15,mod_revision也变成了15,version变成了3。对同一个key写入同一个value,版本号依然会变化。

删除操作revision又增加了一次,但是数据已经没有了。

重新插入key5,全局revision和create_revision、mod_revision都是17,version重新变成了1,又重新开始计数了,因为version代表key被修改的次数,在同一个任期内的term值是不发生变化的。

fg是将后台中的命令调至前台,然后停掉进程,重新启动

再次查询key5的数据,集群全局的term值从2变成了3,但是全局数据的revision是不变的。

如果再次的修改key5,

再次修改key5,集群全局的revision加1,create_revision保持不变,mod_revision为本次操作的版本,被修改过一次version变成了2。

key-value在etcd中是二进制的形式,这里输出是base64编码的,反解base64查看etcd 客户端输出数据的内容,

etcd数据同步

当数据被写入的时候,原本的watch就会及时的拿到数据的更新,可以实时的感知到数据的变化

前缀监听

事务

当事务成功之后,去查询key5的数据

etcd事务使用场景k8s元数据存储到etcd中

/ns/pods/minions/configmaps/secrets

k8s将自身所有的状态存储在etcd中,其状态数据存储的复杂性被etcd cover掉之后,k8s系统自身不需要再处理复杂的状态流转,因此自身的架构设计也得到了大幅度的简化。

优势

元数据高可用,无单点故障系统无状态,故障修复方案简单系统可水平扩展,提高性能及容量简化架构实现,降低系统工程复杂性服务注册与发现

在分布式系统中,通常会出现的一个模式,就是我们需要后端服务提供成百上千个进程,提供对等的服务,比如检索服务、中间件服务等,为了简化后端服务的运维成本,后端的进程会被类似k8s的集群管理系统所调度,也就是说事先无法知道这组进程分布在哪里。

存在这几个问题:

资源注册存活性检测api 网关无状态,可水平扩展支持上万个进程的规模

为了解决这些问题,可以利用etcd来解决资源注册的问题。当这一组后端进程被调度之后,在进程内部启动之后 ,可以将自身所在的地址注册到etcd,从而使得api 网关能够及时的感知到后端进程的地址,当后端进程发生故障迁移的时候 ,会重新注册到etcd中,api 网关能够及时感知到新的etcd数据。

因etcd提供了lease操作,还可以及时的感知到进程状态的变化。如果进程运行过程中死掉了,网关可以及时的感知到进程状态的变化,从而使得流量切换到其他的进程上去。通过这种方式,整个集群状态数据被etcd监管,网关本身也是无状态的 ,它可以水平扩展以服务更多的客户。得益于etcd良好的性能,可以支持后端上万个后端进程的节点。

分布式系统中比较常见的选主场景

slave提供了cpu、内存、磁盘、网络等各种资源,master是用来控制这些资源的协同,通常情况 master内部会存储一些状态数据以及实现和业务逻辑相关的控制器。slave之间会和master保持心跳的交互,典型的分布式存储服务以及分布式计算服务,比如hadoop hdfs都是采用类似的设计。

典型的问题:master节点的可用性,master节点故障整个集群就停掉了,启动多个master,那谁来提供服务?因为通常情况下,分布式系统中master都是有状态逻辑的,是无法允许多个master同时运行,因此可以通过etcd来实现选主。

将其中的一个master选举成leader,它负责控制整个集群中所有slave的状态,当被选举的leader将自己的ip注册到etcd中,使得slave节点能够及时的获取到,当前主节点地址从而使得系统按照之前单个master节点的方式继续工作,当leader节点发生异常了之后,通过etcd能够选举出一个新的节点称为组织节点,并且注册新的ip之后 slave又能够拿到新的主节点的ip 从而恢复服务,这一架构在分布式系统中被广泛的使用。

分布式系统并发控制

在分布式系统中,当去执行一些任务,比如升级os或升级os上的软件的时候或者执行一些计算任务的时候,通常情况下需要控制任务的并发度,因为任务依赖的后端服务是有容量瓶颈的,无法在同一个时刻同时拉起成千上万个服务,这样后端的存储或网络资源都是吃不消的,因此需要控制任务执行的并发度。

通过etcd提供的一些基本的api操作来完成分布式的协同。当第一个进程执行完毕以后,第二个进程就可以开始执行。同时利用etcd进程存活性检测机制可以做到,当我们将任务分发给一个进程,但这个进程没有执行完就已经死掉了之后,可以继续的换下一个进程继续的工作。

如果进程运行周期比较长,可以将进程运行中的状态数据存储到etcd,从而使得当进程故障之后,它需要恢复到其他地方的时候能够从etcd中恢复它的一些执行的状态,从而不需要完成整个的计算逻辑,从而加速整个任务的执行效率。

标签: #租约机制的程序流程图