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

目录
  • 需求
  • python-redis-lock
  • 修改业务代码,增加lock操作

需求

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

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

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

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

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

导致问题的示意图如下:

为了解决这个问题,则可以编写一个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数据的情况,如下:

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

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

到此这篇关于python3使用python-redis-lock解决并发计算问题的文章就介绍到这了,更多相关python-redis-lock 并发内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • Redis分布式锁python-redis-lock使用方法

    python-redis-lock 多个redis客户端访问同一个redis服务端,控制并发. github: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(&qu

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

    目录 需求 python-redis-lock 修改业务代码,增加lock操作 需求 我在最近的一个任务中,存在一个redis高并发计算多个客户端接收预警信息的时长问题. 模型是首先模拟多个客户端连接预警服务器集群,然后向预警服务集群发送告警信息.随后预警服务集群将会向客户端推送告警信息. 此时,我记录了发送告警至预警集群的时间,并且在客户端还会记录接收到告警的时间. 我将这个时间都会记录到redis中,那么此时就会有一个问题,当多个客户端抢占式往redis 读取数据,计算,设置数据,这个过程是

  • 使用Redis incr解决并发问题的操作

    项目背景: 1.新增问题件工单,工单中有工单编码字段,工单编码字段的规则为 "WT"+yyyyMMdd+0000001. 2.每天的工单生成量是30W,所以会存在并发问题 解决思路: 1.首先乐观的认为redis不会宕机,对应的缓存不会被清除(除非人为操作,人为操作会有独立的补救办法) 2.将工单编码存到缓存中(redis),其值只存"WT"+yyyyMMdd后面的数字部分: 对应的key为:key标识+yyyyMMdd,即每天一个key 3.每次生成工单编码时,先

  • Python+redis通过限流保护高并发系统

    保护高并发系统的三大利器:缓存.降级和限流.那什么是限流呢?用我没读过太多书的话来讲,限流就是限制流量.我们都知道服务器的处理能力是有上限的,如果超过了上限继续放任请求进来的话,可能会发生不可控的后果.而通过限流,在请求数量超出阈值的时候就排队等待甚至拒绝服务,就可以使系统在扛不住过高并发的情况下做到有损服务而不是不服务. 举个例子,如各地都出现口罩紧缺的情况,广州政府为了缓解市民买不到口罩的状况,上线了预约服务,只有预约到的市民才能到指定的药店购买少量口罩.这就是生活中限流的情况,说这个也是希

  • 关于SpringBoot 使用 Redis 分布式锁解决并发问题

    目录 问题背景 解决方案 主要实现原理: 可靠性: SpringBoot 集成使用 Redis 分布式锁 使用示例 参考文档 问题背景 现在的应用程序架构中,很多服务都是多副本运行,从而保证服务的稳定性.一个服务实例挂了,其他服务依旧可以接收请求.但是服务的多副本运行随之也会引来一些分布式问题,比如某个接口的处理逻辑是这样的:接收到请求后,先查询 DB 看是否有相关的数据,如果没有则插入数据,如果有则更新数据.在这种场景下如果相同的 N 个请求并发发到后端服务实例,就会出现重复插入数据的情况:

  • php 使用redis锁限制并发访问类示例

    本文介绍了php 使用redis锁限制并发访问类,并详细的介绍了并发访问限制方法. 1.并发访问限制问题 对于一些需要限制同一个用户并发访问的场景,如果用户并发请求多次,而服务器处理没有加锁限制,用户则可以多次请求成功. 例如换领优惠券,如果用户同一时间并发提交换领码,在没有加锁限制的情况下,用户则可以使用同一个换领码同时兑换到多张优惠券. 伪代码如下: if A(可以换领)     B(执行换领)     C(更新为已换领) D(结束) 如果用户并发提交换领码,都能通过可以换领(A)的判断,因

  • PHP开发中解决并发问题的几种实现方法分析

    本文实例讲述了PHP开发中解决并发问题的几种实现方法.分享给大家供大家参考,具体如下: 对于商品抢购等并发场景下,可能会出现超卖的现象,这时就需要解决并发所带来的这些问题了 在PHP语言中并没有原生的提供并发的解决方案,因此就需要借助其他方式来实现并发控制. 方案一:使用文件锁排它锁 flock函数用于获取文件的锁,这个锁同时只能被一个线程获取到,其它没有获取到锁的线程要么阻塞,要么获取失败 在获取到锁的时候,先查询库存,如果库存大于0,则进行下订单操作,减库存,然后释放锁 方案二:使用Mysq

  • 基于centos7 安装python3.6.4出错的解决方法

    错误:zipimport.ZipImportError: can't decompress data; zlib not available 解决方法:从错误信息分析,就是缺少了zlib的解压缩类库,安装即可. 执行 yum -y install zlib* 安装完成之后,重新安装即可,所有的问题都已经正常解决了!!! 以上这篇基于centos7 安装python3.6.4出错的解决方法就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持我们. 您可能感兴趣的文章: 在cen

  • 安装python3的时候就是输入python3死活没有反应的解决方法

    我用brew安装python3 装完了发现 输入python3毫无反应,检查了 $PATH 也没有任何问题 这个时候回去看安装过程,发现安装时有一个错误: ERROR:The `brew link` step did not complete successfully The formula built, but is not symlinked into /usr/local Could not symlink lib/pkgconfig/python-3.6.pc (好像是这个,安装的时候忘

  • 使用Python控制摄像头拍照并发邮件

    o1 前言 为什么会有写这个程序的想法呢? 最初的想法是写一个可以用电脑前置摄像头拍照的程序,在舍友使用你电脑的时候,不经意间获取到一大堆奇葩舍友的表情包. 然后我又突发奇想,要不搞个开机启动吧,这样我就可以看到是谁开启了我的电脑啦. 然后,突(nao)发(dong)奇(da)想(kai)的我又想到万一我电脑不在身边怎么办?要不再加个邮件发送机制吧,开机拍到照片再邮件发送给我?哈哈 02 工具 •deepin 15.9 •好看好用的国产linux系统 •python 2.7或者3.6 •解释器,

  • Centos 升级到python3后pip 无法使用的解决方法

    一. 问题 [root@localhost local]# pip -bash: pip: command not found pip无法使用. 二. 系统环境 Centos 6.6 Python 3.5.2 三. 解决方法 设置软连接. 1.查找pip所在位置 [root@xxx local]# find / -name "pip" /Python-3.5.2/Tools/msi/pip /usr/bin/pip /usr/local/python3.5.2/bin/pip /usr

随机推荐