Python Redis pipeline操作(秒杀实现)

设想这样的一个场景,你要批量的执行一系列redis命令,例如执行100次get key,这时你要向redis请求100次+获取响应100次。如果能一次性将100个请求提交给redis server,执行完成之后批量的获取相应,只需要向redis请求1次,然后批量执行完命令,一次性结果,性能是不是会好很多呢?

答案是肯定的,节约的时间是客户端client和服务器redis server之间往返网络延迟的时间。这个时间可以用ping命令查看。

网络延迟高:批量执行,性能提升明显

网络延迟低(本机):批量执行,性能提升不明显

某些客户端(java和python)提供了一种叫做pipeline的编程模式用来解决批量提交请求的方式。

这里我们用python客户端来举例说明一下。

1、pipeline

网络延迟

client与server机器之间网络延迟如下,大约是30ms。

测试用例

分别执行其中的try_pipeline和without_pipeline统计处理时间。

# -*- coding:utf-8 -*-import redis
import time
from concurrent.futures import ProcessPoolExecutorr = redis.Redis(host='10.93.84.53', port=6379, password='bigdata123')def try_pipeline():start = time.time()with r.pipeline(transaction=False) as p:p.sadd('seta', 1).sadd('seta', 2).srem('seta', 2).lpush('lista', 1).lrange('lista', 0, -1)p.execute()print time.time() - startdef without_pipeline():start = time.time()r.sadd('seta', 1)r.sadd('seta', 2)r.srem('seta', 2)r.lpush('lista', 1)r.lrange('lista', 0, -1)print time.time() - startdef worker():while True:try_pipeline()with ProcessPoolExecutor(max_workers=12) as pool:for _ in range(10):pool.submit(worker)

结果分析

try_pipeline平均处理时间:0.04659

without_pipeline平均处理时间:0.16672

我们的批量里有5个操作,在处理时间维度上性能提升了4倍!

网络延迟大约是30ms,不使用批量的情况下,网络上的时间损耗就有0.15s(30ms*5)以上。而pipeline批量操作只进行一次网络往返,所以延迟只有0.03s。可以看到节省的时间基本都是网路延迟。

2、pipeline与transation

pipeline不仅仅用来批量的提交命令,还用来实现事务transation。

这里对redis事务的讨论不会太多,只是给出一个demo。详细的描述你可以参见这篇博客。redis事务

细心的你可能发现了,使用transaction与否不同之处在与创建pipeline实例的时候,transaction是否打开,默认是打开的。

# -*- coding:utf-8 -*-import redis
from redis import WatchError
from concurrent.futures import ProcessPoolExecutorr = redis.Redis(host='127.0.0.1', port=6379)# 减库存函数, 循环直到减库存完成
# 库存充足, 减库存成功, 返回True
# 库存不足, 减库存失败, 返回False
def decr_stock():# python中redis事务是通过pipeline的封装实现的with r.pipeline() as pipe:while True:try:# watch库存键, multi后如果该key被其他客户端改变, 事务操作会抛出WatchError异常pipe.watch('stock:count')count = int(pipe.get('stock:count'))if count > 0:  # 有库存# 事务开始pipe.multi()pipe.decr('stock:count')# 把命令推送过去# execute返回命令执行结果列表, 这里只有一个decr返回当前值print pipe.execute()[0]return Trueelse:return Falseexcept WatchError, ex:# 打印WatchError异常, 观察被watch锁住的情况print expipe.unwatch()def worker():while True:# 没有库存就退出if not decr_stock():break# 实验开始
# 设置库存为100
r.set("stock:count", 100)# 多进程模拟多个客户端提交
with ProcessPoolExecutor(max_workers=2) as pool:for _ in range(10):pool.submit(worker)

posted on 2018-11-28 11:01 _潜行者 阅读(...) 评论(...) 编辑 收藏

转载于:https://www.cnblogs.com/wangwei916797941/p/10030882.html

