1. 程式人生 > >3、第八周 - 網絡編程進階 - Redis消息緩存

3、第八周 - 網絡編程進階 - Redis消息緩存

utf-8 SM -c 取出 rename none IE 列表 host

Redis概念

  Redis是主流的key-value nosql 數據庫之一。和Memcached類似,它支持存儲的value類型相對更多,包括string(字符串)、list(鏈表)、set(集合)、zset(sorted set --有序集合)和hash(哈希類型)。這些數據類型都支持push/pop、add/remove及取交集並集和差集及更豐富的操作.,redis支持各種不同方式的排序。與memcached一樣,為了保證效率,數據都是緩存在內存中。區別的是redis會周期性的把更新的數據寫入磁盤或者把修改操作寫入追加的記錄文件,並且在此基礎上實現了master-slave(主從)同步

Redis優點

  • 異常快速 : Redis是非常快的,每秒可以執行大約110000設置操作,81000個/每秒的讀取操作。
  • 豐富的數據類型 : Redis支持最大多數開發人員已經知道如列表,集合,可排序集合,哈希等數據類型。
  • 操作都是原子 : 所有 Redis 的操作都是原子,從而確保當兩個客戶同時訪問 Redis 服務器得到的是更新後的值(最新值)。
  • Mutily工具:Redis是一個多功能實用工具,可以在很多如:緩存,消息傳遞隊列中使用(Redis原生支持發布/訂閱),在應用程序中,如:Web應用程序會話,網站頁面點擊數等任何短暫的數據。

Redis API使用

  • 連接方式
  • 連接池
  • 操作
    • String 操作
    • Hash 操作
    • List 操作
    • Set 操作
    • Sort Set 操作
  • 管道
  • 發布訂閱

註:Redis 安裝,請參考百度。

Python庫安裝:https://pypi.org/project/redis/#description 參考官網

1、Redis API的連接模式

A、連接方式:

  redis-py提供兩個類Redis和StrictRedis用於實現Redis API的命令,StrictRedis用於實現大部分官方的命令,並使用官方的語法和命令,Redis是StrictRedis的子類,用於向後兼容舊版本的redis-py。

import redis

r1 = redis.StrictRedis(host=‘213.66.8.41‘, port=6379, db=0) #redis通常會設置賬號密碼,給配置password=‘‘
r1.set(‘chen‘,‘1203‘)
print(r1.get(‘chen‘))

r2 = redis.Redis(host=‘213.66.8.41‘, port=6379, db=0)
r2.set(‘chen1‘,‘12034‘)
print(r2.get(‘chen1‘))

上述代碼中有,db=0。redis 庫中,有0-15個數據,總共16個。可以通過select 來切換,如下:

127.0.0.1:6379> select 15
OK
127.0.0.1:6379[15]> 

B、連接池設置:

  redis-py使用connection pool來管理對一個redis server的所有連接,避免每次建立、釋放連接的開銷。默認,每個Redis實例都會維護一個自己的連接池。可以直接建立一個連接池,然後作為參數Redis,這樣就可以實現多個Redis實例共享一個連接池。

  連接池通常情況下, 需要做redis操作時, 會創建一個連接, 並基於這個連接進行redis操作, 操作完成後, 釋放連接。一般情況下, 是沒問題的, 但當並發量比較高的時候, 頻繁的連接創建和釋放對性能會有較高的影響,於是連接池就發揮作用。連接池的原理是, 通過預先創建多個連接, 當進行redis操作時, 直接獲取已經創建的連接進行操作, 而且操作完成後, 不會釋放, 用於後續的其他redis操作。這樣就達到了避免頻繁的redis連接創建和釋放的目的, 從而提高性能了。

import redis

pool = redis.ConnectionPool(host=‘203.66.8.41‘, port=6379, db=1)
conn = redis.Redis(connection_pool=pool)
conn.set(‘chen3‘,‘chenchangqing‘)
print(conn.get(‘chen3‘))

2、Redis 的操作方式

A、String操作:字符串操作

redis中的String在在內存中按照一個name對應一個value來存儲。

技術分享圖片

查看工具語法的使用,使用help 。如下:

127.0.0.1:6379> help set

  SET key value [EX seconds] [PX milliseconds] [NX|XX]
  summary: Set the string value of a key
  since: 1.0.0
  group: string

String工具及語法使用:

SET key value [EX seconds] [PX milliseconds] [NX|XX]

