python之redis
Redis安装
redis 介绍: http://www.redis.net.cn/order/
windows 安装:http://www.cnblogs.com/ningskyer/articles/5730611.html
1 redis-server.exe redis.windows.conf 2 3 安装服务: 4 5 redis-server --service-install redis.windows.conf 6 7 8 停止服务: 9 10 redis-server --service-stop 11 12 13 14 切换到redis目录下运行 15 16 redis-cli.exe -h 127.0.0.1 -p 6379
ubuntu 安装:
1 $sudo apt-get update 2 $sudo apt-get install redis-server 3 启动 Redis 4 5 $redis-server 6 查看 redis 是否还在运行 7 8 $redis-cli 9 这将打开一个 Redis 提示符,如下图所示: 10 redis 127.0.0.1:6379> 11 在上面的提示信息中:127.0.0.1 是本机的IP地址,6379是 Redis 服务器运行的端口。现在输入 PING 命令,如下图所示: 12 redis 127.0.0.1:6379> ping 13 PONG
Redis 连接方式
- redis-py提供两个类Redis和StrictRedis用于实现Redis的命令,StrictRedis用于实现大部分官方的命令,并使用官方的语法和命令,Redis是StrictRedis的子类,用于向后兼容旧版本的redis-py。
1 import redis 2 3 4 r = redis.Redis(host='localhost',port=6379) 5 r.set('name','gareth') 6 print(r.get('name'))
2. redis-py使用connection pool来管理对一个redis server的所有连接,避免每次建立、释放连接的开销。默认,每个Redis实例都会维护一个自己的连接池。可以直接建立一个连接池,然后作为参数Redis,这样就可以实现多个Redis实例共享一个连接池。
1 import redis 2 3 pool = redis.ConnectionPool(host='localhost', port=6379,db=5) 4 r = redis.Redis(connection_pool=pool) 5 r.set('age', '22') 6 print(r.get('age'))
Redis string操作
redis中的String在在内存中按照一个key对应一个value来存储。通过setbit和bitcount方法结合可以统计用户登入量以及用户状态,用户ID对应二进制位,value(0,1)对应在线或不在线。
方法:
命令 | 描述 |
---|---|
Redis SET 命令 | 设置指定 key 的值 |
Redis Get 命令 | 获取指定 key 的值。 |
Redis Getrange 命令 | 返回 key 中字符串值的子字符 |
Redis Getset 命令 | 将给定 key 的值设为 value ,并返回 key 的旧值(old value)。 |
Redis Getbit 命令 | 对 key 所储存的字符串值,获取指定偏移量上的位(bit)。 |
Redis Mget 命令 | 获取所有(一个或多个)给定 key 的值。 |
Redis Setbit 命令 | 对 key 所储存的字符串值,设置或清除指定偏移量上的位(bit)。 |
Redis Setex 命令 | 将值 value 关联到 key ,并将 key 的过期时间设为 seconds (以秒为单位)。 |
Redis Setnx 命令 | 只有在 key 不存在时设置 key 的值。 |
Redis Setrange 命令 | 用 value 参数覆写给定 key 所储存的字符串值,从偏移量 offset 开始。 |
Redis Strlen 命令 | 返回 key 所储存的字符串值的长度。 |
Redis Mset 命令 | 同时设置一个或多个 key-value 对。 |
Redis Msetnx 命令 | 同时设置一个或多个 key-value 对,当且仅当所有给定 key 都不存在。 |
Redis Psetex 命令 | 这个命令和 SETEX 命令相似,但它以毫秒为单位设置 key 的生存时间,而不是像 SETEX 命令那样,以秒为单位。 |
Redis Incr 命令 | 将 key 中储存的数字值增一。 |
Redis Incrby 命令 | 将 key 所储存的值加上给定的增量值(increment) 。 |
Redis Incrbyfloat 命令 | 将 key 所储存的值加上给定的浮点增量值(increment) 。 |
Redis Decr 命令 | 将 key 中储存的数字值减一。 |
Redis Decrby 命令 | key 所储存的值减去给定的减量值(decrement) 。 |
Redis Append 命令 | 如果 key 已经存在并且是一个字符串, APPEND 命令将 value 追加到 key 原来的值的末尾。 |
set(key, value, ex=None, px=None, nx=False, xx=False) : 在Redis中设置值,默认,不存在则创建,存在则修改
参数:
-
- ex,过期时间(秒)
- px,过期时间(毫秒)
- nx,如果设置为True,则只有key不存在时,当前set操作才执行
- xx,如果设置为True,则只有name存在时,当前set操作才执行
setnx(key,value) 则只有key不存在时,当前set操作才执行
setex(key, second, value) 设置值,并且设置过期时间
psetex(key, millisecond, value) 设置值,并且设置过期时间,毫秒
mset(*args,**kwargs) 批量设置值,如 r.mset({'k1':'v1','k2':'v2'}) 或 r.mset(k1=
'v1'
, k2=
'v2'
)
get(key) 获取值value
mget(keys,*args) 批量获取
1 print(r.mget('k1','k2')) 2 #[b'v1', b'v2'] 3 print(r.mget(['k1','k2'])) 4 #[b'v1', b'v2']
getset(name,value) 设置新值并且获取原来的值
1 print(r.get('k1')) 2 print(r.getset('k1','v_new')) 3 print(r.get('k1')) 4 # b'v1_old' 5 # b'v1_old' 6 # b'v_new'
getrange(key,start, end) 获取存储在指定 key 中字符串的子字符串。字符串的截取范围由 start 和 end 两个偏移量决定(包括 start 和 end 在内)
1 r.set('k3','testrange') 2 print(r.getrange('k3',0,5)) 3 # b'testra' 4 print(r.getrange('k3',0,-1)) 5 # b'testrange'
setrange(key, ofset, value) 修改字符串内容,从指定字符串索引开始向后替换,如果新值太长时,则向后添加
1 r.set('k3','testrange') 2 r.setrange('k3',1,'N') 3 print(r.get('k3')) # b'tNstrange' 4 r.setrange('k3',5,'new_string') 5 print(r.get('k3')) # b'tNstrnew_string'
setbit(key, offset, value) 对key对应值的二进制位进行操作,offset: 位的索引(将值变换成二进制后再进行索引); value: 值只能是 1 或 0
1 str = 'aaa' 2 r.set('k5',str) 3 for ch in str: 4 print(ord(ch),bin((ord(ch)))) # 97 0b1100001 5 r.setbit('k5',6,1) 6 r.setbit('k5',13,1) 7 r.setbit('k5',22,1) 8 #01100001 01100001 01100001 9 print(r.get('k5')) 10 #b'cec' 11 # 一个字节的范围为0-7
getbit(key, offset) # 获取key对应的值的二进制表示中的某位的值 (0或1)
1 r.set('k5','a') 2 print(bin(ord('a')),r.getbit('k5',7)) 3 # 0b1100001 1
bitcount(key, start=None, end=None) 获取key对应的值的二进制表示中 1 的个数,start和end分别表示字节的起始和结束,包括end
1 r.set('k5','aaaa') 2 print(bin(ord('a')),r.bitcount('k5'),r.bitcount('k5',0,2)) 3 # 0b1100001 12 9
strlen(key) 返回key对应值的字节长度(一个汉字3个字节)
1 r.set('k5','aaaa') 2 print(r.strlen('k5')) 3 # 4
incr(self, key, amount=1) 自增 key对应的值,当key不存在时,则创建key=amount,否则,则自增。
incrbyfloat(self, key, amount=1.0) 自增 key对应的值,当key不存在时,则创建key=amount,否则,则自增。amount为浮点数
1 r.set('k5',1) 2 r.incr('k5',2) 3 r.incr('k6',3) 4 print('k5:',r.get('k5')) 5 print('k6:',r.get('k6')) 6 # k5: b'3' 7 # k6: b'3'
decr(self, key, amount=1) 自减key对应的值,当key不存在时,则创建key=amount,否则,则自减。 amount为整数
1 r.set('k5',3) 2 r.decr('k5',3) 3 r.decr('k10',8) 4 print('k5:',r.get('k5')) 5 print('k10:',r.get('k9')) 6 # k5: b'0' 7 # k10: b'8'
append(key, value) 在key对应的值后面追加内容
1 r.set('k5','gareth') 2 r.append('k5','test') 3 print(r.get('k5')) 4 # b'garethtest'
Redis hash操作
命令 | 描述 |
---|---|
Redis Hdel 命令 | 删除一个或多个哈希表字段 |
Redis Hexists 命令 | 查看哈希表 key 中,指定的字段是否存在。 |
Redis Hget 命令 | 获取存储在哈希表中指定字段的值/td> |
Redis Hgetall 命令 | 获取在哈希表中指定 key 的所有字段和值 |
Redis Hincrby 命令 | 为哈希表 key 中的指定字段的整数值加上增量 increment 。 |
Redis Hincrbyfloat 命令 | 为哈希表 key 中的指定字段的浮点数值加上增量 increment 。 |
Redis Hkeys 命令 | 获取所有哈希表中的字段 |
Redis Hlen 命令 | 获取哈希表中字段的数量 |
Redis Hmget 命令 | 获取所有给定字段的值 |
Redis Hmset 命令 | 同时将多个 field-value (域-值)对设置到哈希表 key 中。 |
Redis Hset 命令 | 将哈希表 key 中的字段 field 的值设为 value 。 |
Redis Hsetnx 命令 | 只有在字段 field 不存在时,设置哈希表字段的值。 |
Redis Hvals 命令 | 获取哈希表中所有值 |
redis中的Hash 在内存中类似于一个name对应一个dic来存储。
hset(name, key, value)
1 #name对应的hash中设置一个键值对(不存在,则创建,否则,修改) 2 r.hset("dic_name","a1","aa")
hmset(name, mapping) 在name对应的hash中批量设置键值对
1 dic={"a1":"aa","b1":"bb"} 2 r.hmset("dic_name",dic) 3 print(r.hget("dic_name","b1"))#输出:bb
hget(name,key)
1 r.hset("dic_name","a1","aa") 2 #在name对应的hash中根据key获取value 3 print(r.hget("dic_name","a1"))#输出:aa
hmget(name, keys, *args) 在name对应的hash中获取多个key的值
1 r.hmget('xx', ['k1', 'k2']) 2 r.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) 自增name对应的hash中的指定key的值,不存在则创建key=amount
hscan(name, cursor=0, match=None, count=None)
hscan_iter(name, match=None, count=None)
Redis list操作
命令 | 描述 |
---|---|
Redis Blpop 命令 | 移出并获取列表的第一个元素, 如果列表没有元素会阻塞列表直到等待超时或发现可弹出元素为止。 |
Redis Brpop 命令 | 移出并获取列表的最后一个元素, 如果列表没有元素会阻塞列表直到等待超时或发现可弹出元素为止。 |
Redis Brpoplpush 命令 | 从列表中弹出一个值,将弹出的元素插入到另外一个列表中并返回它; 如果列表没有元素会阻塞列表直到等待超时或发现可弹出元素为止。 |
Redis Lindex 命令 | 通过索引获取列表中的元素 |
Redis Linsert 命令 | 在列表的元素前或者后插入元素 |
Redis Llen 命令 | 获取列表长度 |
Redis Lpop 命令 | 移出并获取列表的第一个元素 |
Redis Lpush 命令 | 将一个或多个值插入到列表头部 |
Redis Lpushx 命令 | 将一个或多个值插入到已存在的列表头部 |
Redis Lrange 命令 | 获取列表指定范围内的元素 |
Redis Lrem 命令 | 移除列表元素 |
Redis Lset 命令 | 通过索引设置列表元素的值 |
Redis Ltrim 命令 | 对一个列表进行修剪(trim),就是说,让列表只保留指定区间内的元素,不在指定区间之内的元素都将被删除。 |
Redis Rpop 命令 | 移除并获取列表最后一个元素 |
Redis Rpoplpush 命令 | 移除列表的最后一个元素,并将该元素添加到另一个列表并返回 |
Redis Rpush 命令 | 在列表中添加一个或多个值 |
Redis Rpushx 命令 | 为已存在的列表添加值 |
redis中的List在在内存中按照一个name对应一个List来存储。
lpush(name,values) 在name对应的list中添加元素,每个新的元素都添加到列表的最左边
lpushx(name,value) 在name对应的list中添加元素,只有name已经存在时,值添加到列表的最左边
llen(name) name对应的list元素的个数
linsert(name, where, refvalue, value)) 在name对应的列表的某一个值前或后插入一个新值
name:redis的name
where:BEFORE或AFTER
- refvalue:标杆值,即:在它前后插入数据
value:要插入的数据
r.lset(name, index, value) 对name对应的list中的某一个索引位置重新赋值
r.lrem(name, value, num) 在name对应的list中删除指定的值
name: redis的name
value:要删除的值
num: num=0,删除列表中所有的指定值;
num=2,从前到后,删除2个;num=-2,从后向前,删除2个.
lpop(name) 在name对应的列表的左侧获取第一个元素并在列表中移除,返回值则是第一个元素
lindex(name, index) 在name对应的列表中根据索引获取列表元素
lrange(name, start, end) 在name对应的列表分片获取数据
ltrim(name, start, end) 在name对应的列表中移除没有在start-end索引之间的值
rpoplpush(src, dst) 从一个列表取出最右边的元素,同时将其添加至另一个列表的最左边
blpop(keys, timeout) 将多个列表排列,按照从左到右去pop对应列表的元素
brpoplpush(src, dst, timeout=0) 从一个列表的右侧移除一个元素并将其添加到另一个列表的左侧
Redis set集合操作
Set集合就是不允许重复的列表。
sadd(name,values) name对应的集合中添加元素
scard(name) 获取name对应的集合中元素个数
sdiff(keys, *args) 在第一个name对应的集合中且不在其他name对应的集合的元素集合
sdiffstore(dest, keys, *args) 获取第一个name对应的集合中且不在其他name对应的集合,再将其新加入到dest对应的集合中
sinter(keys, *args) 获取多一个name对应集合的并集
sinterstore(dest, keys, *args) 获取多一个name对应集合的并集,再讲其加入到dest对应的集合中
sismember(name, value) 检查value是否是name对应的集合的成员
smembers(name) 获取name对应的集合的所有成员
smove(src, dst, value) 将某个成员从一个集合中移动到另外一个集合
spop(name) 从集合的右侧(尾部)移除一个成员,并将其返回
srandmember(name, numbers) 从name对应的集合中随机获取 numbers 个元素
srem(name, values) 在name对应的集合中删除某些值
sunion(keys, *args) 获取多一个name对应的集合的并集
sunionstore(dest,keys, *args) 获取多一个name对应的集合的并集,并将结果保存到dest对应的集合中
sscan(name, cursor=0, match=None, count=None)
sscan_iter(name, match=None, count=None) 同字符串的操作,用于增量迭代分批获取元素,避免内存消耗太大
有序集合,在集合的基础上,为每元素排序;元素的排序需要根据另外一个值来进行比较,所以,对于有序集合,每一个元素有两个值,即:值和分数,分数专门用来做排序。
zadd(name, *args, **kwargs) 在name对应的有序集合中添加元素
zcard(name) 获取name对应的有序集合元素的数量
zcount(name, min, max) 获取name对应的有序集合中分数 在 [min,max] 之间的个数
zincrby(name, value, amount) 自增name对应的有序集合的 name 对应的分数
r.zrange( name, start, end, desc=False, withscores=False, score_cast_func=float) 按照索引范围获取name对应的有序集合的元素
name,redis的nam
- start,有序集合索引起始位置(非分数)
- end,有序集合索引结束位置(非分数)
- desc,排序规则,默认按照分数从小到大排序
- withscores,是否获取元素的分数,默认只获取元素的值
- score_cast_func,对分数进行数据转换的函数
zrank(name, value) 获取某个值在 name对应的有序集合中的排行(从 0 开始)
zrem(name, values) 删除name对应的有序集合中值是values的成员
zremrangebyrank(name, min, max) 根据排行范围删除
zremrangebyscore(name, min, max) 根据分数范围删除
zscore(name, value) 获取name对应有序集合中 value 对应的分数
zinterstore(dest, keys, aggregate=None) 获取两个有序集合的交集,如果遇到相同值不同分数,则按照aggregate进行操作
zunionstore(dest, keys, aggregate=None) 获取两个有序集合的并集,如果遇到相同值不同分数,则按照aggregate进行操作
zscan(name, cursor=0, match=None, count=None, score_cast_func=float)
zscan_iter(name, match=None, count=None,score_cast_func=float) 同字符串相似,相较于字符串新增score_cast_func,用来对分数进行操作
其他常用操作
delete(*names) 删除redis中的任意数据类型
exists(name) 检测redis的name是否存在
keys(pattern='*') 根据模型获取redis的name, 参照正则匹配
expire(name ,time) 为某个redis的某个name设置超时时间
rename(src, dst) 对redis的name重命名为
move(name, db)) 将redis的某个值移动到指定的db下
randomkey() 随机获取一个redis的name(不删除)
type(name) 获取name对应值的类型
scan(cursor=0, match=None, count=None)
scan_iter(match=None, count=None) 同字符串操作,用于增量迭代获取key
管道
redis-py默认在执行每次请求都会创建(连接池申请连接)和断开(归还连接池)一次连接操作,如果想要在一次请求中指定多个命令,则可以使用pipline实现一次请求指定多个命令,并且默认情况下一次pipline 是原子性操作。
1 import redis 2 3 pool = redis.ConnectionPool(host='10.211.55.4', port=6379) 4 5 r = redis.Redis(connection_pool=pool) 6 7 # pipe = r.pipeline(transaction=False) 8 pipe = r.pipeline(transaction=True) 9 10 pipe.set('name', 'alex') 11 pipe.set('role', 'sb') 12 13 pipe.execute()
发布与订阅