Redis應用場景

本文主要介紹Redis的常用場景缀去,這都是由Redis的特性決定的履恩。并盡量從源碼角度說明Redis為什么適合于這種場景。

I倔既、積分排行榜

1锦茁、積分排行榜是Redis的經典應用,這是得益于Redis提供了zset的有序集合數(shù)據結構叉存。

2码俩、針對zset,Redis提供了一系列的命令:

ZADD: 添加新元素歼捏;
ZRANGE: 按分數(shù)從低到高返回給定排名區(qū)間的元素稿存;
ZREVRANGE: 按分數(shù)從高到底返回給定區(qū)間的元素;
ZRANK: 返回某個元素的排名瞳秽。

3瓣履、實現(xiàn):下面的例子為用python完成的一個leaderboard

# -*- coding: utf-8 -*-
#!/usr/bin/python
import redis
class Leaderboard:
    def __init__(self,host,port,key,db):
        self.host = host
        self.port = port
        self.key = key
        self.db = db
        self.r = redis.StrictRedis(host=self.host,port=self.port,db=self.db)
    def isRedisValid(self):
        return self.r is None
    def addMember(self,member,score):
        if self.isRedisValid():
            return None
        return self.r.zadd(self.key,score,member)
    def delMember(self,member):
        if self.isRedisValid():
            return None
        return self.r.zrem(self.key,member)
    def incrScore(self,member,increment):
        """increase score on specified member"""
        if self.isRedisValid():
            return None
        return self.r.zincrby(self.key,member,increment)
    def getRankByMember(self,member):
        """Get ranking by specified member."""
        if self.isRedisValid():
            return None
        return self.r.zrank(self.key,member)
    def getLeaderboard(self,start,stop,reverse,with_score):
        """Return the whole leaderboard."""
        if self.isRedisValid():
            return None
        return self.r.zrange(self.key,start,stop,reverse,with_score)
    def getLeaderboardByPage(self,item_per_page,page_num,reverse=False,with_score=False):
        """Return part of leaderboard configurably."""
        # fix parameters
        if item_per_page <= 0:
            item_per_page = 5
        if page_num <= 0:
            page_num = 1
        # note: it is possible that return value is empty list.
        return self.getLeaderboard((page_num-1)*item_per_page,
                                    page_num*item_per_page-1,
                                            reverse,with_score)
    def getWholeLeaderboard(self,reverse=False,with_score=False):
        """Return the whole leaderboard."""
        return self.getLeaderboard(0,-1,reverse,with_score)

II、分布式鎖

1练俐、我們通常所提到的鎖袖迎,一般都是在本地環(huán)境下對多線程完成互斥操作,而如果共享資源存在于網絡上腺晾,本地的鎖就不起作用了燕锥。
互斥訪問某個網絡資源的時候,需要有一個在網絡上的鎖服務器悯蝉,負責鎖的申請與回收归形,Redis就可以作為這種分布式鎖的服務器。

2鼻由、因為Redis是單進程單線程的工作模式暇榴,所以前來申請鎖資源的請求都被排隊處理,能保證鎖資源的同步訪問蕉世。

3蔼紧、實現(xiàn):可以在Redis服務器設置一個鍵值對,用以表示一把分布式互斥鎖狠轻,當申請鎖的時候奸例,申請方SET這個鍵值對,當釋放鎖的時候哈误,釋放方DEL這個鍵值對:

lock = redis.get("mutex_lock");
if(!lock)
    error("apply the lock error.");
else
    -- 確定可以申請鎖
    redis.set("mutex_lock","locking");
    do_something();

4哩至、上述的申請方法躏嚎,涉及到客戶端與Redis服務器的多次交互,當客戶端確定可以加鎖的時候菩貌,可能這時候鎖已經被其他客戶端申請了卢佣,最終導致兩個客戶端同時持有鎖。解決這個問題的方法就是將申請/釋放鎖的邏輯都放在服務器上箭阶。Redis Lua腳本可以完成這個問題:

-- apply for lock
local key = KEYS[1]
local res = redis.call('get', key)

-- 鎖被占用虚茶,申請失敗
if res == '0' then
return -1

-- 鎖可以被申請
else
local setres = redis.call('set', key, 0)
if setres['ok'] == 'OK' then
return 0
end
end
return -1

get 命令不成功返回(nil).
實驗命令:保存lua 腳本redis-cli script load ”$(cat mutex_lock.lua)”
-- releae lock
local key = KEYS[1]
local setres = redis.call('set', key, 1)
if setres['ok'] == 'OK' then
return 0
return -1

5、死鎖問題

分布式鎖由于客戶端的崩潰很容易造成鎖無法釋放仇参,從而出現(xiàn)死鎖嘹叫。所以需要使用Redis的TTL功能,設置超時釋放:

-- apply for lock
local key = KEYS[1]
local timeout = KEYS[2]

local res = redis.call('get', key)

-- 鎖被占用诈乒,申請失敗
if res == '0' then
return -1
-- 鎖可以被申請
else
local setres = redis.call('set', key, 0)
local exp_res = redis.call('pexpire', key, timeout)
if exp_res == 1 then
return 0
end
end
return -1

