【consul】consul的锁应用

前言

在建设数据库高可用的时候,采用了consul的机制实现,在开发相关组件的时候,使用了consul的锁机制。但是由于使用的不正确,带来了一些问题,下面主要介绍我的使用场景及使用方式,出现的问题,以及正确的使用方法。

我的使用场景及使用方式简介

在进行数据库高可用的选举组件设计时,考虑使用consul的锁来进行consul-server的选举,谁先获取到锁,谁就成为consul-server的leader,由leader实施数据库选主。

组件开发选用python进行开发,consul驱动使用的是python的consul驱动:【https://pypi.org/project/python-consul/】
驱动对于consul的相关操作基本与consul提供的api功能保持一致。

设计中每一套高可用服务都有一个锁k-v,选举动作触发的时候,所有consul-server都会尝试对这个锁k-v加锁,绑定自己的session id,完成选主动作后,再释放锁,即:

import consul
lock_key = "app1/master1/lock_key"
CONSUL_CLI = consul.Consul()
sid = CONSUL_CLI.session.create()
lock_flag = CONSUL_CLI.kv.put(lock_key, "test1-acquire", acquire=sid)
"""
选举...
"""
CONSUL_CLI.session.destroy(sid)

存在的问题

当高可用服务中,假设架构为
A:主
B:从1
C:从2
连续两个节点A、B故障,此时应该由A切换到B,然后由B切换到C。

但是实际发生的时候,由A切换到B,但是B无法切换到C。

根据分析和测试,发现consul的锁有两个点没注意到:
1、consul的锁在非正常释放的时候,会根据session的lock_delay参数进行解锁延迟,这个lock_delay默认是15s。
2、通过destroy session的方式释放锁是非正常的锁释放,需要通过release操作才是正确的锁释放。

根据这两个点,基本上能确定,为什么A切换到B后,无法切换到C。

主要是A、B连续故障,选举间隔在15s内,而程序是通过destroy session来释放锁,会有15s的锁释放延迟,导致B故障的时候consul-server无法获取到锁,从而无法进行选主,也就无法切换到C节点了。

正确的使用

根据以上两点,做了两点调整
1、通过release方式释放锁,使得锁能够正确释放;
2、将lock_delay调成2s,避免非正常释放锁的情况下其他consul-server无法获取到锁,从而无法选举出正确的主节点;
demo

import consul
lock_key = "app1/master1/lock_key"
CONSUL_CLI = consul.Consul()
sid = CONSUL_CLI.session.create(lock_delay=2)
lock_flag = CONSUL_CLI.kv.put(lock_key, "test1-acquire", acquire=sid)
"""
选举...
"""
lock_flag = CONSUL_CLI.kv.put(lock_key, "test1-release", release=sid)
CONSUL_CLI.session.destroy(sid)
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章