基于redis的分布式锁--python实现

直接上代码

 1 # coding=utf-8
 2
 3
 4 # 使用redis实现分布式锁的原因
 5 # 1 redis性能好
 6 # 2 redis命令对此支持较好,实现起来比较方便
 7
 8 """
 9 redis命令介绍
10     setnx key val  当且仅当key不存在时,set一个key为val的字符串,返回1;若key存在,则什么都不做,返回0
11     expire key timeout  为key设置一个超时时间,单位为second,超过这个时间锁会自动释放,避免死锁
12     delete key  删除key
13 """
14 import time
15 import uuid
16 from threading import Thread
17
18 import redis
19
20 redis_client = redis.Redis(host="localhost", port=6379, db=2)
21
22
23 def acquire_lock(lock_str, acquire_time=10, time_out=10):
24     """设置锁"""
25     lock_key = "string:lock:" + lock_str
26     identifier_uuid_str = str(uuid.uuid4())
27     end = time.time() + acquire_time
28
29     try:
30         while time.time() < end:
31             if redis_client.setnx(lock_key, identifier_uuid_str):
32                 # 设置超时时间,防止进程崩溃导致其他进程无法获取锁
33                 redis_client.expire(lock_key, time=time_out)
34                 return identifier_uuid_str
35
36             elif not redis_client.ttl(lock_key):
37                 redis_client.expire(lock_key, time=time_out)
38             time.sleep(0.01)
39     finally:
40         # 释放锁
41         redis_client.delete(lock_key)
42         return False
43
44
45 def release_lock(lock_str, identifier_uuid_str):
46     """释放锁"""
47     lock = "string:lock:" + lock_str
48     pip = redis_client.pipeline(True)
49     while True:
50         try:
51             pip.watch(lock)
52             lock_value = redis_client.get(lock)
53             if not lock_value:
54                 return True
55
56             if lock_value.decode() == identifier_uuid_str:
57                 pip.multi()
58                 pip.delete(lock)
59                 pip.execute()
60                 return True
61             pip.unwatch()
62             break
63         except redis.exceptions.WatchError:
64             pass
65     return False
66
67
68 # 秒杀demo
69 def seckill(product_id, t_id):
70     identifier_uuid_str = acquire_lock(product_id)
71     if not identifier_uuid_str:
72         return "error"
73     print "线程:{}--获得了锁".format(t_id)
74     stock = int(redis_client.get("stock"))
75     if stock > 0:
76         real_stock = stock - 1
77         redis_client.set("stock", str(real_stock))
78         print "线程:{}--抢到一件商品,剩余库存{}件".format(t_id, real_stock)
79     else:
80         print "线程:{}--没抢到,库存不足".format(t_id)
81         return
82     release_lock(product_id, identifier_uuid_str)
83     print "线程:{}--释放了锁".format(i)
84
85
86 # redis-cli: set stock 20
87 for i in range(25):
88     product_id = "product_001"
89     t = Thread(target=seckill, args=(product_id, i,))
90     t.start()

实际还存在一个问题,如果任务的执行时间超过了锁的有效期,就会导致其他进程获取锁,会出现释放的锁并非当前任务加的锁的情况,这里可以另开一个线程在一定时间内不断为锁续命。

原文地址:https://www.cnblogs.com/82nlf-xlqb/p/12116167.html

时间: 2024-10-10 03:47:14

基于redis的分布式锁--python实现的相关文章

python基于redis实现分布式锁

阅读目录 什么事分布式锁 基于redis实现分布式锁 一.什么是分布式锁 我们在开发应用的时候,如果需要对某一个共享变量进行多线程同步访问的时候,可以使用我们学到的锁进行处理,并且可以完美的运行,毫无Bug! 注意这是单机应用,后来业务发展,需要做集群,一个应用需要部署到几台机器上然后做负载均衡,大致如下图: 上图可以看到,变量A存在三个服务器内存中(这个变量A主要体现是在一个类中的一个成员变量,是一个有状态的对象),如果不加任何控制的话,变量A同时都会在分配一块内存,三个请求发过来同时对这个变

基于Redis的分布式锁到底安全吗(上)?

网上有关Redis分布式锁的文章可谓多如牛毛了,不信的话你可以拿关键词"Redis 分布式锁"随便到哪个搜索引擎上去搜索一下就知道了.这些文章的思路大体相近,给出的实现算法也看似合乎逻辑,但当我们着手去实现它们的时候,却发现如果你越是仔细推敲,疑虑也就越来越多. 实际上,大概在一年以前,关于Redis分布式锁的安全性问题,在分布式系统专家Martin Kleppmann和Redis的作者antirez之间就发生过一场争论.由于对这个问题一直以来比较关注,所以我前些日子仔细阅读了与这场争

