Redis 各類型常用方法與 運用場景

數據結構性質 決定其 用途:

Redis的六種特性

Strings     --->計數(微博數等)

Hashs      --->用戶信息  (map)

Lists        ---> TOPN 最新

Sets        --->朋友圈共同好友 :交集 並集  二度好友 

Sorted Sets   -->scords 權重  按權進行排序  如:按文章 點贊 排名

Pub/Sub      --->發佈、訂閱

Redis各特性的應用場景

Strings

Strings 數據結構是簡單的key-value類型,value其實不僅是String,也可以是數字。

常用方法

方法

說明

特性

set

設置key對應的的值爲String類型的value

   

get

獲取對應key對應的String的值,如果不存在返回nil

   

setnx

設置可以爲對應的值爲String類型的value,如果key存在返回0不覆蓋,不存在返回1

nx的意思爲not exist

Set the value of a key, only if the key does not exist

setex

key對應的值爲String類型的value,並指定此鍵值對應的有效期

SETEX key seconds value

例:setex mykey 10 你好

setrange

設置keyvalue的子字符串

setrange key 位置 替換的內容

如果替換內容沒有原value,則原value剩餘的內容將被保留

mset

一次設置多個key的值,成功返回ok,失敗返回0要成功都成功,要不成功全部失敗。

mset key1 內容一 key2 內容二

msetnx

一次設置多個key的值,成功返回ok,失敗返回0不覆蓋已經存在的值,要成功都成功,要失敗都失敗。

   

getset

設置key的值並返回key的舊值

getset key newValuse

getrange

獲取key對應的value子字符串

getrange key 0 5 //獲取前6個字符

mget

批量獲取

mget key1 key2 key3 //沒有設置則返回空

incr

key的值做增加操作,並返回新的值

   +1

incrby

對可以的value加指定的值,

key如果不存在會設置keyvalue0

incrby key1 5 //key1的值加5

decr

key的值做減減操作

    -1

decrby

key的值減去指定值

   

append

給指定key的字符串追加value,返回新的字符串長度

   

strlen

取指定keyvalue值的長度

   

使用場景

常規key-value緩存應用。

常規計數微博數粉絲數

Hashs

Memcached中,我們經常將一些結構化的信息打包成hashmap,在客戶端序列化後存儲爲一個字符串的值,比如用戶的暱稱、年齡、性別、積分等,這時候在需要修改其中某一項時,通常需要將所有值取出反序列化後,修改某一項的值,再序列化存儲回去。這樣不僅增大了開銷,也不適用於一些可能併發操作的場合(比如兩個併發的操作都需要修改積分)。而RedisHash結構可以使你像在數據庫中Update一個屬性一樣只修改某一項屬性值

它是一個String類型的fieldvalue的映射表,它的添加和刪除都是平均的,hash特別適合用於存儲對象,對於將對象存儲成字符串而言,hash會佔用更少的內存,並且可以更方便的存取整個對象它和javaHashMap完全類似

常用方法

方法

說明

特性

hset

設置一個hash field爲指定值,如果key不存在則先創建

hset tab ke1 val1

hget

獲取某個hash的某個field

hget tab ke1

hsetnx

類似string只是操作的是hash

   

hmset

批量設置hash的內容

   

hmget

獲取hash表的全部key

Hmget key field1 field2

hincrby

hash表的某個字段增加值

   

hexists

判斷hash表中某個key是否存在

   

hlen

返回hash表中的key數量

   

hdel

刪除指定hash表的某個鍵值對

   

hkeys

返回hash表中所有的key

    

hvals

返回hash表中所有的value

   

hgetall

 獲取hash表中所有keyvalue

   

使用場景

存儲部分變更數據

如用戶信息等。

Lists

Lists 就是鏈表,略有數據結構知識的人都應該能理解其結構。使用Lists結構,我們可以輕鬆地實現最新消息排行等功能。Lists的另一個應用就是消息隊列,可以利用ListsPUSH操作,將任務存在Lists中,然後工作線程再用POP操作將任務取出進行執行。Redis還提供了操作Lists中某一段的api,你可以直接查詢,刪除Lists中某一段的元素。

 

