使用事务的其中一个好处就是底层的客户端会通过使用流水线来提高事务执行时的性能。使用非事务型流水线(non-transactional pipeline)同样可以获得相似的性能提升,并且可以让用户同时执行多个不同的命令。

MULTI和EXEC也会消耗资源,并且可能会导致其他重要的命令被延迟执行。但也可以在不使用MULTI和EXEC的情况下,获得流水线带来的所有好处。

pipe = conn.pipeline()

在执行pipeline()时传入True作为参数,或者不传入任何参数,那么客户端将使用MULTI和EXEC包裹起用户要执行的所有命令。如果传入False为参数,那么客户端同样会像执行事务那样收集用户要执行的所有命令,只是不再使用MULTI和EXEC包裹这些命令。如果用户需要向Redis发送多个命令,并且对于这些命令来说,一个命令的执行结果并不会影响另一个命令的输入,而且这些命令也不需要以事务的方式来执行的话,那么我们可以通过向pipeline()方法传入False来进一步提升Redis的整体性能。

下面是没有使用非事务型流水线代码:

def update_token(conn, token, user, item=None):
    timestamp = time.time()
    conn.hset('login:', token, user)
    conn.zadd('recent:', token, timestamp)
    
    if item:
        conn.zadd('viewed:' + token, item, timestamp)
        conn.zremrangebyrank('viewed:' + token, 0, -26)
        conn.zincrby('viewed:', item, -1)
        

使用非实物型流水线后:

def update_token_pipeline(conn, token, uesr, item=None)
    timestamp = time.time()
    pipe = conn.pipeline(False)
    pipe.hset('login:', token, user)
    pipe.zadd('recent:', token, timestamp)
    
    if itme:
        pipe.zadd('viewed:' + token, item, timestamp)
        pipe.zremrangebyrank('viewed:' + token, 0, -26)
        pipe.zincrby('viewed:', item, -1)
    pipe.execute()

根据测试,高延迟网络使用流水线时的速度要比不使用流水线时的速度快5倍,低延迟网络使用流水线也可以带来接近4倍的速度提升,本地网络的测试结果实际上已经达到Python在单核环境使用redis协议发送和接收短命令序列的性能极限。


parvin
424 声望26 粉丝

« 上一篇
Redis事务详解
下一篇 »
Redis分布式锁