Redis細節積累

2021-09-01 01:56:53 字數 2158 閱讀 8058

redis細節積累

一、優點

二、缺點

三、redis複製缺陷的解決方案

我們可以採用主動複製的方式來搭建我們的集群環境,所謂主動複製是指由業務端或者通過**中介軟體對redis儲存的資料進行雙寫或多寫,通過資料的多份儲存來達到與複製相同的目的。但是會造成資料一致性問題,這樣需要看專案的應用場景是否對資料一致性要求高不高

resharding的方案來解決動態擴容和資料分割槽的問題,實際就是在同一臺機器上部署多個redis例項的方式,當容量不夠時將多個例項拆分到不同的機器上,這樣實際就達到了擴容的效果。但是實際還是依賴redis的複製功能,所以做這個拆分的過程最好選擇為業務訪問低峰時段進行。

首先寫redis的aof檔案,並對這個aof檔案按檔案大小進行自動分割滾動,同時關閉redis的rewrite命令,然後會在業務低峰時間進行記憶體 快照儲存,並把當前的aof檔案位置一起寫入到快照檔案中,這樣我們可以使快照檔案與aof檔案的位置保持一致性,這樣我們得到了系統某一時刻的記憶體快 照,並且同時也能知道這一時刻對應的aof檔案的位置,那麼當從庫傳送同步命令時,我們首先會把快照檔案傳送給從庫,然後從庫會取出該快照檔案中儲存的 aof檔案位置,並將該位置發給主庫,主庫會隨後傳送該位置之後的所有命令,以後的複製就都是這個位置之後的增量資訊了。

四、記憶體優化

hash-max-zipmap-entries 64 

hash-max-zipmap-value 512

hash-max-zipmap-entries

當value這個map內部不超過多少個成員時會採用線性緊湊格式儲存,預設是64,即value內部有64個以下的成員就是使用線性緊湊儲存,超過該值自動轉成真正的hashmap。

hash-max-zipmap-value 含義是當 value這個map內部的每個成員值長度不超過多少位元組就會採用線性緊湊儲存來節省空間。

以上2個條件任意乙個條件超過設定值都會轉換成真正的hashmap,也就不會再節省記憶體了,那麼這個值是不是設定的越大越好呢,答案當然是否定 的,hashmap的優勢就是查詢和操作的時間複雜度都是o(1)的,而放棄hash採用一維儲存則是o(n)的時間複雜度,如果成員數量很少,則影響不大,否則會嚴重影響效能,所以要權衡好這個值的設定,總體上還是最根本的時間成本和空間成本上的權衡。

同理list:

list-max-ziplist-entries 512

set-max-intset-entries 512

不過如果在redis內部儲存的大部分資料是數值型的話,redis內部採用了乙個shared integer的方式來省去分配記憶體的開銷,即在系統啟動時先分配乙個從1~n 那麼多個數值物件放在乙個池子中,如果儲存的資料恰好是這個數值範圍內的資料,則直接從池子裡取出該物件,並且通過引用計數的方式來共享,這樣在系統儲存 了大量數值下,也能一定程度上節省記憶體並且提高效能,這個引數值n的設定需要修改源**中的一行巨集定義redis_shared_integers,該值 預設是10000,可以根據自己的需要進行修改,修改後重新編譯就可以了。

有redis線上運維經驗的人會發現redis在物理記憶體使用比較多,但還沒有超過實際物理記憶體總容量時就會發生不穩定甚至崩潰的問題,有人認為是 基於快照方式持久化的fork系統呼叫造成記憶體占用加倍而導致的,這種觀點是不準確的,因為fork 呼叫的copy-on-write機制是基於作業系統頁這個單位的,也就是只有有寫入的髒頁會被複製,但是一般你的系統不會在短時間內所有的頁都發生了寫 入而導致複製,那麼是什麼原因導致redis崩潰的呢?

答案是redis的持久化使用了buffer io造成的,所謂buffer io是指redis對持久化檔案的寫入和讀取操作都會使用物理記憶體的page cache,而大多數資料庫系統會使用direct io來繞過這層page cache並自行維護乙個資料的cache,而當redis的持久化檔案過大(尤其是快照檔案),並對其進行讀寫時,磁碟檔案中的資料都會被載入到物理內 存中作為作業系統對該檔案的一層cache,而這層cache的資料與redis記憶體中管理的資料實際是重複儲存的,雖然核心在物理記憶體緊張時會做 page cache的剔除工作,但核心很可能認為某塊page cache更重要,而讓你的程序開始swap ,這時你的系統就會開始出現不穩定或者崩潰了。我們的經驗是當你的redis物理記憶體使用超過記憶體總容量的3/5時就會開始比較危險了。

shell中的細節積累一

1.shell的noglob設定 寫shell指令碼時遇到乙個問題,tmp echo tmp 期望的結果是輸出 但是最終的輸出結果都是當前目錄的所有檔名 將 號進行了轉義 如何不對特殊符號進行轉義呢,設定noglob 設定noglob後,等一些其他的特殊字元便會失去特定的功能,恢復成乙個簡單的字元 ...

Redis命令小細節

set 將字串 value的值關聯到key 如果key已經存在,那麼覆蓋原來的,如果不存在,那麼就建立 setnx 將key的值設定為value,當且僅當key不存在的時候,如果key已經存在,是設定不成功的。setex是設定乙個帶生存期限的key,通過下面,我們可以發現,setex的引數順序是,k...

Redis命令小細節

set 將字串 value的值關聯到key 如果key已經存在,那麼覆蓋原來的,如果不存在,那麼就建立 setnx 將key的值設定為value,當且僅當key不存在的時候,如果key已經存在,是設定不成功的。setex是設定乙個帶生存期限的key,通過下面,我們可以發現,setex的引數順序是,k...