Python中使用Redis的批处理工具pipeline(这种方法从底层思考效率还是低于“订阅发布机制”)
一、pipeline出現(xiàn)的原因
1.Redis執(zhí)行命令的過程
redis客戶端執(zhí)行一條命令的過程:
發(fā)送命令-〉命令排隊(duì)-〉命令執(zhí)行-〉返回結(jié)果使用python給redis發(fā)送命令時(shí)的過程:
2.效率提升
當(dāng)redis需要執(zhí)行的命令較多時(shí),這樣的一來一回的網(wǎng)絡(luò)傳輸所消耗的時(shí)間被稱為RTT(Round Trip Time),顯而易見,如果可以將這些命令作為一個(gè)請(qǐng)求一次性發(fā)送給服務(wù)端,并一次性將結(jié)果返回客戶端,會(huì)節(jié)約很多網(wǎng)絡(luò)傳輸?shù)南?#xff0c;可以大大提升響應(yīng)時(shí)間。因此我們python中通過pipeline來進(jìn)行效率提升。
二、pepeline的性能
1、未使用pipeline執(zhí)行N條命令
2、使用了pipeline執(zhí)行N條命令
兩種方式中:使用Pipeline執(zhí)行速度比逐條執(zhí)行要快,特別是客戶端與服務(wù)端的網(wǎng)絡(luò)延遲越大,性能體能越明顯。
三、原生批命令與Pipeline對(duì)比
原始批命令:(mset, mget)
- 原生批命令是原子性,pipeline是非原子性(原子性概念:一個(gè)事務(wù)是一個(gè)不可分割的最小工作單位,要么都成功要么都失敗)
- 原生批命令一命令多個(gè)key, 但pipeline支持多命令(存在事務(wù)),非原子性
- 原生批命令是服務(wù)端實(shí)現(xiàn),而pipeline需要服務(wù)端與客戶端共同完成
四、pipeline的簡單使用
1.簡單的使用
# coding:utf-8 import redisr = redis.StrictRedis.from_url('redis://127.0.0.1/0') # 創(chuàng)建管道對(duì)象 pipe = r.pipeline() pipe.set('name', '張三') pipe.set('age', 15) pipe.set('gender', '男') # 執(zhí)行 pipe.execute()2.pipeline支持命令寫在一起
# coding:utf-8 import redisr = redis.StrictRedis.from_url('redis://127.0.0.1/0') pipe = r.pipeline() # pipeline支持命令寫在一起 pipe.set('hello', 'redis').sadd('faz', 'baz').incr('num').execute()3.pipeline配合上下文管理器
# coding:utf-8 import redisr = redis.StrictRedis.from_url('redis://127.0.0.1/0') # 創(chuàng)建管道對(duì)象,一般配合上下文管理器使用 with r.pipeline() as pipe:pipe.set('name', '張三')pipe.set('age1', '12')pipe.set('age2', '121')pipe.set('age3', '1212')pipe.set('age4', '12121')try:# 執(zhí)行pipe.execute()except Exception as e:print e4.批量接收pipeline的值
# coding:utf-8 import redisr = redis.StrictRedis.from_url('redis://127.0.0.1/0')# 往num_list中添加100個(gè)值 with r.pipeline() as pipe:for i in range(1, 101):pipe.lpush('num_list'.format(i), i)try:pipe.execute()except Exception as e:print e# 從num_list中取出所有值 num_len=r.llen('num_list') with r.pipeline() as pipe:for i in range(num_len):pipe.rpop('num_list')try:result = pipe.execute()print resultexcept Exception as e:print e批量接收pipeline的值會(huì)以列表形式返回
5.pipeline配合事務(wù)的操作
默認(rèn)pipeline中支持事務(wù),若想關(guān)閉事務(wù),則創(chuàng)建pipeline的時(shí)候:
pipe = r.pipeline(transaction=False)錯(cuò)誤總結(jié)
①開啟事務(wù)時(shí)候命令出錯(cuò)
把set寫成settt造成語法錯(cuò)誤
# coding:utf-8 import redisr = redis.StrictRedis.from_url('redis://127.0.0.1/0') # 創(chuàng)建管道對(duì)象,一般配合上下文管理器使用 with r.pipeline() as pipe:pipe.set('name', '張三')pipe.settt('age',18)try:# 執(zhí)行pipe.execute()except Exception as e:print e語法錯(cuò)誤,整個(gè)事務(wù)無法執(zhí)行,控制臺(tái)報(bào)錯(cuò),數(shù)據(jù)庫也不會(huì)執(zhí)行。
②開啟事務(wù)時(shí)候運(yùn)行出錯(cuò)
錯(cuò)將str求長度寫成列表求長度的命令,在redis執(zhí)行過程中報(bào)錯(cuò)
# coding:utf-8 import redisr = redis.StrictRedis.from_url('redis://127.0.0.1/0') # 創(chuàng)建管道對(duì)象,一般配合上下文管理器使用 with r.pipeline() as pipe:pipe.set('name', '張三')pipe.llen('name')pipe.set('name2', '李四')try:# 執(zhí)行pipe.execute()except Exception as e:print e在執(zhí)行過程中發(fā)現(xiàn)命令報(bào)錯(cuò),那么命令錯(cuò)誤的語句無法執(zhí)行,不會(huì)影響其他命令
未改進(jìn)的小例子
import redis import time import jsonhost = "127.0.0.1" port = 6379 password = "ics12345" redis_list_name = "dga-metadata"redis_conn = redis.Redis(host, port, 0, password, decode_responses=True) pipe = redis_conn.pipeline() count = 0 www = 10000 while www:#data = redis_conn.rpop(redis_list_name)pipe.rpop(redis_list_name)#print(data)www -= 1count += 1if count % 1000 == 0:print(count) data = pipe.execute() print("end", len(data)) aaa = [] for item in data:if not item is None:json.loads(item)aaa.append(item) print("end2", len(aaa))?
新人創(chuàng)作打卡挑戰(zhàn)賽發(fā)博客就能抽獎(jiǎng)!定制產(chǎn)品紅包拿不停!總結(jié)
以上是生活随笔為你收集整理的Python中使用Redis的批处理工具pipeline(这种方法从底层思考效率还是低于“订阅发布机制”)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Python基础38(进程基础)
- 下一篇: centos出现磁盘坏道,怎么检索和修复