使用過Redis,那就先說說使用過那些場景吧
字串快取
//舉例
$redis->set(); $redis->get(); $redis->hset(); $redis->hget();
佇列
//舉例
$redis->rpush(); $redis->lpop(); $redis->lrange();
發布訂閱
//舉例
$redis->publish(); $redis->subscribe();
計數器
//舉例
$redis->set(); $redis->incr();
排行榜
//舉例
$redis->zadd(); $redis->zrevrange(); $redis->zrange();
集合間操作
//舉例
$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是哪個業務方,哪個開發創建的?這樣就可以找他溝通了,
嘗試解決問題的思路
一、先通過 keys * 命令,拿到所有的 key,然后根據 key 再獲取所有的內容,
優點:可以不使用 Redis 機器的硬碟,直接網路傳輸,
缺點:如果 key 資料特別多,keys 命令可能會直接導致 Redis 卡住,從而影響業務使用 或 對 Redis 請求太多次,資源消耗多,遍歷資料太慢,
二、開啟 aof,通過 aof 檔案獲取所有的資料,
優點:無需影響 Redis 服務,完全離線操作,足夠安全,
缺點:有一些 Redis 實體寫入頻繁,不適合開啟 aof,普適性不強;aof 檔案有可能特別大,傳輸、決議起來太慢,效率低,
三、使用 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濫用并無法進行監控的問題,
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/117792.html
標籤:PHP
下一篇:系統的講解 - PHP 快取技術
