【代码】基于etcd的分布式锁(python版)

开发者福利!热门AI工具限时免费用 购周边即赠Coding Plan Lite,Claude Code、Cursor等20+工具畅享,效率翻倍! 阅读详情

参考k8s的leader选举: k8s.io/client-go/tools/leaderelection

import os
import socket
import time
from threading import Thread

import etcd3


class DistributedLock(object):
    def __init__(self, etcd, name, ttl, renew):
        self.etcd: etcd3.Etcd3Client = etcd
        self.key = f"/locks/{name}"
        self.value = f"{socket.gethostname()}-{os.getpid()}"
        self.renew_value = lambda: self.value + f" {time.time()}"
        self.ttl = ttl
        self.renew = renew
        self.acquired = False
        self.holder = None

    def acquire(self):
        value = self.etcd.get(self.key)[0]
        if value is None:
            print('init acquire')
            succeeded, resp = self.etcd.transaction(compare=[etcd.transactions.create(self.key) == 0],
                                                    success=[etcd.transactions.put(self.key, self.renew_value())],
                                                    failure=[etcd.transactions.get(self.key)])
            if not succeeded:
                print('init acquire failure')
                holder = resp[0][0][0].decode().split(' ')[0]
            else:
                print('init acquire success')
                holder = self.value
        else:
            holder, alive_time = value.decode().split(' ')
            print('current holder: ', holder)
            if float(alive_time) + self.ttl < time.time():
                print('holder may dead, try to acquire')
                succeeded, resp = self.etcd.transaction(compare=[etcd.transactions.value(self.key) == value],
                                                        success=[etcd.transactions.put(self.key, self.renew_value())],
                                                        failure=[etcd.transactions.get(self.key)])
                if not succeeded:
                    print('try acquire failure')
                    holder = resp[0][0][0].decode().split(' ')[0]
                else:
                    print('try acquire success')
                    holder = self.value
            else:
                if holder == self.value:
                    succeeded, resp = self.etcd.transaction(compare=[etcd.transactions.value(self.key) == value],
                                                            success=[
                                                                etcd.transactions.put(self.key, self.renew_value()), ],
                                                            failure=[etcd.transactions.get(self.key)])
                    if succeeded:
                        print('holder is alive, refreshed success')
                    else:
                        print('holder is alive, refreshed failure')
                else:
                    print("holder is alive, can't acquire")
                succeeded = holder == self.value
        print(self.value, "acquired: ", succeeded)
        self.acquired = succeeded
        self.holder = holder

    def release(self):
        value = self.etcd.get(self.key)[0]
        if value is None:
            return
        holder = value.decode().split(' ')
        if holder != self.value:
            return
        succeeded, _ = self.etcd.transaction(compare=[etcd.transactions.value(self.key) == value[0]],
                                             success=[etcd.transactions.put(self.key, self.value)],
                                             failure=[etcd.transactions.get(self.key)])

    def refresh(self):
        def try_acquire_or_refresh():
            while 1:
                self.acquire()
                time.sleep(self.renew)

        thread = Thread(target=try_acquire_or_refresh)
        thread.start()
        thread.join()

    def is_acquired(self):
        return self.acquired


if __name__ == '__main__':
    etcd = etcd3.client()
    lock = DistributedLock(etcd, 'global', 10, 3)
    lock.acquire()
    lock.refresh()

Python连接Etcd集群基础教程 最近接手了一个项目,项目是使用Python开发的,其中使用到了Etcd,但是项目之前开发的方式,只能够支持单节点连接Etcd,不能够在Etcd节点发生故障时,自动转移。因此需要实现基于现有etcd sdk 开发一个能够实现故障转移的功能,或者更换etcd sdk来实现故障转移等功能。先来看看项目之前使用到的 etcd 库,即,通过给出的示例,没有看到可以连接多节点的方式,深入到源码后,也没有发现可以连接多节点的方式,基本上可以断定之前使用到的 etcd sdk 不支持集群方式了。 阅读详情

相关推荐

Python-一个etcdpython客户端

基于etcd实现leader election功能,让普通脚本也可以运行在分布式环境实现高可用

探秘 `python-etcd3`:Python中的Etcd客户端库

探秘 python-etcd3Python中的Etcd客户端库 项目地址:https://gitcode.com/gh_mirrors/py/python-etcd3 在分布式系统和微服务架构中,Etcd是一个广泛使用的键值存储服务,它提供了高可用性和一致性保证。而python-etcd3Python社区为对接Etcd 3.x本专门开发的一个强大的客户端库。本文将详细介绍这个项目的技术特性,...

