天天看點

radis相關操作

  redis是一個key-value存儲系統。和Memcached類似,它支援存儲的value類型相對更多,包括string(字元串)、list(連結清單)、set(集合)、zset(sorted set --有序集合)和hash(哈希類型)。這些資料類型都支援push/pop、add/remove及取交集并集和差集及更豐富的操作,而且這些操作都是原子性的。在此基礎上,redis支援各種不同方式的排序。與memcached一樣,為了保證效率,資料都是緩存在記憶體中。差別的是redis會周期性的把更新的資料寫入磁盤或者把修改操作寫入追加的記錄檔案,并且在此基礎上實作了master-slave(主從)同步。

radis相關操作
radis相關操作

1. 使用Redis有哪些好處?

(1) 速度快,因為資料存在記憶體中,類似于HashMap,HashMap的優勢就是查找和操作的時間複雜度都是O(1)

(2) 支援豐富資料類型,支援string,list,set,sorted set,hash

(3) 支援事務,操作都是原子性,所謂的原子性就是對資料的更改要麼全部執行,要麼全部不執行

(4) 豐富的特性:可用于緩存,消息,按key設定過期時間,過期後将會自動删除


2. redis相比memcached有哪些優勢?

(1) memcached所有的值均是簡單的字元串,redis作為其替代者,支援更為豐富的資料類型

(2) redis的速度比memcached快很多

(3) redis可以持久化其資料


3. redis常見性能問題和解決方案:

(1) Master最好不要做任何持久化工作,如RDB記憶體快照和AOF日志檔案

(2) 如果資料比較重要,某個Slave開啟AOF備份資料,政策設定為每秒同步一次

(3) 為了主從複制的速度和連接配接的穩定性,Master和Slave最好在同一個區域網路内

(4) 盡量避免在壓力很大的主庫上增加從庫

(5) 主從複制不要用圖狀結構,用單向連結清單結構更為穩定,即:Master <- Slave1 <- Slave2 <- Slave3...

這樣的結構友善解決單點故障問題,實作Slave對Master的替換。如果Master挂了,可以立刻啟用Slave1做Master,其他不變。



 

4. MySQL裡有2000w資料,redis中隻存20w的資料,如何保證redis中的資料都是熱點資料

 相關知識:redis 記憶體資料集大小上升到一定大小的時候,就會施行資料淘汰政策。redis 提供 6種資料淘汰政策:

voltile-lru:從已設定過期時間的資料集(server.db[i].expires)中挑選最近最少使用的資料淘汰

volatile-ttl:從已設定過期時間的資料集(server.db[i].expires)中挑選将要過期的資料淘汰

volatile-random:從已設定過期時間的資料集(server.db[i].expires)中任意選擇資料淘汰

allkeys-lru:從資料集(server.db[i].dict)中挑選最近最少使用的資料淘汰

allkeys-random:從資料集(server.db[i].dict)中任意選擇資料淘汰

no-enviction(驅逐):禁止驅逐資料

 

5. Memcache與Redis的差別都有哪些?

1)、存儲方式

Memecache把資料全部存在記憶體之中,斷電後會挂掉,資料不能超過記憶體大小。

Redis有部份存在硬碟上,這樣能保證資料的持久性。

2)、資料支援類型

Memcache對資料類型支援相對簡單。

Redis有複雜的資料類型。


3),value大小

redis最大可以達到1GB,而memcache隻有1MB



6. Redis 常見的性能問題都有哪些?如何解決?

 

1).Master寫記憶體快照,save指令排程rdbSave函數,會阻塞主線程的工作,當快照比較大時對性能影響是非常大的,會間斷性暫停服務,是以Master最好不要寫記憶體快照。


2).Master AOF持久化,如果不重寫AOF檔案,這個持久化方式對性能的影響是最小的,但是AOF檔案會不斷增大,AOF檔案過大會影響Master重新開機的恢複速度。Master最好不要做任何持久化工作,包括記憶體快照和AOF日志檔案,特别是不要啟用記憶體快照做持久化,如果資料比較關鍵,某個Slave開啟AOF備份資料,政策為每秒同步一次。

 
3).Master調用BGREWRITEAOF重寫AOF檔案,AOF在重寫的時候會占大量的CPU和記憶體資源,導緻服務load過高,出現短暫服務暫停現象。