在Redis中設置值的時候,默認:不存在則創建,存在則修改
參數:
     ex,過期時間(秒)
     px,過期時間(毫秒)
     nx,如果設置為True,則只有name不存在時,當前set操作才執行
     xx,如果設置為True,則只有name存在時,崗前set操作才執行

操作:
# redis-cli 
127.0.0.1:6379> set chen 1203 #設置k/v
OK
127.0.0.1:6379> EXPIRE chen 15 #設置key的過期時間EXPIRE以秒計時;EXPIREAT以毫秒計時
(integer) 1
127.0.0.1:6379> TTL chen #查看還有多長時間過期
(integer) 7	

setnx(name, value)

設置值,只有name不存在時,執行設置操作(添加)。操作如下:
127.0.0.1:6379> setnx key 123
(integer) 1
127.0.0.1:6379> setnx key 124 
(integer) 0
127.0.0.1:6379> keys *
1) "key" 

setex(name, time,value)

# 設置值
# 參數:
    # time,過期時間(數字秒 或 timedelta對象)  
操作:
127.0.0.1:6379> setex chen1 10 1203
OK
127.0.0.1:6379> keys *
1) "chen1"
2) "key"
127.0.0.1:6379> keys *
1) "key"

psetex(name, time_ms, value)

# 設置值
# 參數:
    # time_ms,過期時間(數字毫秒 或 timedelta對象)
操作:
> PSETEX chen2 10000 chen12
>127.0.0.1:6379> keys *
1) "chen1"
2) "chen2"
3) "key"
>127.0.0.1:6379> keys *
1) "chen1"
2) "key"

mset(*args, **kwargs)

批量設置值
如:
    mset(k1=‘v1‘, k2=‘v2‘)
    或
    mget({‘k1‘: ‘v1‘, ‘k2‘: ‘v2‘})
操作:
127.0.0.1:6379> mset chen3 12 chen4 13
OK
127.0.0.1:6379> keys *
1) "chen3"
2) "chen1"
3) "chen4"
4) "key"
127.0.0.1:6379> mget chen3 chen4
1) "12"
2) "13"

get(name)

獲取值

mget(keys, *args)

批量獲取
如:
    mget(‘ylr‘, ‘wui‘)
    或
    r.mget([‘ylr‘, ‘wui‘])

127.0.0.1:6379> mget chen3 chen4
1) "12"
2) "13"

getset(name, value)

設置新值並獲取原來的值

127.0.0.1:6379> get chen3
"18"
127.0.0.1:6379> getset chen3 20
"18"
127.0.0.1:6379> get chen3
"20"

getrange(key, start, end) :根據索引值切片

# 獲取子序列(根據字節獲取,非字符), 相當於切片
如下:
127.0.0.1:6379> set chang fasgsffsfas20
OK
127.0.0.1:6379> GETRANGE chang 3 8
"gsffsf"

setrange(name, offset, value)

# 修改字符串內容,從指定字符串索引開始向後替換(新值太長時,則向後添加)
# 參數:
    # offset,字符串的索引,字節(一個漢字三個字節)
    # value,要設置的值
操作:
127.0.0.1:6379> get chang
"fasesffsfas20"
127.0.0.1:6379> SETRANGE chang 9 A  #索引值,第9個值改為大寫
(integer) 13
127.0.0.1:6379> get chang
"fasesffsfAs20"

setbit(name, offset, value)

# 對name對應值的二進制表示的位進行操作
 
# 參數:
    # name,redis的name
    # offset,位的索引(將值變換成二進制後再進行索引)
    # value,值只能是 1 或 0
 
註:如果在Redis中有一個對應: n1 = "foo",
        那麽字符串foo的二進制表示為:01100110 01101111 01101111
    所以,如果執行 setbit(‘n1‘, 7, 1),則就會將第7位設置為1,
        那麽最終二進制則變成 01100111 01101111 01101111,即:"goo"

# 擴展,轉換二進制表示:
 
    source = "foo"
 
    for i in source:
        num = ord(i)
        print bin(num).replace(‘b‘,‘‘)

如果source是漢字 ,怎麽辦?
    答:對於utf-8,每一個漢字占 3 個字節,對於漢字,for循環時候會按照 字節 叠代,那麽在叠代時,將每一個字節轉換 十進制數,然後再將十進制數轉換成二進制。

getbit(name, offset)

# 獲取name對應的值的二進制表示中的某位的值 (0或1)