基于redis的分布式锁

<?php /** * 基于redis的分布式锁 * * 参考开源代码: * http://nleach.com/post/31299575840/redis-mutex-in-php * * https://gist.github.com/nickyleach/3694555 */ pc_base::load_sys_class('cache_redis', '', 0); class dist_key_redis { //锁的超时时间 const TIMEOUT = 20; const SL

转载:基于Redis实现分布式锁

转载:基于Redis实现分布式锁  ,出处: http://blog.csdn.net/ugg/article/details/41894947 背景在很多互联网产品应用中,有些场景需要加锁处理,比如:秒杀,全局递增ID,楼层生成等等.大部分的解决方案是基于DB实现的,Redis为单进程单线程模式,采用队列模式将并发访问变成串行访问,且多客户端对Redis的连接并不存在竞争关系.其次Redis提供一些命令SETNX,GETSET,可以方便实现分布式锁机制. Redis命令介绍使用Redis实现分

基于redis的分布式锁(不适合用于生产环境)

基于redis的分布式锁 1 介绍 这篇博文讲介绍如何一步步构建一个基于Redis的分布式锁.会从最原始的版本开始,然后根据问题进行调整,最后完成一个较为合理的分布式锁. 本篇文章会将分布式锁的实现分为两部分,一个是单机环境,另一个是集群环境下的Redis锁实现.在介绍分布式锁的实现之前,先来了解下分布式锁的一些信息. 2 分布式锁 2.1 什么是分布式锁? 分布式锁是控制分布式系统或不同系统之间共同访问共享资源的一种锁实现,如果不同的系统或同一个系统的不同主机之间共享了某个资源时,往往需要互斥

基于redis的分布式锁实现

关于分布式锁 很久之前有讲过并发编程中的锁并发编程的锁机制:synchronized和lock.在单进程的系统中,当存在多个线程可以同时改变某个变量时,就需要对变量或代码块做同步,使其在修改这种变量时能够线性执行消除并发修改变量.而同步的本质是通过锁来实现的.为了实现多个线程在一个时刻同一个代码块只能有一个线程可执行,那么需要在某个地方做个标记,这个标记必须每个线程都能看到,当标记不存在时可以设置该标记,其余后续线程发现已经有标记了则等待拥有标记的线程结束同步代码块取消标记后再去尝试设置标记.

[Redis] 基于redis的分布式锁

前言分布式锁一般有三种实现方式:1. 数据库乐观锁:2. 基于Redis的分布式锁:3. 基于ZooKeeper的分布式锁.本篇博客将介绍第二种方式,基于Redis实现分布式锁. 可靠性首先,为了确保分布式锁可用,我们至少要确保锁的实现同时满足以下四个条件: 互斥性.在任意时刻,只有一个客户端能持有锁.不会发生死锁.即使有一个客户端在持有锁的期间崩溃而没有主动解锁,也能保证后续其他客户端能加锁.具有容错性.只要大部分的Redis节点正常运行,客户端就可以加锁和解锁.解铃还须系铃人.加锁和解锁必须

基于redis的分布式锁的分析与实践

转:https://my.oschina.net/wnjustdoit/blog/1606215 前言:在分布式环境中,我们经常使用锁来进行并发控制,锁可分为乐观锁和悲观锁,基于数据库版本戳的实现是乐观锁,基于redis或zookeeper的实现可认为是悲观锁了.乐观锁和悲观锁最根本的区别在于线程之间是否相互阻塞. 那么,本文主要来讨论基于redis的分布式锁算法问题. 从2.6.12版本开始,redis为SET命令增加了一系列选项(SET key value [EX seconds] [PX

基于Redis的分布式锁和Redlock算法

1 前言 前面写了4篇Redis底层实现和工程架构相关文章,感兴趣的读者可以回顾一下: Redis面试热点之底层实现篇-1 Redis面试热点之底层实现篇-2 Redis面试热点之工程架构篇-1 Redis面试热点之工程架构篇-2 今天开始来和大家一起学习一下Redis实际应用篇,会写几个Redis的常见应用. 在我看来Redis最为典型的应用就是作为分布式缓存系统,其他的一些应用本质上并不是杀手锏功能,是基于Redis支持的数据类型和分布式架构来实现的,属于小而美的应用. 结合笔者的日常工作,