Python连接Redis
import redis
方式一:
con = redis.Redis(host=host, port=port, db=db, password=password)
方式二:
# 创建链接池
pool = redis.Connection(host=host, port=port, db=db, password=password)
con = redis.Redis(connection_pool=pool)
方式三:
# 通过url连接
url = "redis://password@ip:port/db"
con = red.form_url(url)
# 或
pool = redis.ConnectionPool.from_url(url)
管道(Pipelining)
概念
Redis是一种基于客户端-服务端模型以及请求/响应协议的TCP服务,客户端向服务端发送一个查询请求,并监听Socket返回,通常是以阻塞模式,等待服务端响应,服务端处理命令,并将结果返回给客户端。这个时间被称之为 RTT (Round Trip Time - 往返时间)。当客户端需要在一个批处理中执行多次请求时,RTT就会很大。
管道(Pipeline)就是为了改善这个情况的,利用管道,客户端可以一次性发送多个请求而不用等待服务器的响应,待所有命令都发送完后再一次性读取服务的响应,这样可以极大的降低RTT时间从而提升性能。需要注意到是用pipeline方式打包命令发送,redis必须在处理完所有命令前先缓存起所有命令的处理结果。打包的命令越多,缓存消耗内存也越多。所以并不是打包的命令越多越好。
pipeline和“事务”是两个完全不同的概念,pipeline只是表达“交互”中操作的传递的方向性,pipeline也可以在事务中运行,也可以不在。无论如何,pipeline中发送的每个command都会被server立即执行,如果执行失败,将会在此后的响应中得到信息;也就是pipeline并不是表达“所有command都一起成功”的语义;但是如果pipeline的操作被封装在事务中,那么将有事务来确保操作的成功与失败。
对比测试
实例代码:
import redis
import time
# decode_response=True 这样写存的格式是字符串格式
def testNoPipeline():
r = redis.Redis(host='127.0.0.1', port=6379, db=0, password='password')
start_time = time.time() * 1000
for i in range(10000):
key = 'keynopipe' + '_' + str(i)
value = str(i)
r.set(key, value)
end_time = time.time() * 1000
print("no pipeline use total time:" + str(end_time-start_time))
def testPipeline():
r = redis.Redis(host='127.0.0.1', port=6379, db=0, password='password')
start_time = time.time() * 1000
pipe = r.pipeline(transaction=True)
for i in range(10000):
key = 'keypipe' + '_' + str(i)
value = str(i)
pipe.set(key, value)
pipe.execute()
end_time = time.time() * 1000
print("with pipeline use total time:" + str(end_time - start_time))
if __name__ == '__main__':
testNoPipeline()
testPipeline()
输出结果
no pipeline use total time:505.63525390625
with pipeline use total time:139.79345703125
事务、管道和脚本的区别
- 事务和脚本从原子性上来说都能满足原子性的要求,其区别在于脚本可借助Lua语言可在服务器端存储的便利性定制和简化操作,但脚本无法处理长耗时的操作。redis确保这条script脚本执行期间,其它任何脚本或者命令都无法执行。正是由于这种原子性,script才可以替代MULTI/EXEC作为事务使用。当然,官方文档也说了,正是由于script执行的原子性,所以我们不要在script中执行过长开销的程序,否则会验证影响其它请求的执行。
- 管道是无状态操作集合,使用管道可能在效率上比使用script要好,但是有的情况下只能使用script。因为在执行后面的命令时,无法得到前面命令的结果,就像事务一样,所以如果需要在后面命令中使用前面命令的value等结果,则只能使用script或者事务+watch。