bitcount(key, start=None, end=None)

# 獲取name對應的值的二進制中表示 1 的個數
# 參數:
    # key,Redis的name
    # start,位起始位置
    # end,位結束位置

127.0.0.1:6379> get chang
"fasesffsfAs20"
127.0.0.1:6379> BITCOUNT chang 2 9
(integer) 33

備註:可通過ascii碼表,找到字母對應數字值,在準換成二進制,最後匯總得出總數33

>ord(a)
97
>bin(97)
ob 01100001

strlen(name)

# 返回name對應值的字節長度(一個漢字3個字節)

127.0.0.1:6379> get chang
"fasesffsfAs20"
127.0.0.1:6379> STRLEN chang
(integer) 13

append(key, value)

# 在redis name對應的值後面追加內容
 
# 參數:
    key, redis的name
    value, 要追加的字符串
操作:
127.0.0.1:6379> get chen4
"13"
127.0.0.1:6379> APPEND chen4 chenchang
(integer) 15
127.0.0.1:6379> get chen4
"13chenchang"

下面三個參數不常用,可通help查看語法

incr(self, name, amount=1)
incrbyfloat(self, name, amount=1.0)
decr(self, name, amount=1)

127.0.0.1:6379> help decr

  DECR key
  summary: Decrement the integer value of a key by one
  since: 1.0.0
  group: string

B、 Hash操作

hash表現形式上有些像pyhton中的字典,可以存儲一組關聯性較強的數據 , redis中Hash在內存中的存儲格式如下圖:

技術分享圖片

hset(name, key, value)

# name對應的hash中設置一個鍵值對(不存在,則創建;否則,修改)
# 參數:
    # name,redis的name
    # key,name對應的hash中的key
    # value,name對應的hash中的value
 
# 註:
    # hsetnx(name, key, value),當name對應的hash中不存在當前key時則創建(相當於添加)

如:
127.0.0.1:6379> hset qing 1 chen
127.0.0.1:6379> hset qing 2 chen1
127.0.0.1:6379> hset qing  3 chen3
輸出數據
127.0.0.1:6379> hget qing 1 
"chen"
127.0.0.1:6379> hget qing 2
"chen1"
127.0.0.1:6379> hget qing 3
"chen3"

hget(name,key)

# 在name對應的hash中獲取根據key獲取value

hmset(name, mapping)

# 在name對應的hash中批量設置鍵值對
 
# 參數:
    # name,redis的name
    # mapping,字典,如:{‘k1‘:‘v1‘, ‘k2‘: ‘v2‘}

127.0.0.1:6379> HMSET qing 4 chen4 5 chen5 6 chen6
OK
127.0.0.1:6379> HMGET qing 4 5 6 
1) "chen4"
2) "chen5"
3) "chen6"

hmget(name, keys, *args)

# 在name對應的hash中獲取多個key的值
 
# 參數:
    # name,reids對應的name
    # keys,要獲取key集合,如:[‘k1‘, ‘k2‘, ‘k3‘]
    # *args,要獲取的key,如:k1,k2,k3
127.0.0.1:6379> HMGET qing 4 5 6 
1) "chen4"
2) "chen5"
3) "chen6"

hgetall(name)

獲取name對應hash的所有鍵值
127.0.0.1:6379> HGETALL qing
 1) "1"
 2) "chen"
 3) "2"
 4) "chen1"
 5) "3"
 6) "chen3"

hlen(name)

# 獲取name對應的hash中鍵值對的個數

hkeys(name)

# 獲取name對應的hash中所有的key的值

127.0.0.1:6379> HKEYS qing
1) "1"
2) "2"
3) "3"
4) "4"
5) "5"
6) "6"

hvals(name)

# 獲取name對應的hash中所有的value的值

127.0.0.1:6379> hvals qing
1) "chen"
2) "chen1"
3) "chen3"
4) "chen4"
5) "chen5"
6) "chen6"

hexists(name, key)

# 檢查name對應的hash是否存在當前傳入的key
127.0.0.1:6379> HEXISTS qing 6
(integer) 1

1為存在;0不存在

hdel(name,*keys)

# 將name對應的hash中指定key的鍵值對刪除

127.0.0.1:6379> Hkeys qing
1) "1"
2) "2"
3) "3"
4) "4"
5) "5"
6) "6"
127.0.0.1:6379> HDEL qing 5  6
(integer) 2
127.0.0.1:6379> Hkeys qing
1) "1"
2) "2"
3) "3"
4) "4"

