python 版本分布式锁

简介:


此文章,实现python 版本的分布式锁,java版本的可以使用curator很容易实现,python版本如下


在做分布式系统开发的时候,分布式锁可以说是必需的一个组件。最近做了一些调研和尝试,经过对比,基于ZooKeeper的分布式锁还是很不错的。

 

参照了IBM的一个帖子:https://www.ibm.com/developerworks/cn/opensource/os-cn-zookeeper/

其中有一段话描述了ZooKeeper的共享锁(即分布式锁)实现,如下:

共享锁在同一个进程中很容易实现,但是在跨进程或者在不同 Server 之间就不好实现了。Zookeeper 却很容易实现这个功能,实现方式也是需要获得锁的 Server 创建一个 EPHEMERAL_SEQUENTIAL 目录节点,然后调用 getChildren方法获取当前的目录节点列表中最小的目录节点是不是就是自己创建的目录节点,如果正是自己创建的,那么它就获得了这个锁,如果不是那么它就调用 exists(String path, boolean watch) 方法并监控 Zookeeper 上目录节点列表的变化,一直到自己创建的节点是列表中最小编号的目录节点,从而获得锁,释放锁很简单,只要删除前面它自己所创建的目录节点就行了。


 通过这段话,大概可以明白其原理。下面我主要写一下基于Python的分布式锁实现。

实现

Google了一下,有个叫Kazoo的python开源包很好的实现了对ZooKeeper的支持。

Kazoo is a Python library designed to make working with Zookeeper a more hassle-free experience that is less prone to errors.

 

链接如下:https://kazoo.readthedocs.org/en/latest/

GitHub地址: https://github.com/python-zk/kazoo

 

 首先,我们去GitHub,下载其源码包。解压缩之后,进行安装

python setup.py install

 

OK,准备工作完成,一切尽在代码中:

文件名:zk_lock.py

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
#!/usr/bin/env python2. 7  
# -*- coding:utf- 8  -*-  
#  
#   Author  :   yunjianfei  
#   E-mail  :   yunjianfei1987 @gmail .com  
#   Date    :    2014 / 12 / 09  
#   Desc    :  
#  
   
import  logging, os, time  
from kazoo.client  import  KazooClient  
from kazoo.client  import  KazooState  
from kazoo.recipe.lock  import  Lock  
   
class  ZooKeeperLock():  
     def __init__(self, hosts, id_str, lock_name, logger=None, timeout= 1 ):  
         self.hosts = hosts  
         self.id_str = id_str  
         self.zk_client = None  
         self.timeout = timeout  
         self.logger = logger  
         self.name = lock_name  
         self.lock_handle = None  
   
         self.create_lock()  
   
     def create_lock(self):  
         try :  
             self.zk_client = KazooClient(hosts=self.hosts, logger=self.logger, timeout=self.timeout)  
             self.zk_client.start(timeout=self.timeout)  
         except Exception, ex:  
             self.init_ret = False  
             self.err_str =  "Create KazooClient failed! Exception: %s"  % str(ex)  
             logging.error(self.err_str)  
             return  
   
         try :  
             lock_path = os.path.join( "/" "locks" , self.name)  
             self.lock_handle = Lock(self.zk_client, lock_path)  
         except Exception, ex:  
             self.init_ret = False  
             self.err_str =  "Create lock failed! Exception: %s"  % str(ex)  
             logging.error(self.err_str)  
             return  
   
     def destroy_lock(self):  
         #self.release()  
   
         if  self.zk_client != None:  
             self.zk_client.stop()  
             self.zk_client = None  
   
     def acquire(self, blocking=True, timeout=None):  
         if  self.lock_handle == None:  
             return  None  
   
         try :  
             return  self.lock_handle.acquire(blocking=blocking, timeout=timeout)  
         except Exception, ex:  
             self.err_str =  "Acquire lock failed! Exception: %s"  % str(ex)  
             logging.error(self.err_str)  
             return  None  
   
     def release(self):  
         if  self.lock_handle == None:  
             return  None  
         return  self.lock_handle.release()  
   
   
     def __del__(self):  
         self.destroy_lock()  
   
   
def main():  
     logger = logging.getLogger()  
     logger.setLevel(logging.INFO)  
     sh = logging.StreamHandler()  
     formatter = logging.Formatter( '%(asctime)s -%(module)s:%(filename)s-L%(lineno)d-%(levelname)s: %(message)s' )  
     sh.setFormatter(formatter)  
     logger.addHandler(sh)  
   
     zookeeper_hosts =  "192.168.10.2:2181, 192.168.10.3:2181, 192.168.10.4:2181"  
     lock_name =  "test"  
   
     lock = ZooKeeperLock(zookeeper_hosts,  "myid is 1" , lock_name, logger=logger)  
     ret = lock.acquire()  
     if  not ret:  
         logging.info( "Can't get lock! Ret: %s" , ret)  
         return  
   
     logging.info( "Get lock! Do something! Sleep 10 secs!" )  
     for  i in range( 1 11 ):  
         time.sleep( 1 )  
         print str(i)  
   
     lock.release()  
   