6罩扇、此外如出現(xiàn)服務器宕機,也會出現(xiàn)死鎖問題怕磨,這就需要slave服務器喂饥。

III、消息中間件

1肠鲫、消息中間件可以理解為分布式的消息隊列员帮。
消息中間件負責接收生產者的消息,并存儲轉發(fā)給對應的消費者导饲,生產者按照topic發(fā)布消息捞高,消費者按topic訂閱各種消息。生產者只需要向中間件中推送消息渣锦,不用等待消費者回應硝岗。

2、也就是說泡挺,這種分布式的消息中間件就是網絡上的一個服務器辈讶,起到一個數(shù)據中轉的功能命浴。

IV娄猫、Web服務器存儲session

1、以Redis作為session的存儲生闲,可以加速后臺的處理速度媳溺,如購物車數(shù)據,就不必直接存儲到磁盤數(shù)據庫中碍讯,在這里Redis的作用就是一個緩存悬蔽。

【參考】
[1] 《Redis源碼日志》

?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市捉兴,隨后出現(xiàn)的幾起案子蝎困,更是在濱河造成了極大的恐慌录语,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,734評論 6 505
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件禾乘,死亡現(xiàn)場離奇詭異澎埠,居然都是意外死亡,警方通過查閱死者的電腦和手機始藕,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,931評論 3 394
  • 文/潘曉璐 我一進店門蒲稳,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人伍派,你說我怎么就攤上這事江耀。” “怎么了诉植?”我有些...
    開封第一講書人閱讀 164,133評論 0 354
  • 文/不壞的土叔 我叫張陵祥国,是天一觀的道長。 經常有香客問我晾腔,道長系宫,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,532評論 1 293
  • 正文 為了忘掉前任建车,我火速辦了婚禮扩借,結果婚禮上,老公的妹妹穿的比我還像新娘缤至。我一直安慰自己潮罪,他們只是感情好,可當我...
    茶點故事閱讀 67,585評論 6 392
  • 文/花漫 我一把揭開白布领斥。 她就那樣靜靜地躺著嫉到,像睡著了一般。 火紅的嫁衣襯著肌膚如雪月洛。 梳的紋絲不亂的頭發(fā)上何恶,一...
    開封第一講書人閱讀 51,462評論 1 302
  • 那天,我揣著相機與錄音嚼黔,去河邊找鬼细层。 笑死,一個胖子當著我的面吹牛唬涧,可吹牛的內容都是我干的疫赎。 我是一名探鬼主播,決...
    沈念sama閱讀 40,262評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼碎节,長吁一口氣:“原來是場噩夢啊……” “哼捧搞!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 39,153評論 0 276
  • 序言:老撾萬榮一對情侶失蹤胎撇,失蹤者是張志新(化名)和其女友劉穎介粘,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體晚树,經...
    沈念sama閱讀 45,587評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡碗短,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 37,792評論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了题涨。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片偎谁。...
    茶點故事閱讀 39,919評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖纲堵,靈堂內的尸體忽然破棺而出巡雨,到底是詐尸還是另有隱情,我是刑警寧澤席函,帶...
    沈念sama閱讀 35,635評論 5 345
  • 正文 年R本政府宣布铐望,位于F島的核電站,受9級特大地震影響茂附,放射性物質發(fā)生泄漏正蛙。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,237評論 3 329
  • 文/蒙蒙 一营曼、第九天 我趴在偏房一處隱蔽的房頂上張望乒验。 院中可真熱鬧,春花似錦蒂阱、人聲如沸锻全。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,855評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽鳄厌。三九已至,卻和暖如春妈踊,著一層夾襖步出監(jiān)牢的瞬間了嚎,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,983評論 1 269
  • 我被黑心中介騙來泰國打工廊营, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留歪泳,地道東北人。 一個月前我還...
    沈念sama閱讀 48,048評論 3 370
  • 正文 我出身青樓赘风,卻偏偏與公主長得像夹囚,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子邀窃,可洞房花燭夜當晚...
    茶點故事閱讀 44,864評論 2 354

推薦閱讀更多精彩內容

  • Redis在很多方面與其他數(shù)據庫解決方案不同:它使用內存提供主存儲支持,而僅使用硬盤做持久性的存儲;它的數(shù)據模型非...
    全能程序猿閱讀 24,210評論 0 8
  • Spring Cloud為開發(fā)人員提供了快速構建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務發(fā)現(xiàn)瞬捕,斷路器鞍历,智...
    卡卡羅2017閱讀 134,656評論 18 139
  • string(字符串) 常用命令: set,get,decr,incr,mget 等。 使用SETBIT肪虎、GETB...
    陳小陌丿閱讀 965評論 0 3
  • 1. 取最新N個數(shù)據的操作 比如典型的取你網站的最新文章劣砍,通過下面方式,我們可以將最新的5000條評論的ID放在R...
    六月星空2011閱讀 502評論 0 1
  • 在英語的時態(tài)中有一個進行時還有一個完成時扇救,其實想來應該還有一個正在適應時刑枝,當你進入一個全新的領域,必然需要一個適應...
    怡兒話書影閱讀 297評論 0 0