hincrby(name, key, amount=1)

# 自增name對應的hash中的指定key的值,不存在則創建key=amount
# 參數:
    # name,redis中的name
    # key, hash對應的key
    # amount,自增數(整數)

127.0.0.1:6379> hget qing 5
"1"
127.0.0.1:6379> HINCRBY qing 5 3 #5 為 key ;3為步長,每執行一次,網上增加數值。
(integer) 4
127.0.0.1:6379> HINCRBY qing 5 3
(integer) 7
127.0.0.1:6379> HINCRBY qing 5 3
(integer) 10
127.0.0.1:6379> hget qing 5
"10"

hincrbyfloat(name, key, amount=1.0)

# 自增name對應的hash中的指定key的值,不存在則創建key=amount
 
# 參數:
    # name,redis中的name
    # key, hash對應的key
    # amount,自增數(浮點數)
# 自增name對應的hash中的指定key的值,不存在則創建key=amount
127.0.0.1:6379> hget qing 6
"0"
127.0.0.1:6379> HINCRBYFLOAT qing 6 1.5
"1.5"
127.0.0.1:6379> HINCRBYFLOAT qing 6 1.5
"3"
127.0.0.1:6379> HINCRBYFLOAT qing 6 1.5
"4.5"
127.0.0.1:6379> HINCRBYFLOAT qing 6 1.5
"6"

hscan(name, cursor=0, match=None, count=None) #重新理解

 增量式叠代獲取,對於數據大的數據非常有用,hscan可以實現分片的獲取數據,並非一次性將數據全部獲取完,從而放置內存被撐爆
 
# 參數:
    # name,redis的name
    # cursor,遊標(基於遊標分批取獲取數據)
    # match,匹配指定key,默認None 表示所有的key
    # count,每次分片最少獲取個數,默認None表示采用Redis的默認分片個數

127.0.0.1:6379> HSCAN qing 2 count 10
1) "0"
2)  1) "1"
    2) "chen"
    3) "2"
    4) "chen1"
    5) "3"
    6) "chen3"
    7) "4"
    8) "chen4"
    9) "5"
   10) "19"
   11) "6"
   12) "15"
   13) "chen"
   14) "chnesgsewe"


127.0.0.1:6379> HSCAN qing 3 match *chen* count 12
1) "0"
2) 1) "chen"
   2) "chnesgsewe"

遍歷操作 SCAN cursor [MATCH pattern] [COUNT count]

  • SCAN、SSCAN、HSCAN、ZSCAN是遍歷集合元素的命令。
  • SCAN:遍歷選中的Redis數據庫的集合,相當於全庫掃描。
  • SSCAN:遍歷Sets類型的元素。
  • HSCAN:遍歷Hash類型及對應的value。
  • ZSCAN:遍歷Sorted Set類型和對應的scores。

hscan_iter(name, match=None, count=None) #重新理解

# 利用yield封裝hscan創建生成器,實現分批去redis中獲取數據
  
# 參數:
    # match,匹配指定key,默認None 表示所有的key
    # count,每次分片最少獲取個數,默認None表示采用Redis的默認分片個數
  
# 如:
    # for item in r.hscan_iter(‘xx‘):
    #     print item

C、 list列表操作

List操作,redis中的List在在內存中按照一個name對應一個List來存儲。如圖:

技術分享圖片

lpush(name,values)

# 在name對應的list中添加元素,每個新的元素都添加到列表的最左邊
 
# 如:
    # r.lpush(‘oo‘, 11,22,33)
    # 保存順序為: 33,22,11
 
# 擴展:
    # rpush(name, values) 表示從右向左操作
#查看redis 列表
127.0.0.1:6379> LRANGE chen 0 20
 1) "chen12"
 2) "chen11"
 3) "chen12"
 4) "chen11"
 5) "chen12"
 6) "chen11"

lpushx(name,value)

# 在name對應的list中添加元素,只有name已經存在時,值添加到列表的最左邊
 
# 更多:
    # rpushx(name, value) 表示從右向左操作

llen(name)

# name對應的list元素的個數

linsert(name, where, refvalue, value))

# 在name對應的列表的某一個值前或後插入一個新值
 
# 參數:
    # name,redis的name
    # where,BEFORE或AFTER
    # refvalue,標桿值,即:在它前後插入數據
    # value,要插入的數據

lset(name, index, value)