Redislist是每個子元素都是String類型的雙向鏈表,可以通過pushpop操作從列表的頭部或者尾部添加或者刪除元素,這樣List即可以作爲棧,也可以作爲隊列

常用方法

方法

說明

特性

lpush

key所對應的list頭部添加一個元素

l的意思是left

rpush

key說對應的list尾部添加一個元素

r的意思是right

lrange

顯示list裏面的內容

lrange 0 -1 //全部顯示

linsert

key對應的list

linsert mylist before one myvalue

lset

設置list中指定下標元素的值

lset mylist index myvalue

lrem

key對應的list中刪除n個和value相同的元素,結果返回影響元素的個數,n<0從尾部開始刪除,n=0全刪除

lrem mylist count "value"

ltrim

保留指定key範圍內的數據,返回ok成功

ltrim mylist 0 3 //0-3是保留的範圍

lpop

list的頭部刪除一個元素,並返回該刪除的元素

 

rpop

list的尾部彈出一個元素,並返回該刪除的元素

 

rpoplpush

從第一個list的尾部元素異常元素並添加到第二個list的頭部

rpoplpush mylistA mylistB

lindex

返回list位置的元素

lindex mylist 3

llen

返回list中元素的個數

llen mylist

使用場景

消息隊列系統

使用list可以構建隊列系統,使用sorted set甚至可以構建有優先級的隊列系統。

比如:將Redis用作日誌收集器

實際上還是一個隊列,多個端點將日誌信息寫入Redis,然後一個worker統一將所有日誌寫到磁盤。

取最新N個數據的操作

記錄前N個最新登陸的用戶Id列表,超出的範圍可以從數據庫中獲得。

//把當前登錄人添加到鏈表裏

ret = r.lpush("login:last_login_times", uid)

//保持鏈表只有N

ret = redis.ltrim("login:last_login_times", 0, N-1)

//獲得前N個最新登陸的用戶Id列表

last_login_list = r.lrange("login:last_login_times", 0, N-1)

 

比如sina微博:

Redis中我們的最新微博ID使用了常駐緩存,這是一直更新的。但是我們做了限制不能超過5000ID,因此我們的獲取ID函數會一直詢問Redis。只有在start/count參數超出了這個範圍的時候,才需要去訪問數據庫。

我們的系統不會像傳統方式那樣刷新緩存,Redis實例中的信息永遠是一致的。SQL數據庫(或是硬盤上的其他類型數據庫)只是在用戶需要獲取很遠的數據時纔會被觸發,而主頁或第一個評論頁是不會麻煩到硬盤上的數據庫了。

Sets

Sets 就是一個集合,集合的概念就是一堆不重複值的組合。利用Redis提供的Sets數據結構,可以存儲一些集合性的數據。

案例:

微博應用中,可以將一個用戶所有的關注人存在一個集合中,將其所有粉絲存在一個集合。Redis還爲集合提供了求交集、並集、差集等操作,可以非常方便的實現如共同關注、共同喜好、二度好友等功能,對上面的所有集合操作,你還可以使用不同的命令選擇將結果返回給客戶端還是存集到一個新的集合中。

 

Set是集合,是String類型的無序集合set是通過hashtable實現的,概念和數學中個的集合基本類似,可以交集,並集,差集等等,set中的元素是沒有順序的。

常用方法

方法

說明

特性

sadd

向名稱爲keyset中添加元素,返回影響元素的個數,0爲失敗,1爲成功

sadd myset value

smembers

查看集合中所有的成員

smebers myset

srem

刪除集合的一個元素

srem myset two

spop

隨機返回並刪除set中一個元素

spop myset

sdiff

返回所有set與第一個set的差集

sdiff myset1 myset2

sdiffstore

比較差集並且存儲到另一個set中,返回1代表成功

sdiffstore setstoreSet mySet1 myset2

sinter

返回所有給定集合的交集

sinter myset1 mysert2 //1集合和2集合的交集

sinterstore