4). Redis主從複制的性能問題,為了主從複制的速度和連接配接的穩定性,Slave和Master最好在同一個區域網路内




7, redis 最适合的場景


Redis最适合所有資料in-momory的場景,雖然Redis也提供持久化功能,但實際更多的是一個disk-backed的功能,跟傳統意義上的持久化有比較大的差别,那麼可能大家就會有疑問,似乎Redis更像一個加強版的Memcached,那麼何時使用Memcached,何時使用Redis呢?

       如果簡單地比較Redis與Memcached的差別,大多數都會得到以下觀點:

     1 、Redis不僅僅支援簡單的k/v類型的資料,同時還提供list,set,zset,hash等資料結構的存儲。
     2 、Redis支援資料的備份,即master-slave模式的資料備份。
     3 、Redis支援資料的持久化,可以将記憶體中的資料保持在磁盤中,重新開機的時候可以再次加載進行使用。

(1)、會話緩存(Session Cache)

最常用的一種使用Redis的情景是會話緩存(session cache)。用Redis緩存會話比其他存儲(如Memcached)的優勢在于:Redis提供持久化。當維護一個不是嚴格要求一緻性的緩存時,如果使用者的購物車資訊全部丢失,大部分人都會不高興的,現在,他們還會這樣嗎?

幸運的是,随着 Redis 這些年的改進,很容易找到怎麼恰當的使用Redis來緩存會話的文檔。甚至廣為人知的商業平台Magento也提供Redis的插件。

(2)、全頁緩存(FPC)

除基本的會話token之外,Redis還提供很簡便的FPC平台。回到一緻性問題,即使重新開機了Redis執行個體,因為有磁盤的持久化,使用者也不會看到頁面加載速度的下降,這是一個極大改進,類似PHP本地FPC。

再次以Magento為例,Magento提供一個插件來使用Redis作為全頁緩存後端。

此外,對WordPress的使用者來說,Pantheon有一個非常好的插件  wp-redis,這個插件能幫助你以最快速度加載你曾浏覽過的頁面。

(3)、隊列

Reids在記憶體存儲引擎領域的一大優點是提供 list 和 set 操作,這使得Redis能作為一個很好的消息隊列平台來使用。Redis作為隊列使用的操作,就類似于本地程式語言(如Python)對 list 的 push/pop 操作。

如果你快速的在Google中搜尋“Redis queues”,你馬上就能找到大量的開源項目,這些項目的目的就是利用Redis建立非常好的後端工具,以滿足各種隊列需求。例如,Celery有一個背景就是使用Redis作為broker,你可以從這裡去檢視。

(4),排行榜/計數器

Redis在記憶體中對數字進行遞增或遞減的操作實作的非常好。集合(Set)和有序集合(Sorted Set)也使得我們在執行這些操作的時候變的非常簡單,Redis隻是正好提供了這兩種資料結構。是以,我們要從排序集合中擷取到排名最靠前的10個使用者–我們稱之為“user_scores”,我們隻需要像下面一樣執行即可:

當然,這是假定你是根據你使用者的分數做遞增的排序。如果你想傳回使用者及使用者的分數,你需要這樣執行:

ZRANGE user_scores 0 10 WITHSCORES

Agora Games就是一個很好的例子,用Ruby實作的,它的排行榜就是使用Redis來存儲資料的,你可以在這裡看到。

(5)、釋出/訂閱

最後(但肯定不是最不重要的)是Redis的釋出/訂閱功能。釋出/訂閱的使用場景确實非常多。我已看見人們在社交網絡連接配接中使用,還可作為基于釋出/訂閱的腳本觸發器,甚至用Redis的釋出/訂閱功能來建立聊天系統!(不,這是真的,你可以去核實)。

Redis提供的所有特性中,我感覺這個是喜歡的人最少的一個,雖然它為使用者提供如果此多功能。      
radis相關操作

一、Redis安裝和基本使用

1

2

3

4

wget http:

/

/

download.redis.io

/

releases

/

redis