if  __name__ ==  "__main__" :  
     try :  
         main()  
     except Exception, ex:  
         print  "Ocurred Exception: %s"  % str(ex)  
         quit()


测试的时候,只需要改一下“zookeeper_hosts ”这个参数,改为你自己的ZooKeeper的server地址即可.

 

将该测试文件copy到多个服务器,同时运行,就可以看到分布式锁的效果了。



转自:http://yunjianfei.iteye.com/blog/2164888






      本文转自布拉君君 51CTO博客,原文链接:http://blog.51cto.com/5148737/1975603,如需转载请自行联系原作者




相关文章
|
6月前
|
人工智能 数据安全/隐私保护 Python
小红书图文生成器,小红书AI图文生成工具,python版本软件
Pillow库自动生成符合平台尺寸要求的配图7;3)利用Playwright实现自动化发布流程6。
|
7月前
|
Ubuntu 安全 API
Python3.14正式支持Free Threaded版本!
Python 社区迎来历史性时刻!Python 3.14 正式将无 GIL 构建列为受支持选项,标志着 Free‑Threaded Phase II 启动。本文将深入解析 PEP 779 规定的支持标准、3.14.0b3 版本的新变化,以及这对Python开发者意味着什么。文末还有小彩蛋哦!
1247 87
|
人工智能 Python
【02】做一个精美的打飞机小游戏,python开发小游戏-鹰击长空—优雅草央千澈-持续更新-分享源代码和游戏包供游玩-记录完整开发过程-用做好的素材来完善鹰击长空1.0.1版本
【02】做一个精美的打飞机小游戏,python开发小游戏-鹰击长空—优雅草央千澈-持续更新-分享源代码和游戏包供游玩-记录完整开发过程-用做好的素材来完善鹰击长空1.0.1版本
512 7
|
6月前
|
API 数据安全/隐私保护 开发者
企业微信自动加好友软件,导入手机号批量添加微信好友,python版本源码分享
代码展示了企业微信官方API的合规使用方式,包括获取access_token、查询部门列表和创建用户等功能
|
Shell Python
使用 pyenv 来管理多个 Python 版本(2)
使用 pyenv 来管理多个 Python 版本(2)
449 71
使用 pyenv 来管理多个 Python 版本(2)
|
测试技术 Python
【03】做一个精美的打飞机小游戏,规划游戏项目目录-分门别类所有的资源-库-类-逻辑-打包为可玩的exe-练习python打包为可执行exe-优雅草卓伊凡-持续更新-分享源代码和游戏包供游玩-1.0.2版本
【03】做一个精美的打飞机小游戏,规划游戏项目目录-分门别类所有的资源-库-类-逻辑-打包为可玩的exe-练习python打包为可执行exe-优雅草卓伊凡-持续更新-分享源代码和游戏包供游玩-1.0.2版本
621 31
【03】做一个精美的打飞机小游戏,规划游戏项目目录-分门别类所有的资源-库-类-逻辑-打包为可玩的exe-练习python打包为可执行exe-优雅草卓伊凡-持续更新-分享源代码和游戏包供游玩-1.0.2版本
|
机器学习/深度学习 数据可视化 TensorFlow
使用Python实现深度学习模型的分布式训练
使用Python实现深度学习模型的分布式训练
511 73
|
10月前
|
机器学习/深度学习 分布式计算 API
Python 高级编程与实战:深入理解并发编程与分布式系统
在前几篇文章中,我们探讨了 Python 的基础语法、面向对象编程、函数式编程、元编程、性能优化、调试技巧、数据科学、机器学习、Web 开发、API 设计、网络编程和异步IO。本文将深入探讨 Python 在并发编程和分布式系统中的应用,并通过实战项目帮助你掌握这些技术。
|
10月前
|
消息中间件 分布式计算 并行计算
Python 高级编程与实战:构建分布式系统
本文深入探讨了 Python 中的分布式系统,介绍了 ZeroMQ、Celery 和 Dask 等工具的使用方法,并通过实战项目帮助读者掌握这些技术。ZeroMQ 是高性能异步消息库,支持多种通信模式;Celery 是分布式任务队列,支持异步任务执行;Dask 是并行计算库,适用于大规模数据处理。文章结合具体代码示例,帮助读者理解如何使用这些工具构建分布式系统。
|
分布式计算 DataWorks 数据处理
产品测评 | 上手分布式Python计算服务MaxFrame产品最佳实践
MaxFrame是阿里云自研的分布式计算框架,专为大数据处理设计,提供高效便捷的Python开发体验。其主要功能包括Python编程接口、直接利用MaxCompute资源、与MaxCompute Notebook集成及镜像管理功能。本文基于MaxFrame最佳实践,详细介绍了在DataWorks中使用MaxFrame创建数据源、PyODPS节点和MaxFrame会话的过程,并展示了如何通过MaxFrame实现分布式Pandas处理和大语言模型数据处理。测评反馈指出,虽然MaxFrame具备强大的数据处理能力,但在文档细节和新手友好性方面仍有改进空间。

推荐镜像

更多