使用過Redis,我居然還不知道Rdb

使用過Redis,那就先說說使用過那些場景吧
字符串緩存

//舉例php

$redis->set();
$redis->get();
$redis->hset();
$redis->hget();

 


隊列

//舉例git

$redis->rpush();
$redis->lpop();
$redis->lrange();

 


發佈訂閱

//舉例github

$redis->publish();
$redis->subscribe();

 


計數器

//舉例redis

$redis->set();
$redis->incr();

 


排行榜

//舉例數據庫

$redis->zadd();
$redis->zrevrange();
$redis->zrange();

 


集合間操做

//舉例vim

$redis->sadd();
$redis->spop();
$redis->sinter();
$redis->sunion();
$redis->sdiff();

 


悲觀鎖

解釋:悲觀鎖(Pessimistic Lock), 顧名思義,就是很悲觀。

每次去拿數據的時候都認爲別人會修改,因此每次在拿數據的時候都會上鎖。

場景:若是項目中使用了緩存且對緩存設置了超時時間。

當併發量比較大的時候,若是沒有鎖機制,那麼緩存過時的瞬間,

大量併發請求會穿透緩存直接查詢數據庫,形成雪崩效應。

緩存

/**
 * 獲取鎖
 * @param  String  $key    鎖標識
 * @param  Int     $expire 鎖過時時間
 * @return Boolean
 */
public function lock($key = '', $expire = 5) {
    $is_lock = $this->_redis->setnx($key, time()+$expire);
    //不能獲取鎖
    if(!$is_lock){
        //判斷鎖是否過時
        $lock_time = $this->_redis->get($key);
        //鎖已過時,刪除鎖,從新獲取
        if (time() > $lock_time) {
            unlock($key);
            $is_lock = $this->_redis->setnx($key, time() + $expire);
        }
    }

    return $is_lock? true : false;
}

/**
 * 釋放鎖
 * @param  String  $key 鎖標識
 * @return Boolean
 */
public function unlock($key = ''){
    return $this->_redis->del($key);
}

// 定義鎖標識
$key = 'test_lock';

// 獲取鎖
$is_lock = lock($key, 10);
if ($is_lock) {
    echo 'get lock success<br>';
    echo 'do sth..<br>';
    sleep(5);
    echo 'success<br>';
    unlock($key);
} else { //獲取鎖失敗
    echo 'request too frequently<br>';
}

 

樂觀鎖

解釋:樂觀鎖(Optimistic Lock), 顧名思義,就是很樂觀。

每次去拿數據的時候都認爲別人不會修改,因此不會上鎖。

watch命令會監視給定的key,當exec時候若是監視的key從調用watch後發生過變化,則整個事務會失敗。

也能夠調用watch屢次監視多個key。這樣就能夠對指定的key加樂觀鎖了。

注意watch的key是對整個鏈接有效的,事務也同樣。

若是鏈接斷開,監視和事務都會被自動清除。

固然了exec,discard,unwatch命令都會清除鏈接中的全部監視。

安全

$strKey = 'test_age';

$redis->set($strKey,10);

$age = $redis->get($strKey);

echo "---- Current Age:{$age} ---- <br/><br/>";

$redis->watch($strKey);

// 開啓事務
$redis->multi();

//在這個時候新開了一個新會話執行
$redis->set($strKey,30);  //新會話

echo "---- Current Age:{$age} ---- <br/><br/>"; //30

$redis->set($strKey,20);

$redis->exec();

$age = $redis->get($strKey);

echo "---- Current Age:{$age} ---- <br/><br/>"; //30

//當exec時候若是監視的key從調用watch後發生過變化,則整個事務會失敗

上面的一些場景,我們大部分都使用過,卻尚未說起到Rdb文件。

「對吧,使用過Redis,殊不知道Rdb文件,你中槍了嗎?」
Rdb文件是什麼,它是幹什麼的

Redis 做爲互聯網產品開發中不可缺乏的常備武器,它性能高、數據結構豐富、簡單易用,但同時也是由於太容易用了,無論什麼數據、無論這數據有多大、無論數據有多少,統統塞進去,最後致使的問題就是 Redis 內存使用持續上升,可是又不知道里面的數據是否是有用,是否能夠拆分和清理,最可怕的是服務器發生宕機後,Redis 數據庫裏的全部數據將會所有丟失。

好比當內存上升,性能慢時,咱們進行性能調優的時候,咱們想知道:

    哪些Key佔用了大量的內存?
    想知道每一個Key的佔用空間?
    想知道佔用空間大的Key都存了啥?
    想知道佔用空間大的Key的重要性,當性能慢的時候是否能夠立刻刪除?
    更想知道這些Key是哪一個業務方,哪一個開發建立的?這樣就能夠找他溝通了。

嘗試解決問題的思路

1、先經過 keys * 命令,拿到全部的 key,而後根據 key 再獲取全部的內容。

    優勢:能夠不使用 Redis 機器的硬盤,直接網絡傳輸。
    缺點:若是 key 數據特別多,keys 命令可能會直接致使 Redis 卡住,從而影響業務使用 或 對 Redis 請求太屢次,資源消耗多,遍歷數據太慢。

2、開啓 aof,經過 aof 文件獲取全部的數據。

    優勢:無需影響 Redis 服務,徹底離線操做,足夠安全。
    缺點:有一些 Redis 實例寫入頻繁,不適合開啓 aof,普適性不強;aof 文件有可能特別大,傳輸、解析起來太慢,效率低。

3、使用 bgsave,獲取 rdb 文件,解析後獲取數據。

    優勢:機制成熟,可靠性好;文件相對小,傳輸、解析效率高。
    缺點:bgsave 雖然會 fork 子進程,但仍是有可能致使主進程卡住一段時間,對業務有產生影響的風險。