-

3.0

.

6.tar

.gz

tar xzf redis

-

3.0

.

6.tar

.gz

cd redis

-

3.0

.

6

make

啟動服務端

src

/

redis

-

server

啟動用戶端

5

src

/

redis

-

cli

redis>

set

foo bar

OK

redis> get foo

"bar"

二、Python操作Redis

6

7

sudo pip install redis

or

sudo easy_install redis

or

源碼安裝

詳見:https:

/

/

github.com

/

WoLpH

/

redis

-

py

API使用

redis-py 的API的使用可以分類為:

  • 連接配接方式
  • 連接配接池
  • 操作
    • String 操作
    • Hash 操作
    • List 操作
    • Set 操作
    • Sort Set 操作
  • 管道
  • 釋出訂閱

1、操作模式

redis-py提供兩個類Redis和StrictRedis用于實作Redis的指令,StrictRedis用于實作大部分官方的指令,并使用官方的文法和指令,Redis是StrictRedis的子類,用于向後相容舊版本的redis-py。

8

#!/usr/bin/env python

# -*- coding:utf-8 -*-

import

redis

r

=

redis.Redis(host

=

'10.211.55.4'

, port

=

6379

)

r.

set

(

'foo'

,

'Bar'

)

print

r.get(

'foo'

)

備注:使用redis的字元串傳回的值為bytes類型,取不到值時傳回None

2、連接配接池

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

9

10

#!/usr/bin/env python

# -*- coding:utf-8 -*-

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'

)

通用的name的操作:

備注:

  使用redis時,判斷一個name在不在redis中時,使用r.exists("name")  ,如果删除某一個name時,直接r.delete("name"),批量删除多個時,可以使用  r.delete(*[name1,name2,name3...])

  當資料量大的時候,使用r.scan_iter()将所有的name存儲在生成器中,并且可以使用for循環得到每一個name,當資料量小的時候使用 r.keys() 将目前redis中所有的name放在一個清單中。

  不管是r.keys() 還是 r.scan_iter()  都支援正則,比如:模糊比對  

  name = 'shop_1_*'      r.scan_iter(name)  或  r.keys(name)     過濾出所有滿足比對的name的值

r.randomkey()   随機将redis中的一個name傳回

   清空redis中的資料時,使用   r.flushall() 

3、操作

String操作,redis中的String在在記憶體中按照一個name對應一個value來存儲。如圖:

radis相關操作
set(name, value, ex=None, px=None, nx=False, xx=False)

在Redis中設定值,預設,不存在則建立,存在則修改

參數:

ex,過期時間(秒)

px,過期時間(毫秒)

nx,如果設定為True,則隻有name不存在時,目前set操作才執行

xx,如果設定為True,則隻有name存在時,崗前set操作才執行

setnx(name, value)

設定值,隻有name不存在時,執行設定操作(添加)

setex(name, value, time)

# 設定值

# 參數:

# time,過期時間(數字秒 或 timedelta對象)

備注:可使用于優惠劵的過期操作

psetex(name, time_ms, value)

# 設定值

# 參數:

# time_ms,過期時間(數字毫秒 或 timedelta對象)

mset(*args, **kwargs)

批量設定值

如:

mset(k1=

'v1'

, k2=

'v2'

)

mset({

'k1'

:

'v1'

,

'k2'

:

'v2'

})

get(name)

擷取值

mget(keys, *args)

批量擷取

如:

mget(

'ylr'

,

'wupeiqi'

)

r.mget([

'ylr'

,

'wupeiqi'

])

getset(name, value)

設定新值并擷取原來的值

getrange(key, start, end)

# 擷取子序列(根據位元組擷取,非字元)

# 參數:

# name,Redis 的 name

# start,起始位置(位元組)

# end,結束位置(位元組)

# 如: "武沛齊" ,0-3表示 "武"

備注:使用getrange時,start和end是按位元組。start是按索引,包含end的位元組 比如:(“k1”,0,3)得到的結果是四個位元組(包含結尾,不同于清單)。取值操作時  0到-1表示取出所有的值。 

setrange(name, offset, value)

# 修改字元串内容,從指定字元串索引開始向後替換(新值太長時,則向後添加)