Python Redis pipeline操作(秒杀实现)相关推荐

  1. python redis pipeline使用方法_python使用pipeline批量读写redis的方法

    用了很久的redis了.随着业务的要求越来越高.对redis的读写速度要求也越来越高.正好最近有个需求(需要在秒级取值1000+的数据),如果对于传统的单词取值,循环取值,消耗实在是大,有小伙伴可能考 ...

  2. python redis pipeline使用方法_Redis中的管道Pipeline操作

    点击上方蓝色字体,选择"设为星标" 回复"资源"获取更多资源 点击右侧关注,大数据开发领域最强公众号! 点击右侧关注,暴走大数据! Redis默认每次执行请求都 ...

  3. python redis pipeline 堆积_Redis Pipeline python

    问题 简介: 以下代码来自 redis实战 一书中某个小节; 代码是python实现,其中如果pipeline()不加任何参数,或者是pipeline(True)的形式,那么客户端将使用MULTI E ...

  4. python redis list_Python操作redis实例小结【String、Hash、List、Set等】

    本文实例总结了Python操作redis方法.分享给大家供大家参考,具体如下: 这里介绍详细使用 1.String 操作 redis中的String在在内存中按照一个name对应一个value来存储 ...

  5. python redis list操作_使用Python操作redis

    在使用python操作redis之前,需要先安装redis库: pip install redis. 创建连接方式: StrictRedis:实现大部分官方命令. Redis:是StrictRedis ...

  6. python redis队列实现秒杀_redis实现简单延时队列

    继之前用rabbitMQ实现延时队列,Redis由于其自身的Zset数据结构,也同样可以实现延时的操作 Zset本质就是Set结构上加了个排序的功能,除了添加数据value之外,还提供另一属性scor ...

  7. python连接redis有中文_Python连接Redis并操作

    首先开启redis的外连 sch01ar@ubuntu:~$ sudo vim /etc/redis/redis.conf 把bind 127.0.0.1这行注释掉 然后重启redis sudo /e ...

  8. python操作redis实例_Java,php,Python连接并操作redis实例

    1.Java连接并操作redis 在Eclipse里新建一个java project,导入jedis-*.jar包. 示例代码,其他对应的操作类型见:http://my.oschina.net/u/2 ...

  9. Django中pipeline操作Redis数据库

    1.Redis的 C - S 架构: 基于客户端-服务端模型以及请求/响应协议的TCP服务. 客户端向服务端发送一个查询请求,并监听Socket返回. 通常是以阻塞模式,等待服务端响应. 服务端处理命 ...

最新文章

  1. AlphaCode到底强在哪儿?清华博士后十分钟视频详细解析
  2. 【整理】Nginx 战斗准备 —— 优化指南
  3. P1582 倒水(二进制)
  4. python dataframe 查看为空值_Python pandas.DataFrame 找出有空值的行
  5. Spring Boot2 整合 Shiro ,两种方式全总结!
  6. linux 运行eclipse,解决Linux下Eclipse启动错误
  7. 京东二面:MySQL 主从延迟、读写分离 7 种解决方案!
  8. kubernetes与web集群
  9. opencv中的安全指针和指针对齐
  10. Smarty模板引擎技术二
  11. In this year of Hors, he is an adopted son
  12. 用popen函数操作其它程序的输入和输出
  13. firefox访问页面 直接显示代码问题问题解决办法
  14. matlab图片测量尺寸_基于视觉的零件尺寸测量方法
  15. 520送女生什么礼物比较好?一口气推荐六款,快收藏
  16. Java消息队列--ActiveMQ 实战
  17. c语言存储器模式,单片机C51存储器类型及存储模式
  18. 变量、函数、类等编程时常用英文命名和缩写
  19. python绘制条形图的方法_python绘制条形图方法代码详解
  20. Centos7 Failed to start xxx.service: Unit not found

热门文章

  1. 【汇编语言(第3版)王爽】试验7 寻址方式在接过话数据访问中的应用(代码+注释)
  2. 每天一道LeetCode-----判断数组中是否存在两个位置上面的值相等并且下标的差小于某个值
  3. 数据结构-----图的拓扑排序和关键路径算法
  4. 四轴PID控制算法详解(单环PID、串级PID)
  5. java 获取mp4 缩略图_java获取视频缩略图
  6. 问题:出现在哪个地方?关于map的搜索问题
  7. PCA主成分分析_特征创建(数据挖掘入门与实践-实验8)
  8. LintCode刷起来(一)
  9. Eclipse中如何恢复已删除文件
  10. JavaScript学习备忘