返回給定集合的交集並存儲到另一個集合

sinterstore desset myset1 myset2 //存到desset集合中

sunion

返回所有給定集合的並集

sunion set1 set2

sunionstore

返回所有的並集並且存儲到另一個集合中,返回影響的元素個數

sunionstore destSet myset1 myset2

smove

把第一個集合的元素移動到第二個集合中

smove myset myset 你好

scard

返回集合中元素的個數

scard myset1

sismember

測試某個元素是否在集合中,返回0是不是,大於0是存在

sismember mykey1 你好

srandmember

隨機返回個集合中的元素

srandmemeber myset1

使用場景

交集,並集,差集:(Set)

//book表存儲book名稱

set book:1:name    ”The Ruby Programming Language”

set book:2:name     ”Ruby on rail”

set book:3:name     ”Programming Erlang”

//tag表使用集合來存儲數據,因爲集合擅長求交集、並集

sadd tag:ruby 1

sadd tag:ruby 2

sadd tag:web 2

sadd tag:erlang 3

 

//即屬於ruby又屬於web的書?

 inter_list = redis.sinter("tag.web", "tag:ruby")

//即屬於ruby,但不屬於web的書?

 inter_list = redis.sdiff("tag.ruby", "tag:web")

//屬於ruby和屬於web的書的合集?

 inter_list = redis.sunion("tag.ruby", "tag:web")

獲取某段時間所有數據去重值

這個使用Redisset數據結構最合適了,只需要不斷地將數據往set中扔就行了,set意爲集合,所以會自動排重。

Sorted Sets

Sets相比,Sorted Sets增加了一個權重參數score,使得集合中的元素能夠按score進行有序排列,比如一個存儲全班同學成績的Sorted Sets,其集合value可以是同學的學號,而score就可以是其考試得分,這樣在數據插入集合的時候,就已經進行了天然的排序可以用Sorted Sets來做帶權重的隊列,比如普通消息的score1,重要消息的score2,然後工作線程可以選擇按score的倒序來獲取工作任務。讓重要的任務優先執行。

常用方法

方法

說明

特性

zadd

zset中添加元素memberscore 用於排序,如果元素存在,則更新其順序,返回0代表沒添加成功

ZADD key score member

zadd myset 3 itim

zrange

取出集合中的元素

zrange myset 0 -1 withscores//顯示序號

by index

zrem

刪除名稱爲keyzset中的元素member

zrem myset itim

zincrby

修改元素的排序,如果元素不存在則添加該元素,且排序的score值爲增加值

zincrby myzset score itim

zrank

返回元素在集合中的排序位置,就是索引值

zrank myzset itim //itim在集合中的位置

zrevrank

返回從大到小的排序索引值,就是逆序位置

zrevrangk myzset itim//逆序的位置

zrevrange

返回集合中從大到小排序(降序)的,索引startend的所有元素

zrevrange myzset 0 -1 //逆序後的元素

zrangebyscore

根據排序索引的scores來返回元素

zrangebyscore myzset 1 3 withscores//

zcount

返回集合中給定區間的數量

zcount myzset 2 4 //集合中2-4索引元素的個數

zcard

返回集合中所有元素的個數

zcard myzset //返回所有元素的個數

zremrangebyrank

刪除集合中排序在給定區間的所有元素(按索引刪除)

zremrangebyrank myzset 2 3 //

zremrangebyscore

刪除集合中在給定排序區間的元素 (按順序刪除)

zremrangebyscore myzset 2 5 //

使用場景

排行榜應用,取TOP N操作

這個需求與上面需求的不同之處在於,前面操作以時間爲權重,這個是以某個條件爲權重,比如按頂的次數排序,這時候就需要我們的sorted set出馬了,將你要排序的值設置成sorted setscore,將具體的數據設置成相應的value,每次只需要執行一條ZADD命令即可。

//將登錄次數和用戶統一存儲在一個sorted set

zadd login:login_times 5 1

zadd login:login_times 1 2

zadd login:login_times 2 3

ZADD key score member

//當用戶登錄時,對該用戶的登錄次數自增1