# 對name對應的list中的某一個索引位置重新賦值
 
# 參數:
    # name,redis的name
    # index,list的索引位置
    # value,要設置的值

lrem(name, value, num)

# 在name對應的list中刪除指定的值
 
# 參數:
    # name,redis的name
    # value,要刪除的值
    # num,  num=0,刪除列表中所有的指定值;
           # num=2,從前到後,刪除2個;
           # num=-2,從後向前,刪除2個

lpop(name)

# 在name對應的列表的左側獲取第一個元素並在列表中移除,返回值則是第一個元素
 
# 更多:
    # rpop(name) 表示從右向左操作

lindex(name, index)

在name對應的列表中根據索引獲取列表元素

lrange(name, start, end)

# 在name對應的列表分片獲取數據
# 參數:
    # name,redis的name
    # start,索引的起始位置
    # end,索引結束位置

> LRANGE chen 0 20

ltrim(name, start, end)

# 在name對應的列表中移除沒有在start-end索引之間的值
# 參數:
    # name,redis的name
    # start,索引的起始位置
    # end,索引結束位置

rpoplpush(src, dst)

# 從一個列表取出最右邊的元素,同時將其添加至另一個列表的最左邊
# 參數:
    # src,要取數據的列表的name
    # dst,要添加數據的列表的name

blpop(keys, timeout)

# 將多個列表排列,按照從左到右去pop對應列表的元素
 
# 參數:
    # keys,redis的name的集合
    # timeout,超時時間,當元素所有列表的元素獲取完之後,阻塞等待列表內有數據的時間(秒), 0 表示永遠阻塞
 
# 更多:
    # r.brpop(keys, timeout),從右向左獲取數據

brpoplpush(src, dst, timeout=0)

# 從一個列表的右側移除一個元素並將其添加到另一個列表的左側
 
# 參數:
    # src,取出並要移除元素的列表對應的name
    # dst,要插入元素的列表對應的name
    # timeout,當src對應的列表中沒有數據時,阻塞等待其有數據的超時時間(秒),0 表示永遠阻塞

D、set集合操作

Set操作,Set集合就是不允許重復的列表

sadd(name,values)

#name對應的集合中添加元素
設置集合
127.0.0.1:6379[1]> SADD chen chang1 chang2 chang3
(integer) 3
可以利用sdiff查看集合中的元素
127.0.0.1:6379[1]> SDIFF chen
1) "chang1"
2) "chang2"
3) "chang3"

scard(name)

獲取name對應的集合中元素個數
127.0.0.1:6379[1]> scard chen
(integer) 3

sdiff(keys, *args)

在第一個name對應的集合中且不在其他name對應的集合的元素集合。。以第一個集合為基準

127.0.0.1:6379[1]> SDIFF chen
1) "chang1"
2) "chang2"
3) "chang3"
127.0.0.1:6379[1]> SDIFF chen1
1) "qing3"
2) "qing1"
3) "qing2"
4) "chang3"
127.0.0.1:6379[1]> SDIFF chen chen1 #獲取第一個集合中跟第二個集合中不相同的元素
1) "chang1"
2) "chang2"

sdiffstore(dest, keys, *args)

#獲取第一個chen對應的集合中且不在其他chen1對應的集合,再將其新加入到chen2對應的集合中

127.0.0.1:6379[1]> SDIFFSTORE chen2 chen chen1
(integer) 2
127.0.0.1:6379[1]> SDIFF chen2
1) "chang2"
2) "chang1"

sinter(keys, *args)

# 獲取多一個name對應集合的交集
127.0.0.1:6379[1]> SINTER chen chen1
1) "chang3"
127.0.0.1:6379[1]> 

sinterstore(dest, keys, *args)

# 獲取多個name對應集合的交集,再講其加入到dest對應的集合中
127.0.0.1:6379[1]> SINTERSTORE chen3 chen chen1
(integer) 1
127.0.0.1:6379[1]> SDIFF chen3
1) "chang3"

sismember(name, value)

# 檢查value是否是name對應的集合的成員 :0否 1是

127.0.0.1:6379[1]> SISMEMBER chen chang3
(integer) 1
127.0.0.1:6379[1]> SISMEMBER chen chang4
(integer) 0

smembers(name)

將某個成員從一個集合中移動到另外一個集合

127.0.0.1:6379[1]> SMEMBERS chen
1) "chang2"
2) "chang1"
3) "chang3"

spop(name)

