Redis
python操作Redis,还包括Memcache,RabbitMQ
Redis内容还是比较多的,详细的可以去上面几篇博客
下面我主要挑一些常用的进行总结
Redis和Memcache差不多,也是内存级别的key-value存储系统,不过相比Memcache,Redis支持value类型更多,有5种:
- string(字符串)
- list(链表)
- set(集合)
- zset(有序集合)
- hash(哈希类型,你就理解成我们常用的字典)
而且Redis还支持原子性操作和持久化
安装
- pip install redis
连接
import redis
r = redis.Redis(host='10.211.55.4', port=6379)
r.set('foo', 'Bar')
print r.get('foo')
#连接池连接方式,可减少连接花销, 推荐
import redis
pool = redis.ConnectionPool(host='10.211.55.4', port=6379)
r = redis.Redis(connection_pool=pool)
r.set('foo', 'Bar')
print r.get('foo')
常规操作
- keys(pattern) 获取所有的键,默认所有
conn.keys()
- scan_iter(pattern) 分批次取出键,减小redis压力
conn.scan_iter("luffy_shopping_car_1*")
conn.scan_iter()
- flushall() 清空redis缓存
conn.flushall()
- delete(name) 删除指定key-val,批量删除可传入*list
conn.delete('k1')
- exists(name)
检测redis的name是否存在 - expire(name ,time)
为某个redis的某个name设置超时时间
5大类型
String字符串
- set(name, value, ex=None, px=None, nx=False, xx=False)
在Redis中设置值,默认,不存在则创建,存在则修改
参数:
ex,过期时间(秒) 效果等同setex(name, value, time)
px,过期时间(毫秒)
nx,如果设置为True,则只有name不存在时,当前set操作才执行,效果等同setnx(name, value)
xx,如果设置为True,则只有name存在时,岗前set操作才执行
- mset(*args, **kwargs) 批量设置
conn.mset({'k100':'v100', 'k200':'v200'})
- get(name) 获取值
- mget(keys, *args) 批量获取
print(conn.mget('k100', 'k200'))
print(conn.mget(['k100','k200']))
- getset(name, value)
设置新值并获取原来的值
- getrange(key, start, end) 切片取value
- setrange(name, offset, value) 指定位置开始进行替换值
- strlen(name) 获取value字节长度,一个汉字是三个字节
- append(key, value) 对value末尾进行拼接值
conn.append('k100', '00000000000000')
- incr(self, name, amount=1)
自增 name对应的值,当name不存在时,则创建name=amount,否则,则自增 - incrbyfloat(self, name, amount=1.0)
- decr(self, name, amount=1)
conn.set('number', 0)
conn.incr('number')
conn.incr('number')
conn.incr('number') #3
Hash字典
- hset(name, key, value)
name对应的hash中设置一个键值对(不存在,则创建;否则,修改) hsetnx(name, key, value) name下不存在此key,才添加- hmset(name, mapping) 批量添加
conn.hmset('xx', {'k1':'k1', 'k2':'k2'})
- hget(name,key)
在name对应的hash中获取根据key获取value - hmget(name, keys, *args) 批量获取
print(conn.hmget('xx', ['k1', 'k2']))
print(conn.hmget('xx', 'k1', 'k2'))
- hgetall(name)
获取name对应的hash所有键值 hlen(name)获取name对应的hash中键值对的个数- hkeys(name)
获取name对应的hash中所有的key的值 - hvals(name)
获取name对应的hash中所有的value的值 - hexists(name, key)
检查name对应的hash是否存在当前传入的key - hdel(name,*keys)
将name对应的hash中指定key的键值对删除
- hincrby(name, key, amount=1)
自增name对应的hash中的指定key的值,不存在则创建key=amount - hincrbyfloat(name, key, amount=1.0)
- hscan(name, cursor=0, match=None, count=None) 通过游标分批获取数据
- hscan_iter(name, match=None, count=None)
利用yield封装hscan创建生成器,实现分批去redis中获取数据
# 第一次:cursor1, data1 = r.hscan('xx', cursor=0, match=None, count=None)
# 第二次:cursor2, data1 = r.hscan('xx', cursor=cursor1, match=None, count=None)
# for item in r.hscan_iter('xx'):
# print item
List链表
- lpush(name,values) 左添加 [添加]
- lpushx(name,value) name存在才左添加 [添加]
- rpush(name,values) 右添加 [添加]
- rpushx(name,value) name存在才右添加 [添加]
conn.lpush('xx', 11, 22, 33)
conn.lpushx('oo', 11)
conn.lpushx('xx', 11)
- linsert(name, where, refvalue, value)) [添加] 指定元素前或后插值,
where,BEFORE或AFTER,refvalue,标杆值,即:在它前后插入数据,value,要插入的数据 - 如果列表中有多个同样的标杆值,默认是第一个
conn.linsert('xx', 'BEFORE', '33', '8888')
- llen(name)
name对应的list元素的个数 - lset(name, index, value) 指定索引位置改值 [修改]
- lpop(name) 左移除并获取 [获取]
rpop(name) 右移除并获取 [获取]- lindex(name, index) 指定索引获取
[获取] - lrange(name, start, end)
在name对应的列表分片获取数据[获取]
- r.lrem(name, num, value)
在name对应的list中删除指定值[删除]
# value,要删除的值
# num, num=0,删除列表中所有的指定值;
# num=2,从前到后,删除2个;
# num=-2,从后向前,删除2个
- ltrim(name, start, end)
name对应的列表中移除没有在start-end索引之间的值[删除] - rpoplpush(src, dst)
# 从一个列表取出最右边的元素,同时将其添加至另一个列表的最左边
# 参数:
# src,要取数据的列表的name
# dst,要添加数据的列表的name
- blpop(keys, timeout) 左取,没有值时阻塞
brpop(keys, timeout) 右取,没有值时阻塞
import redis
"""
redis = {
k1:[1,2,3,43,45]
}
"""
conn = redis.Redis(host='47.94.172.250',port=6379,password='Luffy!4321')
# 左插入
# conn.lpush('k1',11)
# 右插入
# conn.rpush('k1',33)
# 左获取
# val = conn.lpop('k1')
# val = conn.blpop('k1',timeout=10) # hang住
# 右获取
# val = conn.rpop('k1')
# val = conn.brpop('k1',timeout=10) # hang住
# conn.lpush('k1',*[11,22,33,44,55,66,77,88,99,66,666,2234,345234,234])
由于redis链表类型没有提供scan_iter这么一个方法,而且也要防止列表过大,撑爆内存,我们需要自定义列表的scan_iter方法
def list_iter(key,count=100):
index = 0
while True:
data_list = conn.lrange('k1', index, index+count-1)
if not data_list:
return
index += count
for item in data_list:
yield item
print(conn.lrange('k1',0,101))
for item in list_iter('k1',count=3):
print(item)
set集合
另外两个数据类型,集合和有序集合,这里不多赘述,可文头文章
这两种数据类型主要用于交集,差集,并集运算
- 用于去重
- 有序集合用于排序
管道
默认执行一次命令是redis连接会创建(连接池申请连接)和断开(归还连接池),如果想一次执行多条命令,就可以用pipline,而且是原子性操作
import redis
"""
redis = {
k1:[1,2,3,43,45]
}
"""
conn = redis.Redis(host='47.94.172.250',port=6379,password='Luffy!4321')
pipe = conn.pipeline(transaction=True)
pipe.multi()
pipe.set('k2','123')
pipe.hset('k3','n1',666)
pipe.lpush('k4','laonanhai')
pipe.execute()

浙公网安备 33010602011771号