day6_redis模块和pipeline
读1m的数据从磁盘和从内存上读,相差100倍,redis是一个数据库,他的数据全都是存放在内存里面的,redis每秒能支持30w次的读写
首先启动本地的redis,客户端启动命令是,首先解压Redis-x64-3.2.100.zip,进入Redis-x64-3.2.100文件夹下执行redis-server.exe redis.windows-service.conf命令,如果报
redis.exceptions.AuthenticationError: Client sent AUTH, but no password is set,要重新执行redis-server.exe,服务起来后,再打开一个cmd窗口,执行redis-cli.exe,然后执行config set requirepass 123456就可以了,
D:\20171104\Redis-x64-3.2.100>redis-server.exe redis.windows-service.conf,然后连接redis,在pycharm里输入下面的代码:
import redis
r = redis.Redis(host='211.149.218.16', port=6378, password='123456', db=2) # 连接redis数据库的命令,db不写默认是db0
r2 = redis.Redis(host='127.0.0.1', port=6379) # 连本地redis直接就用host和port,db不写默认是db0
下面的方法是处理string类型的,数据库里显示string:ssj,value是你真好
r.set('ssj', 'hello') # set数据
print(r.get('ssj')) # get数据打印出bytes类型,如b'best'
print(r.get('ssj').decode()) # bytes类型转成字符串,如果不想每次都decode(),在连接数据库的时候加上decode_responses=True就可以了
print(r.keys()) # 会把所有的key打印出来,返回一个列表
print(r.keys('s*')) # 会把以s开头的key打印出来,返回一个列表
for k in r.keys(): # 循环所有的key和value,bytes类型的
print('{k}:{v}'.format(k=k, v=r.get(k)))
print('{k}:{v}'.format(k=k, v=r.set(k, '哈哈'))) # value都写成一样,返回的值是True
r.setex('ssj', 20,'abc') # 指定key的超时时间,20秒后删除key,字符串有失效时间,hash没有,
# redis连接工具里显示TTL:-1代表永不失效,除非重启redis,如果value没有显示出来,选择View as Plain Text,默认就是Plain Text
下面的方法是处理hash类型的,数据库里显示hash,hash会显示输入的name,key和value依次一行一行在下面排队
r.hset('ssj', 'age', '22') # 设置值
r.hset('ssj', 'age1', '22') # 设置值
print(r.hget('ssj', 'age')) # 获取值
print(r.hgetall('ssj')) # 获取hash类型这个name里面所有的数据,返回一个字典
r.delete('ssj') # 删除key
r.flushall() # 清空所有数据库的所有内容
r.flushdb() # 清空当前数据库里的数据
print(r.exists('k')) # 判断key是否存在,打印1代表存在,0代表不存在
print(r.keys()) # 获取当前数据库所有的key,返回一个list
print(r.type('k')) # 获取key的类型,有可能是string,也可能是hash类型
把bytes类型的字典转成字符串类型的字典的代码如下:
res = r.hgetall('sss')
lis = {}
for k in res:
new_k = k.decode()
v = res[k]
new_v = v.decode()
lis[new_k] = new_v
print(lis)
redis数据库迁移db2到db3代码如下:
r1 = redis.Redis(host='211.149.218.16', port=6378, password='123456', db=2) # 获取数据
r2 = redis.Redis(host='211.149.218.16', port=6378, password='123456', db=3) # 写数据
keys = r1.keys() # r1数据库上所有的key
for k in keys:
if r1.type(k) == b'hash':
# 判断是否是hash类型,因为redis里面返回的数据都是bytes类型,所以在hash前面加上b
hash_data = r1.hgetall(k) # 获取hash类型的数据,是一个字典
for k2, v in hash_data.items(): # 循环字典的key和value
r2.set(k, k2, v) # set哈希类型的值
else:
v = r1.get(k) # 从r1里面取值
r2.set(k, v) # 把从r1里面取的值set到r2里
import redis
r1 = redis.Redis(host='211.149.218.16', password='123456', db=2, decode_responses=True)
r2 = redis.Redis(host='211.149.218.16', password='123456', db=3, decode_responses=True)
for k in r1.keys():
if r1.type(k) == b'string':
value = r1.get(k)
r2.set(k, value)
if r1.type(k) == b'hash':
value = r1.hgetall(k)
r2.hmset(k, value) # hmset()传入一个k和字典,value就是一个字典
# for key, v in value.items():
# r2.hset(k, key, v)
import redis
import time
r = redis.Redis(host='188.24.103.140', password='123456', db=2, decode_responses=True)
pipeline = r.pipeline() # 建立一个管道
lis = range(50)
start_time = time.time()
for i in lis:
# r.set('key%i' % i, str(i))
pipeline.set('key%i' % i, str(i))
pipeline.execute() # 执行管道,一次性写到redis里,用for循环也可以实现,但是set一次就要操作一次redis,性能不好
print(time.time() - start_time) # for循环和pipeline的时间差太多,pipeline只执行一次redis操作