# 參數:

# offset,字元串的索引,位元組(一個漢字三個位元組)

# value,要設定的值

r.set('k2','123456')
print(r.get('k2'))   # b'123456'

r.setrange('k2',2,'ab')
print(r.get('k2'))   # b'12ab56'

r.setrange('k2',2,'abcdef')
print(r.get('k2'))   # b'12abcdef'      
setbit(name, offset, value)

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

# 對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 = "武沛齊"

source

=

"foo"

for

i

in

source:

num

=

ord

(i)

print

bin

(num).replace(

'b'

,'')

特别的,如果source是漢字

"武沛齊"

怎麼辦?

答:對于utf

-

8

,每一個漢字占

3

個位元組,那麼

"武沛齊"

則有

9

個位元組

對于漢字,

for

循環時候會按照 位元組 疊代,那麼在疊代時,将每一個位元組轉換 十進制數,然後再将十進制數轉換成二進制

11100110

10101101

10100110

11100110

10110010

10011011

11101001

10111101

10010000

-

-

-

-

-

-

-

-

-

-

-

-

-

-

-

-

-

-

-

-

-

-

-

-

-

-

-

-

-

-

-

-

-

-

-

-

-

-

-

-

-

-

-

-

-

-

-

-

-

-

-

-

-

-

-

-

-

-

-

-

-

-

-

-

-

-

-

-

-

-

-

-

-

-

-

-

-

-

-

-

-

-

-

-

武                         沛                           齊

getbit(name, offset)

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

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

# 擷取name對應的值的二進制表示中 1 的個數

# 參數:

# key,Redis的name

# start,位起始位置

# end,位結束位置

bitop(operation, dest, *keys)

# 擷取多個值,并将值做位運算,将最後的結果儲存至新的name對應的值

# 參數:

# operation,AND(并) 、 OR(或) 、 NOT(非) 、 XOR(異或)

# dest, 新的Redis的name

# *keys,要查找的Redis的name

# 如:

bitop(

"AND"

,

'new_name'

,

'n1'

,

'n2'

,

'n3'

)

# 擷取Redis中n1,n2,n3對應的值,然後講所有的值做位運算(求并集),然後将結果儲存 new_name 對應的值中

strlen(name)

# 傳回name對應值的位元組長度(一個漢字3個位元組)

incr(self, name, amount=1)

# 自增 name對應的值,當name不存在時,則建立name=amount,否則,則自增。

# 參數:

# name,Redis的name

# amount,自增數(必須是整數)

# 注:同incrby

備注:使用incr時,值如果是字元串,必須是數字類型的字元串,自增後的結果為int類型。

  若自增的name不存在時,則自增的起始值為0.

incrbyfloat(self, name, amount=1.0)

# 自增 name對應的值,當name不存在時,則建立name=amount,否則,則自增。

# 參數:

# name,Redis的name

# amount,自增數(浮點型)

decr(self, name, amount=1)

# 自減 name對應的值,當name不存在時,則建立name=amount,否則,則自減。

# 參數:

# name,Redis的name

# amount,自減數(整數)

append(key, value)

# 在redis name對應的值後面追加内容

# 參數:

key, redis的name

value, 要追加的字元串

  

Hash操作,redis中Hash在記憶體中的存儲格式如下圖:

radis相關操作
hset(name, key, value)

# name對應的hash中設定一個鍵值對(不存在,則建立;否則,修改)

# 參數:

# name,redis的name

# key,name對應的hash中的key

# value,name對應的hash中的value

# 注:

# hsetnx(name, key, value),當name對應的hash中不存在目前key時則建立(相當于添加)

hmset(name, mapping)

# 在name對應的hash中批量設定鍵值對

# 參數:

# name,redis的name

# mapping,字典,如:{'k1':'v1', 'k2': 'v2'}

# 如:

# r.hmset('xx', {'k1':'v1', 'k2': 'v2'})

hget(name,key)

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

hmget(name, keys, *args)

# 在name對應的hash中擷取多個key的值

# 參數:

# name,reids對應的name

# keys,要擷取key集合,如:['k1', 'k2', 'k3']