從集合的右側(尾部)移除一個成員,並將其返回

127.0.0.1:6379[1]> SMEMBERS chen1
1) "qing3"
2) "chang3"
3) "qing2"
4) "qing1"
127.0.0.1:6379[1]> SPOP chen1
"chang3"
127.0.0.1:6379[1]> SMEMBERS chen1
1) "qing3"
2) "qing2"
3) "qing1"

srandmember(name, numbers)

從name對應的集合中隨機獲取 numbers 個元素,並返回

127.0.0.1:6379[1]> SRANDMEMBER chen1 2
1) "qing1"
2) "qing2"
127.0.0.1:6379[1]> SRANDMEMBER chen1 1
1) "qing1"

srem(name, values)

在name對應的集合中刪除指定的值。

127.0.0.1:6379[1]> srem chen1 qing3
(integer) 1
127.0.0.1:6379[1]> SMEMBERS chen1
1) "qing2"
2) "qing1"

sunion(keys, *args)

獲取多一個name對應的集合的並集

127.0.0.1:6379[1]> SMEMBERS chen
1) "chang2"
2) "chang1"
3) "chang3"
127.0.0.1:6379[1]> SMEMBERS chen1
1) "chen"
2) "chang3"
3) "qing2"
4) "qing1"
127.0.0.1:6379[1]> SUNION chen chen1
1) "chang1"
2) "qing1"
3) "chang2"
4) "chang3"
5) "chen"
6) "qing2"

sunionstore(dest,keys, *args)

# 獲取多個name對應的集合的並集,並將結果保存到chen4對應的集合中
127.0.0.1:6379[1]> sunionstore chen4 chen chen1
(integer) 6
127.0.0.1:6379[1]> SMEMBERS chen4
1) "chang1"
2) "qing1"
3) "chang2"
4) "chang3"
5) "chen"
6) "qing2"

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] 之間的個數

操作:
127.0.0.1:6379[1]> ZADD c1 1 "chen" 2 "chang" 3 "qing"
(integer) 3
127.0.0.1:6379[1]> ZCARD c1
(integer) 3
127.0.0.1:6379[1]> ZRANGE c1 0 -1 WITHScORES
1) "chen"
2) "1"
3) "chang"
4) "2"
5) "qing"
6) "3"
127.0.0.1:6379[1]> ZCOUNT c1 0 100
(integer) 3

zrange( name, start, end, desc=False, withscores=False, score_cast_func=float)

# 按照索引範圍獲取name對應的有序集合的元素
 
# 參數:
    # name,redis的name
    # start,有序集合索引起始位置(非分數)
    # end,有序集合索引結束位置(非分數)
    # desc,排序規則,默認按照分數從小到大排序
    # withscores,是否獲取元素的分數,默認只獲取元素的值
    # score_cast_func,對分數進行數據轉換的函數

# 更多:
    # 從大到小排序
    # zrevrange(name, start, end, withscores=False, score_cast_func=float)
 
    # 按照分數範圍獲取name對應的有序集合的元素
    # zrangebyscore(name, min, max, start=None, num=None, withscores=False, score_cast_func=float)
    # 從大到小排序
    # zrevrangebyscore(name, max, min, start=None, num=None, withscores=False, score_cast_func=float)

zincrby(name, value, amount)

# 自增name對應的有序集合的 name 對應的分數
127.0.0.1:6379[1]> ZINCRBY c1 3 amount
"18"
127.0.0.1:6379[1]> ZRANGE c1 0 -1 WITHSCORES
1) "chen"
2) "1"
3) "chang"
4) "2"
5) "qing"
6) "3"
7) "amount"
8) "18"

zrank(name, value)

# 獲取某個值在 name對應的有序集合中的排行(從 0 開始)
 
# 更多:
    # zrevrank(name, value),從大到小排序

127.0.0.1:6379[1]> ZRANK c1 qing #查找集合中的成員
(integer) 2
127.0.0.1:6379[1]> ZRANK c1 chang
(integer) 1
  • zrem(name, values) #刪除name對應的有序集合中值是values的成員 # 如:zrem(‘zz‘, [‘s1‘, ‘s2‘])
  • zremrangebyrank(name, min, max) #根據排行範圍刪除
  • zremrangebyscore(name, min, max) # 根據分數範圍刪除
  • zscore(name, value) # 獲取name對應有序集合中 value 對應的分數
  • zinterstore(dest, keys, aggregate=None) # 獲取兩個有序集合的交集,如果遇到相同值不同分數,則按照aggregate進行操作 # aggregate的值為: SUM MIN MAX
  • zunionstore(dest, keys, aggregate=None) # 獲取兩個有序集合的並集,如果遇到相同值不同分數,則按照aggregate進行操作 aggregate的值為: SUM MIN MAX
  • 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,用來對分數進行操作

