Redis常見應用場景


Redis提供了非常豐富的數據結構,那么利用好每種數據結構變可提高web應用的訪問速度。

應用場景:

1.取最新N個數據的操作:(Linked List)

記錄前20個最新登陸的用戶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)

 2.取 TOP N 操作:(Sorted Set)

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

熱門,排行榜應用:

//將登錄次數和用戶統一存儲在一個sorted set里
zadd login:login_times 5 1
zadd login:login_times 1 2
zadd login:login_times 2 3
//當用戶登錄時,對該用戶的登錄次數自增1
ret = r.zincrby("login:login_times", 1, uid)
//那么如何獲得登錄次數最多的用戶呢,逆序排列取得排名前N的用戶
ret = r.zrevrange("login:login_times", 0, N-1)

3.查找某個值所在的區間(區間無重合) :(Sorted Set)

例如有下面兩個范圍,10-20和30-40

  • A_start 10, A_end 20
  • B_start 30, B_end 40

我們將這兩個范圍的起始位置存在Redis的Sorted Sets數據結構中,基本范圍起始值作為score,范圍名加start和end為其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的第一個值。(+inf在Redis中表示正無窮大,15前面的括號表示>15而非>=15)

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

4.交集,並集,差集:(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")

5.統計每天登陸過的活躍用戶:(bitmaps)

Redis支持對String類型的value進行基於二進制位的置位操作。通過將一個用戶的id對應value上的一位,通過對活躍用戶對應的位進行置位,就能夠用一個value記錄所有活躍用戶的信息。如下圖所未,下圖中的bitmap有9個位被置為1,表示這9個位上對應的用戶是今天的活躍用戶。其中第15位表示uid為15的用戶,第一位表示uid為0的用戶。

下面表格表示對應一天,一周,一個月統計時所花費的時間。

Period   Time(ms)
Daily   50.2
Weekly 392.0
Monthly 1624.8            

 

//下面是具體的java代碼片斷:
//1.算出一天的活躍用戶數量
import redis.clients.jedis.Jedis;
import java.util.BitSet;
...
  Jedis redis = new Jedis("localhost");
...
  public int uniqueCount(String action, String date) {
    String key = action + ":" + date;
    BitSet users = BitSet.valueOf(redis.get(key.getBytes()));
    return users.cardinality();
  } 
//2.計算某幾個內活躍用戶的數量(某一天活躍就算,所以是取並集)
import redis.clients.jedis.Jedis;
import java.util.BitSet;
...
  Jedis redis = new Jedis("localhost");
...
  public int uniqueCount(String action, String... dates) {
    BitSet all = new BitSet();
    for (String date : dates) {
      String key = action + ":" + date;
      BitSet users = BitSet.valueOf(redis.get(key.getBytes()));
      all.or(users);
    }
    return all.cardinality();
  }

 

 

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM