【Consul】Consul架构-Session会话

x33g5p2x  于2021-12-20 转载在 其他  
字(2.4k)|赞(0)|评价(0)|浏览(406)

     Consul提供session会话机制——可以用于构建分布式锁,session可以绑定到节点、健康检查、KV数据。目的是提供颗粒锁——受 The Chubby LockService for Loosely-Coupled Distributed Systems启发。

     本节主要讲解consul内部技术细节,使用consul不需要必须了解这些细节的。这些文章是为那些不愿意深入源代码但是希望技术细节的人准备的。

1.1 session设计

     Consulsession代表一个有非常具体的语义——合约,当构建一个session时,需要提供节点名称,健康检查列表,行为, TTL,锁期限。。新建session返回唯一的标识ID。此ID可用于作为与KV操作的锁:互斥机制。

     下面一个各部分间的关系图:

     Consul提供的合约,发生如下任一情况,session都会被销毁:

     •节点销毁

     •任何的健康检查,注销

     •任何健康检查都要进入Critical状态

     •会话被显式销毁

     •TTL到期,如果适用

     当session失效后,会被销毁,不能再使用。关联的锁发生什么行为,取决于创建时指定的修饰符。Consul支持release和delete两种处理方式。如果没有指定,默认为release。

     如果使用release,任何与该session相关的锁都会被释放,并且持有该锁的key的ModifyIndex也会递增。

     如果使用了Delete,持有该锁的KEY将会被删除。

     虽然这只是说简单的设计,但启用了众多的使用模式。默认情况下,基于故障检测的gossip可用协同健康检查。这种故障检测允许Consul自动释放故障节点持有的锁。为Consul locks提供liveness特性(活性),也就是说,在系统故障后,集群可以继续运转。然而,由于没有完美的故障检测器,它可能有一个假阳性(伪故障),这导致锁被释放,即使锁的所有者仍然活着。这意味着我们牺牲了一些安全。

     第二,可以创建一个健康检查无关的会话。这消除安全隐患。即使现有的持有者已经故障,consul也不会释放锁。由于Consul API允许会话强制销毁。此时,就绪管理员手骨干预,以防止出现脑裂。

     第三,使用TTL创建于健康检查有关的session。创建一个会话时,指定TTL。如果TTL时间到期没有续签,会话会过期或失效**。这种类型的故障检测器也被称为一个心跳故障检测器**。由于增加server节点的负担,但是其扩展性不如基于gossip的故障检测,但在这种机制适合某些场景。TTL合约代表了下界失效,也就是说,在TTL到达之前,consul session不会失效,允许 TTL进行延期——会话创建(create),重新开始(renew),leader故障。当使用TTL时,client需要注意时钟偏移问题:即在client与server间要保证时间同步,最好的是,在设置TTL值时,考虑网络延迟和时间偏移因素。

     最后的细微差别在于会话可能会提供一个锁的延迟。这是一个持续时间,在0到60秒之间。当一个会话失效发生,consul防止在lock-delay间隔内先前的锁持有重新持有锁。这是设计灵感来自Google'sChubby。这种delay的目的是让潜在的仍然活的Leader来检测无效请求和停止处理可能导致不一致状态的请求。While not a bulletproof method, it does avoid the need to introducesleep states into application logic and can help mitigate many issues. Whilethe default is to use a 15 second delay, clients are able to disable thismechanism by providing a zero delay value.

1.2 K/V集成

     KV存储和会话的集成是使用会话的主要场景。必须在使用之前创建一个会话,然后使用它的ID。

     KV API支持acquire和release操作,acquire操作类似检查-设置(Check-And-Set)操作——只有当锁不存在持有者时才会返回成功。当成功时,某个normal标识会更新,也会递增LockIndex,当然也会更新session的信息。

     如果在acquire操作时,与session相关的锁已经持有,那么LockIndex就不会递增,但是key值会更新,这就允许锁的当前持有者无需重新获得锁就可以更新key的内容。

     一旦获得锁,所需要经release操作来释放(使用相同的session)。Release操作也类似于检查-设置(Check-And-Set)操作。如果给定的session无效,那么请求会失败。需要特别注意的是,无需经过session的创建者,lock也是可以被释放的。这种设计是允许操作者干预来终止会话,在需要的时候。如上所述,会话无效也将导致所有被持有的锁被释放或删除。当锁被释放时,LockIndex不会变化,但是session会被清空,并且ModifyIndex递增。

     这些语义允许元组(Key,LockIndex,Session)作为一个独特的“序列”。这个序列可以被传递和用于验证请求是否属于当前的锁持有者。因为每次acquire 都会导致LockIndex递增,即使同一会话中重新获取锁,该序列能够检测到陈旧的请求。同样,如果会话失效,相应的LockIndex将为空。

     要清楚的是,这种锁系统是纯粹的咨询。并不是强制Client必须获取锁再能执行操作作。任何客户端都可以在未获得锁的情况下读取、写入和删除Key操作。它不是Consul用于保护系统的方法。

1.3 Leader选举

     通过Session提供的原语和KV存储的lock机制可以用来建立client端的leader选举算法。详细细节可以参照《leader Electionguide》。

相关文章