綜合評估後,決定採用低峯期在從節點作 bgsave 獲取 rdb 文件,相對安全可靠,也能夠覆蓋全部業務的 Redis 集羣。

也就是說每一個實例天天在低峯期自動生成一個 .rdb 文件,即便報表數據有一天的延遲也是能夠接受的。

「哦,原來.rdb文件是磁盤的緩存文件,那麼如何開啓持久化呢?」

下面簡單的介紹下,Redis 的持久化。

Redis 支持兩種方式的持久化,一種是RDB方式,一種是AOF方式。

RDB 是 Redis 用來進行持久化的一種方式,是把當前內存中的數據集,快照寫入磁盤。
RDB - 自動

RDB(Redis DataBase)方式是經過快照完成的,當符合必定條件時Redis會自動將內存中的全部數據進行快照,而且存儲到硬盤上,RDB是Redis的默認持久化方式。服務器

vim /usr/local/redis/conf/redis.conf

save 900 1    #15分鐘內有至少1個鍵被更改
save 300 10   #5分鐘內至少有10個鍵被更改
save 60 1000  #1分鐘內至少有10000個鍵被更改

#以上條件都是或的關係,當知足其一就會進行快照。

dbfilename "dump.rdb"       #持久化文件名稱
dir "/data/dbs/redis/6381"  #持久化數據文件存放的路徑

#配置文件修改後,須要重啓redis服務。

 

這裏我還準備了一分學習圖和資料,以下:網絡

連接:https://pan.baidu.com/s/1v5gm7n0L7TGyejCmQrMh2g 提取碼:x2p5

免費分享,可是X度限制嚴重,如若連接失效點擊連接或搜索加羣 羣號518475424


還能夠經過命令行的方式進行配置:

CONFIG GET save    #查看redis持久化配置

CONFIG SET save "100 20" #修改redis持久化配置

#使用命令行的方式配置,即時生效,服務器重啓後須要從新配置。

 

RDB - 手動

    save

該命令會阻塞當前Redis服務器,執行save命令期間,Redis不能處理其餘命令,直到RDB過程完成爲止。

顯然該命令對於內存比較大的實例會形成長時間阻塞,這是致命的缺陷。

    bgsave

執行該命令時,Redis會在後臺異步進行快照操做,快照同時還能夠響應客戶端請求。

具體操做是Redis進程執行fork操做建立子進程,RDB持久化過程由子進程負責,完成後自動結束。阻塞只發生在fork階段。
AOF

AOF(APPEND ONLY MODE)是經過保存對redis服務端的寫命令(如set、sadd、rpush)來記錄數據庫狀態的,即保存你對redis數據庫的寫操做。

配置日誌文件以下:

vim /usr/local/redis/conf/redis.conf
dir "/data/dbs/redis/6381"           #AOF文件存放目錄
appendonly yes                       #開啓AOF持久化,默認關閉
appendfilename "appendonly.aof"      #AOF文件名稱(默認)
appendfsync no                       #AOF持久化策略
auto-aof-rewrite-percentage 100      #觸發AOF文件重寫的條件(默認)
auto-aof-rewrite-min-size 64mb       #觸發AOF文件重寫的條件(默認)

#上面的每一個參數,能夠找資料瞭解下,不作多解釋了。

 RDB 與 AOF 的優缺點,見上面的便可。至此,咱們瞭解了 Redis 持久化的一些配置,裏面的細節建議查詢相關資料進行研究。接下來繼續,經過上一步咱們拿到了 rdb 文件,就至關於拿到了Redis實例的數據。    解析 rdb 文件,獲取key和value的值。    根據相應的數據結構及內容,估算內存消耗。    統計並生成報表。分析工具    雪球 rdr:https://github.com/xueqiu/rdr    redis-rdb-tools:https://github.com/sripathikrishnan/redis-rdb-tools小結    講解了工做中經常使用的 redis 使用場景。    講解了 redis 持久化的兩個方式(RDB、AOF)。    推薦了兩個分析rdb的工具。經過對 redis 的使用 到 瞭解到服務器上如何對redis數據作持久化快照,再到如何利用工具進行分析rdb文件,最後經過分析後的數據,能夠反過來對 redis 的使用提出一些建議。其餘知識點也是這樣,咱們不能只停留在方法的簡單調用,就以爲理解了這門技術!聯想其實上面分析出來的數據,是不可能定位到這個key是哪一個業務方的,哪一個開發建立的,是否重要等等,那咱們應該怎麼作呢?    制定開發團隊的Redis Key的使用規範,經過key的命名能夠獲得:        屬於什麼業務(加域名錶示)        屬於什麼數據類型(加數據類型標示)        是否設置過時時間        …    統一平臺進行Redis Key的申請,只有申請了才能進行使用:        填寫申請人        填寫申請時間        填寫申請業務方        填寫數據類型        填寫Key的重要性        填寫Key是否存在過時時間        根據填寫項生成規範的key名稱        …(等等須要標記的)    上面咱們已經能分析出某個redis實例rdb文件的內容,經過分析出來的內容 與 統一平臺申請的數據,進行整合,分析key的合格率、內存使用量、不一樣數據類型的分佈、內存佔用量Top 100的值 等等。    咱們能夠經過運維瞭解到,每一個服務器與實例之間的配置關係,就能夠了解到某臺服務器(N個實例)上的 key的合格率、內存使用量、不一樣數據類型的分佈、內存佔用量Top 100的值等等。這樣,在後臺系統中就能夠看到哪臺服務器,哪一個實例的使用狀況,解決了Redis濫用並沒有法進行監控的問題。

相關文章
相關標籤/搜索