Redis數據過期和淘汰策略詳解
背景
Redis作為一個高性能的內存NoSQL數據庫,其容量受到最大內存限制的限制。
用戶在使用阿里雲Redis時,除了對性能,穩定性有很高的要求外,對內存佔用也比較敏感。在使用過程中,有些用戶會覺得自己的線上實例內存佔用比自己預想的要大。
事實上,實例中的內存除了保存原始的鍵值對所需的開銷外,還有一些運行時產生的額外內存,包括:
垃圾數據和過期Key所佔空間
字典漸進式Rehash導致未及時刪除的空間
Redis管理數據,包括底層數據結構開銷,客戶端信息,讀寫緩衝區等
主從複製,bgsave時的額外開銷
其它
本系列文章主要分析這些在Redis中產生的原因,帶來的影響和規避的方式。
本文主要分析第一項Redis過期策略對內存的影響。
Redis過期數據清理策略
過期數據清理時機
為了防止一次性清理大量過期Key導致Redis服務受影響,Redis只在空閒時清理過期Key。
具體Redis逐出過期Key的時機為:
訪問Key時,會判斷Key是否過期,逐出過期Key;
背景
Redis作為一個高性能的內存NoSQL數據庫,其容量受到最大內存限制的限制。
用戶在使用阿里雲Redis時,除了對性能,穩定性有很高的要求外,對內存佔用也比較敏感。在使用過程中,有些用戶會覺得自己的線上實例內存佔用比自己預想的要大。
事實上,實例中的內存除了保存原始的鍵值對所需的開銷外,還有一些運行時產生的額外內存,包括:
垃圾數據和過期Key所佔空間
字典漸進式Rehash導致未及時刪除的空間
Redis管理數據,包括底層數據結構開銷,客戶端信息,讀寫緩衝區等
主從複製,bgsave時的額外開銷
其它
本系列文章主要分析這些在Redis中產生的原因,帶來的影響和規避的方式。
本文主要分析第一項Redis過期策略對內存的影響。
Redis過期數據清理策略
過期數據清理時機
為了防止一次性清理大量過期Key導致Redis服務受影響,Redis只在空閒時清理過期Key。
具體Redis逐出過期Key的時機為:
訪問Key時,會判斷Key是否過期,逐出過期Key;
2. CPU空閒時在定期serverCron任務中,逐出部分過期Key;
背景
Redis作為一個高性能的內存NoSQL數據庫,其容量受到最大內存限制的限制。
用戶在使用阿里雲Redis時,除了對性能,穩定性有很高的要求外,對內存佔用也比較敏感。在使用過程中,有些用戶會覺得自己的線上實例內存佔用比自己預想的要大。
事實上,實例中的內存除了保存原始的鍵值對所需的開銷外,還有一些運行時產生的額外內存,包括:
垃圾數據和過期Key所佔空間
字典漸進式Rehash導致未及時刪除的空間
Redis管理數據,包括底層數據結構開銷,客戶端信息,讀寫緩衝區等
主從複製,bgsave時的額外開銷
其它
本系列文章主要分析這些在Redis中產生的原因,帶來的影響和規避的方式。
本文主要分析第一項Redis過期策略對內存的影響。
Redis過期數據清理策略
過期數據清理時機
為了防止一次性清理大量過期Key導致Redis服務受影響,Redis只在空閒時清理過期Key。
具體Redis逐出過期Key的時機為:
訪問Key時,會判斷Key是否過期,逐出過期Key;
2. CPU空閒時在定期serverCron任務中,逐出部分過期Key;
3.每次事件循環執行的時候,逐出部分過期Key;
背景
Redis作為一個高性能的內存NoSQL數據庫,其容量受到最大內存限制的限制。
用戶在使用阿里雲Redis時,除了對性能,穩定性有很高的要求外,對內存佔用也比較敏感。在使用過程中,有些用戶會覺得自己的線上實例內存佔用比自己預想的要大。
事實上,實例中的內存除了保存原始的鍵值對所需的開銷外,還有一些運行時產生的額外內存,包括:
垃圾數據和過期Key所佔空間
字典漸進式Rehash導致未及時刪除的空間
Redis管理數據,包括底層數據結構開銷,客戶端信息,讀寫緩衝區等
主從複製,bgsave時的額外開銷
其它
本系列文章主要分析這些在Redis中產生的原因,帶來的影響和規避的方式。
本文主要分析第一項Redis過期策略對內存的影響。
Redis過期數據清理策略
過期數據清理時機
為了防止一次性清理大量過期Key導致Redis服務受影響,Redis只在空閒時清理過期Key。
具體Redis逐出過期Key的時機為:
訪問Key時,會判斷Key是否過期,逐出過期Key;
2. CPU空閒時在定期serverCron任務中,逐出部分過期Key;
3.每次事件循環執行的時候,逐出部分過期Key;
過期數據清理算法
Redis過期Key清理的機制對清理的頻率和最大時間都有限制,在儘量不影響正常服務的情況下,進行過期Key的清理,以達到長時間服務的性能最優.
Redis會週期性的隨機測試一批設置了過期時間的key並進行處理。測試到的已過期的key將被刪除。具體的算法如下:
Redis配置項hz定義了serverCron任務的執行週期,默認為10,即CPU空閒時每秒執行10次;
每次過期key清理的時間不超過CPU時間的25%,即若hz=1,則一次清理時間最大為250ms,若hz=10,則一次清理時間最大為25ms;
清理時依次遍歷所有的db;
從db中隨機取20個key,判斷是否過期,若過期,則逐出;
若有5個以上key過期,則重複步驟4,否則遍歷下一個db;
在清理過程中,若達到了25%CPU時間,退出清理過程;
這是一個基於概率的簡單算法,基本的假設是抽出的樣本能夠代表整個key空間,redis持續清理過期的數據直至將要過期的key的百分比降到了25%以下。這也意味著在長期來看任何給定的時刻已經過期但仍佔據著內存空間的key的量最多為每秒的寫操作量除以4.
由於算法採用的隨機取key判斷是否過期的方式,故幾乎不可能清理完所有的過期Key;
調高hz參數可以提升清理的頻率,過期key可以更及時的被刪除,但hz太高會增加CPU時間的消耗;Redis作者關於hz參數的一些討論
代碼分析如下:
背景
Redis作為一個高性能的內存NoSQL數據庫,其容量受到最大內存限制的限制。
用戶在使用阿里雲Redis時,除了對性能,穩定性有很高的要求外,對內存佔用也比較敏感。在使用過程中,有些用戶會覺得自己的線上實例內存佔用比自己預想的要大。
事實上,實例中的內存除了保存原始的鍵值對所需的開銷外,還有一些運行時產生的額外內存,包括:
垃圾數據和過期Key所佔空間
字典漸進式Rehash導致未及時刪除的空間
Redis管理數據,包括底層數據結構開銷,客戶端信息,讀寫緩衝區等
主從複製,bgsave時的額外開銷
其它
本系列文章主要分析這些在Redis中產生的原因,帶來的影響和規避的方式。
本文主要分析第一項Redis過期策略對內存的影響。
Redis過期數據清理策略
過期數據清理時機
為了防止一次性清理大量過期Key導致Redis服務受影響,Redis只在空閒時清理過期Key。
具體Redis逐出過期Key的時機為:
訪問Key時,會判斷Key是否過期,逐出過期Key;
2. CPU空閒時在定期serverCron任務中,逐出部分過期Key;
3.每次事件循環執行的時候,逐出部分過期Key;
過期數據清理算法
Redis過期Key清理的機制對清理的頻率和最大時間都有限制,在儘量不影響正常服務的情況下,進行過期Key的清理,以達到長時間服務的性能最優.
Redis會週期性的隨機測試一批設置了過期時間的key並進行處理。測試到的已過期的key將被刪除。具體的算法如下:
Redis配置項hz定義了serverCron任務的執行週期,默認為10,即CPU空閒時每秒執行10次;
每次過期key清理的時間不超過CPU時間的25%,即若hz=1,則一次清理時間最大為250ms,若hz=10,則一次清理時間最大為25ms;
清理時依次遍歷所有的db;
從db中隨機取20個key,判斷是否過期,若過期,則逐出;
若有5個以上key過期,則重複步驟4,否則遍歷下一個db;
在清理過程中,若達到了25%CPU時間,退出清理過程;
這是一個基於概率的簡單算法,基本的假設是抽出的樣本能夠代表整個key空間,redis持續清理過期的數據直至將要過期的key的百分比降到了25%以下。這也意味著在長期來看任何給定的時刻已經過期但仍佔據著內存空間的key的量最多為每秒的寫操作量除以4.
由於算法採用的隨機取key判斷是否過期的方式,故幾乎不可能清理完所有的過期Key;
調高hz參數可以提升清理的頻率,過期key可以更及時的被刪除,但hz太高會增加CPU時間的消耗;Redis作者關於hz參數的一些討論
代碼分析如下:
Redis數據逐出策略
數據逐出時機
背景
Redis作為一個高性能的內存NoSQL數據庫,其容量受到最大內存限制的限制。
用戶在使用阿里雲Redis時,除了對性能,穩定性有很高的要求外,對內存佔用也比較敏感。在使用過程中,有些用戶會覺得自己的線上實例內存佔用比自己預想的要大。
事實上,實例中的內存除了保存原始的鍵值對所需的開銷外,還有一些運行時產生的額外內存,包括:
垃圾數據和過期Key所佔空間
字典漸進式Rehash導致未及時刪除的空間
Redis管理數據,包括底層數據結構開銷,客戶端信息,讀寫緩衝區等
主從複製,bgsave時的額外開銷
其它
本系列文章主要分析這些在Redis中產生的原因,帶來的影響和規避的方式。
本文主要分析第一項Redis過期策略對內存的影響。
Redis過期數據清理策略
過期數據清理時機
為了防止一次性清理大量過期Key導致Redis服務受影響,Redis只在空閒時清理過期Key。
具體Redis逐出過期Key的時機為:
訪問Key時,會判斷Key是否過期,逐出過期Key;
2. CPU空閒時在定期serverCron任務中,逐出部分過期Key;
3.每次事件循環執行的時候,逐出部分過期Key;
過期數據清理算法
Redis過期Key清理的機制對清理的頻率和最大時間都有限制,在儘量不影響正常服務的情況下,進行過期Key的清理,以達到長時間服務的性能最優.
Redis會週期性的隨機測試一批設置了過期時間的key並進行處理。測試到的已過期的key將被刪除。具體的算法如下:
Redis配置項hz定義了serverCron任務的執行週期,默認為10,即CPU空閒時每秒執行10次;
每次過期key清理的時間不超過CPU時間的25%,即若hz=1,則一次清理時間最大為250ms,若hz=10,則一次清理時間最大為25ms;
清理時依次遍歷所有的db;
從db中隨機取20個key,判斷是否過期,若過期,則逐出;
若有5個以上key過期,則重複步驟4,否則遍歷下一個db;
在清理過程中,若達到了25%CPU時間,退出清理過程;
這是一個基於概率的簡單算法,基本的假設是抽出的樣本能夠代表整個key空間,redis持續清理過期的數據直至將要過期的key的百分比降到了25%以下。這也意味著在長期來看任何給定的時刻已經過期但仍佔據著內存空間的key的量最多為每秒的寫操作量除以4.
由於算法採用的隨機取key判斷是否過期的方式,故幾乎不可能清理完所有的過期Key;
調高hz參數可以提升清理的頻率,過期key可以更及時的被刪除,但hz太高會增加CPU時間的消耗;Redis作者關於hz參數的一些討論
代碼分析如下:
Redis數據逐出策略
數據逐出時機
數據逐出算法
在逐出算法中,根據用戶設置的逐出策略,選出待逐出的key,直到當前內存小於最大內存值為主.
可選逐出策略如下:
volatile-lru:從已設置過期時間的數據集(server.db[i].expires)中挑選最近最少使用 的數據淘汰
volatile-ttl:從已設置過期時間的數據集(server.db[i].expires)中挑選將要過期的數 據淘汰
volatile-random:從已設置過期時間的數據集(server.db[i].expires)中任意選擇數據 淘汰
allkeys-lru:從數據集(server.db[i].dict)中挑選最近最少使用的數據淘汰
allkeys-random:從數據集(server.db[i].dict)中任意選擇數據淘汰
no-enviction(驅逐):禁止驅逐數據
具體代碼如下
背景
Redis作為一個高性能的內存NoSQL數據庫,其容量受到最大內存限制的限制。
用戶在使用阿里雲Redis時,除了對性能,穩定性有很高的要求外,對內存佔用也比較敏感。在使用過程中,有些用戶會覺得自己的線上實例內存佔用比自己預想的要大。
事實上,實例中的內存除了保存原始的鍵值對所需的開銷外,還有一些運行時產生的額外內存,包括:
垃圾數據和過期Key所佔空間
字典漸進式Rehash導致未及時刪除的空間
Redis管理數據,包括底層數據結構開銷,客戶端信息,讀寫緩衝區等
主從複製,bgsave時的額外開銷
其它
本系列文章主要分析這些在Redis中產生的原因,帶來的影響和規避的方式。
本文主要分析第一項Redis過期策略對內存的影響。
Redis過期數據清理策略
過期數據清理時機
為了防止一次性清理大量過期Key導致Redis服務受影響,Redis只在空閒時清理過期Key。
具體Redis逐出過期Key的時機為:
訪問Key時,會判斷Key是否過期,逐出過期Key;
2. CPU空閒時在定期serverCron任務中,逐出部分過期Key;
3.每次事件循環執行的時候,逐出部分過期Key;
過期數據清理算法
Redis過期Key清理的機制對清理的頻率和最大時間都有限制,在儘量不影響正常服務的情況下,進行過期Key的清理,以達到長時間服務的性能最優.
Redis會週期性的隨機測試一批設置了過期時間的key並進行處理。測試到的已過期的key將被刪除。具體的算法如下:
Redis配置項hz定義了serverCron任務的執行週期,默認為10,即CPU空閒時每秒執行10次;
每次過期key清理的時間不超過CPU時間的25%,即若hz=1,則一次清理時間最大為250ms,若hz=10,則一次清理時間最大為25ms;
清理時依次遍歷所有的db;
從db中隨機取20個key,判斷是否過期,若過期,則逐出;
若有5個以上key過期,則重複步驟4,否則遍歷下一個db;
在清理過程中,若達到了25%CPU時間,退出清理過程;
這是一個基於概率的簡單算法,基本的假設是抽出的樣本能夠代表整個key空間,redis持續清理過期的數據直至將要過期的key的百分比降到了25%以下。這也意味著在長期來看任何給定的時刻已經過期但仍佔據著內存空間的key的量最多為每秒的寫操作量除以4.
由於算法採用的隨機取key判斷是否過期的方式,故幾乎不可能清理完所有的過期Key;
調高hz參數可以提升清理的頻率,過期key可以更及時的被刪除,但hz太高會增加CPU時間的消耗;Redis作者關於hz參數的一些討論
代碼分析如下:
Redis數據逐出策略
數據逐出時機
數據逐出算法
在逐出算法中,根據用戶設置的逐出策略,選出待逐出的key,直到當前內存小於最大內存值為主.
可選逐出策略如下:
volatile-lru:從已設置過期時間的數據集(server.db[i].expires)中挑選最近最少使用 的數據淘汰
volatile-ttl:從已設置過期時間的數據集(server.db[i].expires)中挑選將要過期的數 據淘汰
volatile-random:從已設置過期時間的數據集(server.db[i].expires)中任意選擇數據 淘汰
allkeys-lru:從數據集(server.db[i].dict)中挑選最近最少使用的數據淘汰
allkeys-random:從數據集(server.db[i].dict)中任意選擇數據淘汰
no-enviction(驅逐):禁止驅逐數據
具體代碼如下
相關最佳實踐
不要放垃圾數據,及時清理無用數據
實驗性的數據和下線的業務數據及時刪除;
key儘量都設置過期時間
對具有時效性的key設置過期時間,通過redis自身的過期key清理策略來降低過期key對於內存的佔用,同時也能夠減少業務的麻煩,不需要定期手動清理了.
單Key不要過大
給用戶排查問題時遇到過單個string的value有43M的,也有一個list 100多萬個大成員佔了1G多內存的。這種key在get的時候網絡傳輸延遲會比較大,需要分配的輸出緩衝區也比較大,在定期清理的時候也容易造成比較高的延遲. 最好能通過業務拆分,數據壓縮等方式避免這種過大的key的產生。
不同業務如果公用一個業務的話,最好使用不同的邏輯db分開
從上面的分析可以看出,Redis的過期Key清理策略和強制淘汰策略都會遍歷各個db。將key分佈在不同的db有助於過期Key的及時清理。另外不同業務使用不同db也有助於問題排查和無用數據的及時下線.