其他常用操作

del names

# 根據刪除redis中的任意數據類型
127.0.0.1:6379[1]> DEL c1
(integer) 1

exists name

# 檢測redis的name是否存在
127.0.0.1:6379[1]> exists c1
(integer) 0

keys ‘*‘

# 根據模型獲取redis的name
 
# 更多:
    # KEYS * 匹配數據庫中所有 key 。
    # KEYS h?llo 匹配 hello , hallo 和 hxllo 等。
    # KEYS h*llo 匹配 hllo 和 heeeeello 等。
    # KEYS h[ae]llo 匹配 hello 和 hallo ,但不匹配 hillo

expire name time

為某個redis的某個name設置超時時間

rename(src, dst)

# 對redis的name重命名為
127.0.0.1:6379[1]> KEYS *
1) "chen3"
127.0.0.1:6379[1]> RENAME chen3 chan3
OK
127.0.0.1:6379[1]> KEYS *
1) "chan3"

move(name, db))

# 將redis的某個值移動到指定的db下
127.0.0.1:6379[1]> KEYS *
1) "chan3"
2) "chen11"
127.0.0.1:6379[1]> MOVE chen11 6
(integer) 1
127.0.0.1:6379[1]> KEYS *
1) "chan3"
127.0.0.1:6379[1]> select 6 
OK
127.0.0.1:6379[6]> keys *
1) "chen11"

randomkey()

# 隨機獲取一個redis的name(不刪除)

127.0.0.1:6379[1]> RANDOMKEY
"chen1"
127.0.0.1:6379[1]> RANDOMKEY
"chen2"
127.0.0.1:6379[1]> RANDOMKEY
"myset"

type(name)

# 獲取name對應值的類型
127.0.0.1:6379[1]> TYPE chan3
set
127.0.0.1:6379[1]> type chen
string

scan(cursor=0, match=None, count=None)
scan_iter(match=None, count=None)

# 同字符串操作,用於增量叠代獲取key

3、Redis 管道

4、Redis 訂閱發布

技術分享圖片

類似RabbitMQ發布訂閱模式。

Redis_daemon.py

import redis

class RedisHelper:

    def __init__(self):
        self.__conn = redis.Redis(host=‘localhost‘,port=6379,db=2)
        self.chan_sub = ‘fm104.5‘
        self.chan_pub = ‘fm104.5‘

    def public(self, msg):
        self.__conn.publish(self.chan_pub, msg)
        return True

    def subscribe(self):
        pub = self.__conn.pubsub() #打開收音機
        pub.subscribe(self.chan_sub)#調頻道
        pub.parse_response() #準備接收
        return pub #接收

用戶訂閱:redis_recv.py(可以執行多個終端)

import sys
sys.path.append("/www")
import redis_daemon
 
obj = redis_daemon.RedisHelper()
redis_sub = obj.subscribe()
 
while True:
    msg= redis_sub.parse_response()
    print (msg)

發布者:

import sys
sys.path.append("/www")
import redis_daemon
 
obj = redis_daemon.RedisHelper()
while True:
  msg = input("Enter messsage:")
  obj.public(msg)

操作效果:

發布者、通過腳本發布:
# /opt/Python-3.5.2/python redis_send.py 
Enter messsage:chen
Enter messsage:chang
Enter messsage:qing

通過命令行發布:
127.0.0.1:6379[2]> PUBLISH fm104.5 chenchangqing
(integer) 1
127.0.0.1:6379[2]> PUBLISH fm104.5 "how2 "
(integer) 1

訂閱者
# /opt/Python-3.5.2/python redis_recv.py 
[b‘message‘, b‘fm104.5‘, b‘hello‘]
[b‘message‘, b‘fm104.5‘, b‘chen‘]
[b‘message‘, b‘fm104.5‘, b‘chang‘]
[b‘message‘, b‘fm104.5‘, b‘qing‘]
[b‘message‘, b‘fm104.5‘, b‘chenchangqing‘]

3、第八周 - 網絡編程進階 - Redis消息緩存