python3使用python-redis-lock解决并发计算问题

作者:海洋的渔夫 时间:2021-05-09 16:04:18 

需求

我在最近的一个任务中,存在一个redis高并发计算多个客户端接收预警信息的时长问题。

模型是首先模拟多个客户端连接预警服务器集群,然后向预警服务集群发送告警信息。随后预警服务集群将会向客户端推送告警信息。

此时,我记录了发送告警至预警集群的时间,并且在客户端还会记录接收到告警的时间。

我将这个时间都会记录到redis中,那么此时就会有一个问题,当多个客户端抢占式往redis 读取数据,计算,设置数据,这个过程是会被相互覆盖的。

python3使用python-redis-lock解决并发计算问题

可以从上面的截图来看,多个不同的客户端读取redis的数据,大部分读取到了同一个数据,导致计算错误。

导致问题的示意图如下:

python3使用python-redis-lock解决并发计算问题

为了解决这个问题,则可以编写一个redis的锁,用来控制数据的并发读取以及写入。
在python redis库默认只有乐观锁的一种写法,在这里我再推荐使用一个库python-redis-lock,使用这个库对redis多个客户端并发的情况加锁,真的很方便。
下面来看看怎么使用。

python-redis-lock

https://pypi.org/project/python-redis-lock/

在使用这个库之前,需要安装如下:


pip install python-redis-lock

使用锁的示例:


lock = redis_lock.Lock(conn, "name-of-the-lock")
if lock.acquire(blocking=False):
   print("Got the lock.")
   lock.release()
else:
   print("Someone else has the lock.")

上面是单独设置锁的方式,还可以单独设置所有redis的操作加入锁。


# On application start/restart
import redis_lock
redis_lock.reset_all(redis_client)

修改业务代码,增加lock操作

1. 首先导入redis_lock


import redis_lock

2.将redis连接的客户端传入lock中,并设置lock的名称


# 设置redis连接
self.conn = redis.Redis(host='127.0.0.1', port=6379, decode_responses=True, db=3)

# 设置redis锁
self.lock = redis_lock.Lock(self.conn, "redis-lock")

3.将业务读取、设置redis的部分加入锁


while True:
   # 设置redis锁,操作redis
   if self.lock.acquire(blocking=False):
       print("Got the lock.")
       # 获取lock,执行业务处理
       # 获取当前redis钟记录的客户端接收到告警的总时长
       recv_time_sum_count_clients = self.conn.get(recv_time_sum_count_clients_key)
       if recv_time_sum_count_clients is None:
           recv_time_sum_count_clients = "0:0"

# 获取当前的统计数据
       recv_time_sum, count_clients = recv_time_sum_count_clients.split(":")

# 计算告警接收总时长
       recv_time_sum = float(recv_time_sum) + recv_time
       # 计算收到预警的客户端数量
       count_clients = int(count_clients) + 1

# 写入redis中
       recv_time_sum_count_clients = "%s:%s" % (str(recv_time_sum), str(count_clients))
       self.conn.set(recv_time_sum_count_clients_key, recv_time_sum_count_clients)

print("user_id = %s, 计算平均时间成功, "
             "recv_time_sum = %s, count_clients = %s \n" %
             (self.user_id, recv_time_sum, count_clients))

# 释放lock
       self.lock.release()

# 退出循环
       break
   else:
       print("Someone else has the lock.")

在客户端的代码中设置了锁之后,再来执行一下,看看有无抢占读取redis数据的情况,如下:

python3使用python-redis-lock解决并发计算问题

设置了锁之后,客户端由于并发导致redis数据读取、设置错误的情况就可以避免了。

并且这个库还可以使用到Django框架中,更多细节读者可以到该库Github中细细查阅,本篇章就不介绍了,哈哈。

来源:https://blog.csdn.net/u012887259/article/details/103870425

标签:python-redis-lock,并发
0
投稿

猜你喜欢

  • Linux下Python脚本自启动和定时启动的详细步骤

    2022-08-13 20:51:22
  • Python 将json序列化后的字符串转换成字典(推荐)

    2021-11-17 12:36:51
  • python实现excel转置问题详解

    2023-06-27 23:27:27
  • PyCharm专业最新版2019.1安装步骤(含激活码)

    2022-10-21 19:56:06
  • Linux下编译安装MySQL-Python教程

    2021-05-03 05:05:40
  • asp.net iis 无法显示网页的解决方法分析

    2023-07-21 23:34:53
  • pygame游戏之旅 调用按钮实现游戏开始功能

    2023-04-19 06:36:44
  • 基于Python创建可定制的HTTP服务器

    2023-08-09 22:46:09
  • 实例演示在SQL中启用全文检索

    2011-10-01 14:01:37
  • PHP中file_get_contents函数抓取https地址出错的解决方法(两种方法)

    2023-10-14 02:31:42
  • JavaScript运动框架 多值运动(四)

    2023-09-08 01:44:51
  • Python常见MongoDB数据库操作实例总结

    2023-07-08 08:48:34
  • 八卦调侃Reset CSS

    2010-01-13 13:01:00
  • 用Python实现一个简单的线程池

    2023-09-21 15:14:56
  • Python开发编码规范

    2021-04-10 21:07:53
  • 一文带你搞懂PHP单例模式

    2023-05-25 02:23:05
  • oracle chm帮助文件下载

    2010-07-16 12:49:00
  • python内置函数之eval函数详解

    2022-07-22 12:39:29
  • 详解python string类型 bytes类型 bytearray类型

    2023-09-22 20:47:18
  • Oracle与SQL Server数据库镜像对比

    2009-03-25 14:27:00
  • asp之家 网络编程 m.aspxhome.com