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 16redis-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()
發布與訂閱
python之redis