# *args,要擷取的key,如:k1,k2,k3

# 如:

# r.mget('xx', ['k1', 'k2'])

# 或

# print r.hmget('xx', 'k1', 'k2')

hgetall(name)

擷取name對應

hash

的所有鍵值

備注:hgetall的值為一個字典,内部元素為bytes類型。

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的鍵值對删除

備注:輸出為0(表示k1不存在)或1(表示删除成功)

hincrby(name, key, amount=1)

# 自增name對應的hash中的指定key的值,不存在則建立key=amount

# 參數:

# name,redis中的name

# key, hash對應的key

# amount,自增數(整數)

hincrbyfloat(name, key, amount=1.0)

# 自增name對應的hash中的指定key的值,不存在則建立key=amount

# 參數:

# name,redis中的name

# key, hash對應的key

# amount,自增數(浮點數)

# 自增name對應的hash中的指定key的值,不存在則建立key=amount

hscan(name, cursor=0, match=None, count=None)

# 增量式疊代擷取,對于資料大的資料非常有用,hscan可以實作分片的擷取資料,并非一次性将資料全部擷取完,進而放置記憶體被撐爆

# 參數:

# name,redis的name

# cursor,遊标(基于遊标分批取擷取資料)

# match,比對指定key,預設None 表示所有的key

# count,每次分片最少擷取個數,預設None表示采用Redis的預設分片個數

# 如:

# 第一次:cursor1, data1 = r.hscan('xx', cursor=0, match=None, count=None)

# 第二次:cursor2, data1 = r.hscan('xx', cursor=cursor1, match=None, count=None)

# ...

# 直到傳回值cursor的值為0時,表示資料已經通過分片擷取完畢

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    # 以元組的形式接收 key val (key,val)

備注:hscan_iter  為一個生成器 <generator object StrictRedis.hscan_iter at 0x0000023AEAAFEA40> 

   

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

radis相關操作
lpush(name,values)

# 在name對應的list中添加元素,每個新的元素都添加到清單的最左邊

# 如:

# r.lpush('oo', 11,22,33)

# 儲存順序為: 33,22,11

# 擴充:

# rpush(name, values) 表示從右向左操作

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,要插入的資料

r.lset(name, index, value)

# 對name對應的list中的某一個索引位置重新指派

# 參數:

# name,redis的name

# index,list的索引位置

# value,要設定的值

r.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,索引結束位置

備注:值為一個list 裡面的元素都為bytes類型,使用連結清單取出所有值時,使用 lrange(name,0,-1)

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 表示永遠阻塞

自定義增量疊代

# 由于redis類庫中沒有提供對清單元素的增量疊代,如果想要循環name對應的清單的所有元素,那麼就需要:

# 1、擷取name對應的所有清單

# 2、循環清單

# 但是,如果清單非常大,那麼就有可能在第一步時就将程式的内容撐爆,所有有必要自定義一個增量疊代的功能:

def

list_iter(name):

"""

自定義redis清單增量疊代

:param name: redis中的name,即:疊代name對應的清單

:return: yield 傳回 清單元素

"""

list_count

=

r.llen(name)

for

index

in

xrange

(list_count):

yield

r.lindex(name, index)

# 使用

for

item

in

list_iter(

'pp'

):

print

item

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對應的有序集合中添加元素

# 如:

# zadd('zz', 'n1', 1, 'n2', 2)

# 或

# zadd('zz', n1=11, n2=22)

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的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)

zrank(name, value)

# 擷取某個值在 name對應的有序集合中的排行(從 0 開始)

# 更多:

# zrevrank(name, value),從大到小排序

zrangebylex(name, min, max, start=None, num=None)

# 當有序集合的所有成員都具有相同的分值時,有序集合的元素會根據成員的 值 (lexicographical ordering)來進行排序,而這個指令則可以傳回給定的有序集合鍵 key 中, 元素的值介于 min 和 max 之間的成員

# 對集合中的每個成員進行逐個位元組的對比(byte-by-byte compare), 并按照從低到高的順序, 傳回排序後的集合成員。 如果兩個字元串有一部分内容是相同的話, 那麼指令會認為較長的字元串比較短的字元串要大