ret = r.zincrby("login:login_times", 1, uid)

//那麼如何獲得登錄次數最多的用戶呢,逆序排列取得排名前N的用戶

ret = r.zrevrange("login:login_times", 0, N-1)

ZREVRANGE key start stop [WITHSCORES]

 

比如在線遊戲的排行榜,根據得分你通常想要:

         - 列出前100名高分選手

         - 列出某用戶當前的全球排名

    這些操作對於Redis來說小菜一碟,即使你有幾百萬個用戶,每分鐘都會有幾百萬個新的得分。

    模式是這樣的,每次獲得新得分時,我們用這樣的代碼:

    ZADD leaderboard <score> <username>

    你可能用userID來取代username,這取決於你是怎麼設計的。

    得到前100名高分用戶很簡單:ZREVRANGE leaderboard 0 99

用戶的全球排名也相似,只需要:ZRANK leaderboard <username>

ZRANK key member

Determine the index of a member in a sorted set

需要精準設定過期時間的應用

比如你可以把上面說到的sorted setscore值設置成過期時間的時間戳,那麼就可以簡單地通過過期時間排序,定時清除過期數據了,不僅是清除Redis中的過期數據,你完全可以把Redis裏這個過期時間當成是對數據庫中數據的索引,用Redis來找出哪些數據需要過期刪除,然後再精準地從數據庫中刪除相應的記錄。

範圍查找

比如:有一個IP範圍對應地址的列表,現在需要給出一個IP的情況下,迅速的查找到這個IP在哪個範圍,也就是要判斷此IP的所有地。

例如:查詢IP是否存在的問題;

ADSM,查詢IP是否在其他分組中存在。寫json文件

sadd向名稱爲keyset中添加元素,返回影響元素的個數,0爲失敗,1爲成功

例如:有下面兩個範圍,10203040

A_start 10, A_end 20

B_start 30, B_end 40

我們將這兩個範圍的起始位置存在RedisSorted Sets數據結構中,基本範圍起始值作爲score,範圍名加startend爲其value值:

redis 127.0.0.1:6379> zadd ranges 10 A_start

(integer) 1

redis 127.0.0.1:6379> zadd ranges 20 A_end

(integer) 1

redis 127.0.0.1:6379> zadd ranges 30 B_start

(integer) 1

redis 127.0.0.1:6379> zadd ranges 40 B_end

(integer) 1

這樣數據在插入Sorted Sets後,相當於是將這些起始位置按順序排列好了。

現在我需要查找15這個值在哪一個範圍中,只需要進行如下的zrangbyscore查找:

redis 127.0.0.1:6379> zrangebyscore ranges (15 +inf LIMIT 0 1

1) "A_end"

這個命令的意思是在Sorted Sets中查找大於15的第一個值。(+infRedis中表示正無窮大,15前面的括號表示>15而非>=15

查找的結果是A_end,由於所有值是按順序排列的,所以可以判定15是在A_startA_end區間上,也就是說15是在A這個範圍裏。至此大功告成。

當然,如果你查找到的是一個start,比如咱們用25,執行下面的命令

redis 127.0.0.1:6379> zrangebyscore ranges (25 +inf LIMIT 0 1

1) "B_start"

返回結果表明其下一個節點是一個start節點,也就是說25這個值不處在任何startend之間,不屬於任何範圍。

Pub/Sub

Pub/Sub 從字面上理解就是發佈(Publish)與訂閱(Subscribe),在Redis中,你可以設定對某一個key值進行消息發佈及消息訂閱,當一個key值上進行了消息發佈後,所有訂閱它的客戶端都會收到相應的消息。這一功能最明顯的用法就是用作實時消息系統,比如普通的即時聊天,羣聊等功能。

案例:

Qlocenter 下發策略

使用場景

Pub/Sub構建實時消息系統

RedisPub/Sub系統可以構建實時的消息系統

比如很多用Pub/Sub構建的實時聊天系統的例子。



不足之處 ,請指正!

發佈了64 篇原創文章 · 獲贊 61 · 訪問量 18萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章