gitblog_00026的博客 1242

python-etcd3:etcd API v3Python 客户端

python-etcd3 etcd API v3Python 客户端,在 python 2.7、3.4 和 3.5 下支持。 警告:API 大部分是稳定的,但将来可能会发生变化 如果您有兴趣使用此库,请参与。 免费软件:Apache 软件许可证 2.0 文档: : 。 基本用法: import etcd3 etcd = etcd3 . client () etcd . get ( &#39;foo&#39; ) etcd . put ( &#39;bar&#39; , &#39;doot&#39; ) etcd . delete ( &#39;bar&#39; ) # locks lock = etcd . lock ( &#39;thing&#39; ) lock . acquire () # do something lock . release () with etcd . lock ( &#39;doot-machine&#39; ) as lock

python技术简介(三)

应用场景-服务注册与发现:服务注册是指服务实例在启动时,将自己的网络地址(IP 和端口)注册到服务注册中心(如 etcd)。注册中心维护了一个服务实例的目录,客户端可以通过查询注册中心来发现可用的服务实例。服务发现是指客户端从服务注册中心获取可用的服务实例列表,以便进行请求路由。当某个服务实例不可用或增加新的实例时,服务注册中心会相应地更新注册信息。我们现在可以使用 etcd3 库,实现来为我们的。# 获取以指定前缀开头的所有键值。# 删除以指定前缀开头的所有键值。的服务进行服务注册和发现。

jpx65536的博客 327

【亲测免费】 Python-etcd3 项目常见问题解决方案

Python-etcd3 项目常见问题解决方案 1. 项目基础介绍和主要编程语言 项目名称: Python-etcd3 项目简介: Python-etcd3 是一个开源的 Python 客户端库,用于与 etcd 的 API v3 进行交互。etcd 是一个分布式键值存储系统,用于保存元数据并提供分布式系统中的协调和配置服务。 主要编程语言: Python 2. 新手使用时需特别注意的三个问题及解...

gitblog_00356的博客 451

利用etcd实现分布式锁

python中已经自带了分布式锁的实现方式,下面我们尝试一下加锁与解锁的流程在运行该demo同时也对lock对应的key进行watch,观察其变化,注意python-etcd3在实现分布式锁的时候,采用的key需要加上prefix:在这里插入图片描述结果如下:当获取到锁的时候value改变,当release的时候锁value为空,此时cancel掉对当前key的watch。

hanhan的博客 2166

分布式锁(3)--基于Etcd分布式锁实现

当我学到一定基础,有自己的理解能力的时候,会去阅读一些前辈整理的书籍或者手写的笔记资料,这些笔记详细记载了他们对一些技术点的理解,这些理解是比较独到,可以学到不一样的思路。Python所有方向的技术点做的整理,形成各个领域的知识点汇总,它的用处就在于,你可以按照下面的知识点去找对应的学习资源,保证自己学得较为全面。实现分布式锁会非常的方便,同时它是通过HTTP/gRPC提供对应的API,所以它的客户端实现也比较方便,当然如果当前系统依赖的是。的作用,实现的分布式锁默认带有了公平锁的功能,接下来开始手撸。

aobulaien001的博客 848

还活在上个时代,Etcd 3.0 实现分布式锁竟如此简单

传统 Python 单机系统部署中,由于 GIL 的存在,相同进程中我们可以不用处理并发问题。但是随着业务发展需要,原有单机系统演变成分布式或多进程系统后。这将使原有的单机单进程并发控制策略失效。为了解决该问题需要引入一种跨进程、跨机器的互斥锁机制来控制共享资源的访问,这也就是分布式锁的由来。 所以,分布式锁的引入是为了保障多台机器或多个进程对共享资源读写的同步,保证数据的最终一致性。...

1811

etcd 笔记(08)— 基于 etcd 实现分布式锁

基于 etcd 实现分布式锁

wohu1104的专栏 981

分布式锁实战指南:Redis、ZooKeeper、etcd 三大方案深度对比与避坑指南(附代码

本文通过“百人抢厕所”的生动类比,系统讲解了分布式锁的核心原理与应用场景。针对Redis、ZooKeeper和etcd三大主流方案,文章详细分析了各自的实现机制、性能表现及适用场景,并提供了可直接复用的代码示例。特别指出Redis的高性能优势与潜在风险,ZooKeeper的强一致性特点,以及etcd在云原生环境中的平衡表现。最后通过2025年实测数据对比和选型决策树,帮助开发者快速选择最优方案。文中还分享了生产环境中的避坑经验,包括锁重入、死锁预防等高级技巧,为分布式系统开发提供实用指导。

松阳的编程向导 1329

推荐开源项目:Python-Etcd——EtcdPython客户端

`Python-Etcd` 是一个针对Etcd(来自CoreOS的分布式键值存储系统)的完整Python客户端。该项目旨在提供与Etcd服务器本2.0.x及更高本兼容的接口,支持Python 2.7和Python 3.3及以上本。 官方文档地址:[http://python-etcd.readthedocs.org/](http://python-etcd.readthedocs.org/

gitblog_00019的博客 619

python-etcd3, etcd API v3python 客户端.zip

python-etcd3, etcd API v3python 客户端 python-etcd3 etcd,支持 python 2.7,3.4和 3.5下的python 客户端。警告:API主要是稳定的,但是将来可能会发生变化如果你对使用这里库感兴趣,请参与。自由软件:Apach

python-etcd:用于etcdpython客户端

python-etcd文档 Etcdpython客户端 官方文档: : 安装 前提条件 此本的python-etcd仅可与etcd服务器2.0.x或更高本一起正常使用。 如果您正在运行旧etcd,请使用python-etcd 0.3.3或更早本。 已知此客户端可与python 2.7和python 3.3或更高本一起使用。 它未经测试或预期无法在更旧的python本中工作。 从来源 $ python setup.py install 从皮皮 $ python3.5 -m pip install python-etcd 用法 与以前的本相比,客户端的基本方法已更改,以反映新的API结构; 但是,已维护了兼容性层,因此您不必重写所有现有代码。 创建一个客户端对象 import etcd client = etcd . Client () # this will c

etcd备忘录

etcd分布式锁python/go的使用

rgc_520_zyl的博客 590

python 微服务 etcd_架构之微服务(etcd)

1. ETCD是什么ETCD是用于共享配置和服务发现的分布式,一致性的KV存储系统。该项目目前最新稳定本为2.3.0. 具体信息请参考[项目首页]和[Github]。ETCD是CoreOS公司发起的一个开源项目,授权协议为Apache。提供配置共享和服务发现的系统比较多,其中最为大家熟知的是[Zookeeper](后文简称ZK),而ETCD可以算得上是后起之秀了。在项目实现,一致性协议易理解性,...

weixin_39892800的博客 546

Redis分布式锁实现

本文介绍了Redis分布式锁的实现原理与生产级实践。首先分析了分布式锁的必要性及其必须满足的互斥性、安全性等五个条件。随后详细讲解了Redis分布式锁的演进过程,从基础的SETNX+EXPIRE到原子性SET命令,再到解决单点问题的Redlock算法。针对Redlock的争议,作者指出其在大多数业务场景下仍是最佳选择。最后提供了一个Python实现的分布式锁类,支持自动续约、可重入等特性,可直接用于项目开发。全文150字,概括了Redis分布式锁的核心要点与实践方案。

闲人编程的博客 1896

etcd 自动刷新令牌客户端

让你“无感”使用带认证的 etcd:token 过期 → 自动刷新 → 重试一次,业务代码完全不用改;再配合前面那套 key 前缀规范,就把“分布式锁 / 动态配置 / 服务注册”三件事全管了。

Leon_Jinhai_Sun的博客 856

基于 Tenacity 的 Etcd 锁非阻塞获取逻辑

这段代码实现了一个带超时机制的 etcd 分布式锁获取逻辑不依赖父类(super)的阻塞式acquire逻辑,而是通过「每秒尝试一次获取锁 + 超时终止」的方式实现;基于tenacity库(Python 重试库)实现重试逻辑,确保在超时时间内持续尝试获取锁;最终返回「是否成功获取锁」的布尔值。这段代码的核心是用 tenacity 封装 etcd 锁的重试逻辑,将「永久阻塞获取锁」改为「带超时的周期性重试」,既保证了锁的获取能力,又避免了进程无限期阻塞,是分布式场景中常见的锁优化方式。

Leon_Jinhai_Sun的博客 881
上一篇: 【代码】基于mmap和fcntl的一写多读实现
下一篇: 【代码】flask通过uds传输socket描述符实践
azach64
博客等级 码龄8年 25粉丝 68原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值