# 參數:

# name,redis的name

# min,左區間(值)。 + 表示正無限; - 表示負無限; ( 表示開區間; [ 則表示閉區間

# min,右區間(值)

# start,對結果進行分片處理,索引位置

# num,對結果進行分片處理,索引後面的num個元素

# 如:

# ZADD myzset 0 aa 0 ba 0 ca 0 da 0 ea 0 fa 0 ga

# r.zrangebylex('myzset', "-", "[ca") 結果為:['aa', 'ba', 'ca']

# 更多:

# 從大到小排序

# zrevrangebylex(name, max, min, start=None, num=None)

zrem(name, values)

# 删除name對應的有序集合中值是values的成員

# 如:zrem('zz', ['s1', 's2'])

zremrangebyrank(name, min, max)

# 根據排行範圍删除

zremrangebyscore(name, min, max)

# 根據分數範圍删除

zremrangebylex(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,用來對分數進行操作

其他常用操作

delete(*names)

# 根據删除redis中的任意資料類型

exists(name)

# 檢測redis的name是否存在

keys(pattern='*')

# 根據模型擷取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重命名為

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

 

4、管道

redis-py預設在執行每次請求都會建立(連接配接池申請連接配接)和斷開(歸還連接配接池)一次連接配接操作,如果想要在一次請求中指定多個指令,則可以使用pipline實作一次請求指定多個指令,并且預設情況下一次pipline 是原子性操作。

#!/usr/bin/env python

# -*- coding:utf-8 -*-

import

redis

pool

=

redis.ConnectionPool(host

=

'10.211.55.4'

, port

=

6379

)

r

=

redis.Redis(connection_pool

=

pool)

# pipe = r.pipeline(transaction=False)

pipe

=

r.pipeline(transaction

=

True

)

pipe.multi()

pipe.

set

(

'name'

,

'alex'

)

pipe.

set

(

'role'

,

'sb'

)

pipe.execute()

radis相關操作

實作計數器

5、釋出訂閱

radis相關操作

釋出者:伺服器

訂閱者:Dashboad和資料處理

Demo如下:

radis相關操作

RedisHelper

訂閱者:

#!/usr/bin/env python

# -*- coding:utf-8 -*-

from

monitor.RedisHelper

import

RedisHelper

obj

=

RedisHelper()

redis_sub

=

obj.subscribe()

while

True

:

msg

=

redis_sub.parse_response()

print

msg

釋出者:

#!/usr/bin/env python

# -*- coding:utf-8 -*-

from

monitor.RedisHelper

import

RedisHelper

obj

=

RedisHelper()

obj.public(

'hello'

)

6. sentinel

redis重的sentinel主要用于在redis主從複制中,如果master顧上,則自動将slave替換成master

28

29

30

#!/usr/bin/env python

# -*- coding:utf-8 -*-

from

redis.sentinel

import

Sentinel

# 連接配接哨兵伺服器(主機名也可以用域名)

sentinel

=

Sentinel([(

'10.211.55.20'

,

26379

),

(

'10.211.55.20'

,

26380

),

],

socket_timeout

=

0.5

)

# # 擷取主伺服器位址

# master = sentinel.discover_master('mymaster')

# print(master)

#

# # # 擷取從伺服器位址

# slave = sentinel.discover_slaves('mymaster')

# print(slave)

#

#

# # # 擷取主伺服器進行寫入

# master = sentinel.master_for('mymaster')

# master.set('foo', 'bar')

# # # # 擷取從伺服器進行讀取(預設是round-roubin)

# slave = sentinel.slave_for('mymaster', password='redis_auth_pass')

# r_ret = slave.get('foo')

# print(r_ret)

更多參見:https://github.com/andymccurdy/redis-py/

http://doc.redisfans.com/

作者:趙盼盼

出處:https://www.cnblogs.com/zhaopanpan/

本文版權歸作者和部落格園共有,歡迎轉載,但未經作者同意必須保留此段聲明,且在文章頁面明顯位置給出原文連接配接,否則保留追究法律責任的權利。

⇩ 關注或點個喜歡就行 ^_^

關注我

radis相關操作
radis相關操作