亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 數據庫 > Redis > 正文

Redis 2.8-4.0過期鍵優化過程全紀錄

2020-10-28 21:30:39
字體:
來源:轉載
供稿:網友

前言

之前 白馨(陌陌-技術保障部存儲工程師 )在Redis技術交流群里,總結了一下Redis從2.8~4.0關于過期鍵相關的fix記錄,非常有幫助,但有些東西未盡詳細,本文將進行詳細說明。

先從一個問題來看,運行環境如下:

Redis: 2.8.19
db0:keys=10000000,expires=10000000
主從結構

從下圖中可以看到,在從節點get hello非空,在主節點get hello為空,之后從節點get hello為空,經排查主從同步offset基本正常,但出現了主從不一致。

原因先不說,本文來探討下Redis2.8-4.0版本迭代中,針對過期鍵的fix,看看能不能找到答案。

一、過期功能回顧

當你執行了一條setex命令后,Redis會向內部的dict和expires哈希結構中分別插入數據:

dict------dict[key]:valueexpires---expires[key]:timeout

例如:

127.0.0.1:6379> setex hello 120 worldOK127.0.0.1:6379> info# 該數據庫中設置為過期鍵并且未被刪除的總量(如果曾設置為過期鍵且刪除則不計入)db0:keys=1,expires=1,avg_ttl=41989# 歷史上每一次刪除過期鍵就做一次加操作,記錄刪除過期鍵的總數。expired_keys:0

二、Redis過期鍵的刪除策略:

當鍵值過期后,Redis是如何處理呢?綜合考慮Redis的單線程特性,有兩種策略:惰性刪除和定時刪除。

1.惰性刪除策略:

在每次執行key相關的命令時,都會先從expires中查找key是否過期,下面是3.0.7的源碼(db.c):

下面是讀寫key相關的入口:

robj *lookupKeyRead(redisDb *db, robj *key) { robj *val; expireIfNeeded(db,key); val = lookupKey(db,key); ...... return val;}robj *lookupKeyWrite(redisDb *db, robj *key) { expireIfNeeded(db,key); return lookupKey(db,key);}

可以看到每次讀寫key前,所有的Redis命令在執行之前都會調用expireIfNeeded函數:

int expireIfNeeded(redisDb *db, robj *key) { mstime_t when = getExpire(db,key); mstime_t now; if (when < 0) return 0; /* No expire for this key */ now = server.lua_caller ? server.lua_time_start : mstime(); if (server.masterhost != NULL) return now > when; /* Return when this key has not expired */ if (now <= when) return 0; /* Delete the key */ server.stat_expiredkeys++; propagateExpire(db,key); notifyKeyspaceEvent(NOTIFY_EXPIRED,  "expired",key,db->id); return dbDelete(db,key);}

從代碼可以看出,主從邏輯略有不同:

(1) 主庫:過期則expireIfNeeded會刪除過期鍵,刪除成功返回1,否則返回0。

(2) 從庫:expireIfNeeded不會刪除key,而會返回一個邏輯刪除的結果,過期返回1,不過期返回0 。

但是從庫過期鍵刪除由主庫的synthesized DEL operations控制。

2.定時刪除策略:

單單靠惰性刪除,肯定不能刪除所有的過期key,考慮到Redis的單線程特性,Redis使用了定期刪除策略,采用策略是從一定數量的數據庫的過期庫中取出一定數量的隨機鍵進行檢查,不為空則刪除。不保證實時刪除。有興趣的同學可以看看activeExpireCycle中具體實現,還是挺有意思的,下圖是個示意圖


if (server->masterhost == NULL) activeExpireCycle();

(1)主庫: 會定時刪除過期鍵。

(2)從庫: 不執行定期刪除。

綜上所述: 

主庫:

(1) 在執行所有操作之前調用expireIfNeeded惰性刪除。

(2) 定期執行調用一次activeExpireCycle,每次隨機刪除部分鍵(定時刪除)。

從庫:

過期鍵刪除由主庫的synthesized DEL operations控制。

三、過期讀寫問題

Redis過期刪除策略帶來的問題。我們只從用戶操作的角度來討論。

1、過期鍵讀操作

下面是Redis 2.8~4.0過期鍵讀操作的fix記錄

(1) Redis2.8主從不一致

2.8中的讀操作中都先調用lookupKeyRead函數:

robj *lookupKeyRead(redisDb *db, robs *key) {  robj *val;  expireIfNeeded(db,key);  val = lookupKey(db,key);  if (val == NULL)    server.stat_keyspace_misses++;  else    server.stat_keyspace_hits++;  return val;}

•對于主庫,執行expireIfNeeded時,過期會刪除key。lookupKey返回 NULL。

•對于從庫,執行expireIfNeeded時,過期不會刪除key。lookupKey返回value。

所以對于過期鍵的讀操作,主從返回就會存在不一致的情況,也就是開篇提到的問題。

(2) Redis 3.2主從除exists之外都一致

https://github.com/antirez/redis/commit/06e76bc3e22dd72a30a8a614d367246b03ff1312

3.2-rc1讀操作中同樣先調用了lookupKeyRead,實際上調用的是lookupKeyReadWithFlags函數:

robj *lookupKeyReadWithFlags(redisDb *db, robj *key) {  robj *val;  if (expireIfNeeded(db,key) == 1) {     if (server.masterhost == NULL) return NULL;    if (server.current_client && //當前客戶端存在      server.current_client != server.master && //當前客戶端不是master請求建立的(用戶請求的客戶端)      server.current_client->cmd &&      server.current_client->cmd->flags & REDIS_CMD_READONLY) { //讀命令        return NULL;       }  val = lookupKey(db,key,flags);  if (val == NULL)    server.stat_keyspace_misses++;  else    server.stat_keyspace_hits++;  return val;  }

可以看到,相對于2.8,增加了對expireIfNeeded返回結果的判斷:

•對于主庫,執行expireIfNeeded時,過期會刪除key,返回1。masterhost為空返回NULL。

•對于從庫,執行expireIfNeeded時,過期不會刪除key,返回1。滿足當前客戶端不為 master且為讀命令時返回NULL。

除非程序異常。正常情況下對于過期鍵的讀操作,主從返回一致。

(2) Redis 4.0.11解決exists不一致的情況

https://github.com/antirez/redis/commit/32a7a2c88a8b8cca8119b849eee7976b8ada8936

3.2并未解決exists這個命令的問題,雖然它也是個讀操作。之后的4.0.11中問題才得以解決.

2、過期鍵寫操作

在具體說這個問題之前,我們先說一下可寫從庫的使用場景。

(1).主從分離場景中,利用從庫可寫執行耗時操作提升性能。

作者在https://redis.io/topics/replication 中提到過:

For example computing slow Set or Sorted set operations and storing them into local keys is an use case for writable slaves that was observed multiple times.

在 https://github.com/antirez/redis/commit/c65dfb436e9a5a28573ec9e763901b2684eadfc4 舉了一個更具體的例子:

For instance imagine having slaves replicating certain Sets keys from the master. When accessing the data on the slave, we want to peform intersections between
such Sets values. However we don't want to intersect each time: to cache the intersection for some time often is a good idea.

也就是說在讀寫分離的場景中,可以使用過期鍵的機制將從庫作為一個緩存,去緩存從庫上耗時操作的結果,提升整體性能。

(2). 遷移數據時,需要先將從庫設置為可寫。

比如下列場景:線上Redis服務正常,但可能遇到一些硬件的情況,需要對該機器上的Redis主從集群遷移。遷數據的方式就是搭建一個新的主從集群,讓新主成為舊主的從。

進行如下操作:

•(1)主(舊主)從(新主)同步,rdb傳輸完畢90s之后,設置從庫(新主)可寫。

•(2)在主庫(舊主)完全沒有業務連接后,從庫(新主)執行slaveof no one。

這種場景下,為了保證數據完全同步,并且盡量減少對業務的影響,就會先設置從庫可寫。

接著我們來做一個測試:

3.2版本主庫執行的操作,主庫的過期鍵正常過期。

3.2版本可寫從庫執行以下操作,從庫的過期鍵并不會過期。

4.0rc3版本可寫從庫執行以下操作,從庫的過期鍵卻能夠過期。

其實可寫從庫過期鍵問題包含兩個問題:

•(1)從庫中的過期鍵由主庫同步過來的,過期操作由主庫執行(未變更過)。

•(2)從庫中的過期鍵的設置是從庫上操作的。

redis4.0rc3之前,存在過期鍵泄露的問題。當expire直接在從庫上操作,這個key是不會過期的。作者也在https://redis.io/topics/replication 提到過:

However note that writable slaves before version 4.0 were incapable of expiring keys with a time to live set. This means that if you use EXPIRE or other commands that set a maximum TTL for a key, the key will leak, and while you may no longer see it while accessing it with read commands, you will see it in the count of keys and it will still use memory. So in general mixing writable slaves (previous version 4.0) and keys with TTL is going to create issues.

過期鍵泄露問題在https://github.com/antirez/redis/commit/c65dfb436e9a5a28573ec9e763901b2684eadfc4中得到了解決。

四.總結

1、針對過期鍵讀操作

(1) Redis2.8主從不一致 

(2) Redis3.2-rc1主從除exists之外都一致: https://github.com/antirez/redis/commit/06e76bc3e22dd72a30a8a614d367246b03ff1312

(3) Redis4.0.11主從一致:

https://github.com/antirez/redis/commit/32a7a2c88a8b8cca8119b849eee7976b8ada8936

2、針對過期鍵的寫操作:

Redis2.8~4.0都只返回物理結果。

3、從庫中對key執行expire操作,key不會過期。

Redis4.0 rc3解決從庫中設置的過期鍵不過期問題 https://github.com/antirez/redis/commit/c65dfb436e9a5a28573ec9e763901b2684eadfc4

4、如果slave非讀寫分離、上述遷移使用,基本本文問題不會出現。還有就是Redis 4非??孔V,后面也會有文章介紹相關內容。(付磊)

總結

以上就是這篇文章的全部內容了,希望本文的內容對大家的學習或者工作具有一定的參考學習價值,謝謝大家對武林網的支持。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
黑人狂躁日本妞一区二区三区| 中文字幕欧美在线| 国产精品久久久久久久美男| 91高清免费在线观看| 国语自产在线不卡| 日韩欧美在线免费| 国产91精品高潮白浆喷水| 欧美区在线播放| 国产精品一区二区久久久| xxxx欧美18另类的高清| 国产成人综合精品在线| 亚洲mm色国产网站| 伊人伊人伊人久久| 亚洲美女福利视频网站| 亚洲成人av片| 成人有码在线播放| 久久色免费在线视频| 欧美性猛交xxxx黑人猛交| 一本大道亚洲视频| 久久久之久亚州精品露出| 亚洲欧美日韩天堂一区二区| 国产一区二区三区在线播放免费观看| 欧美视频在线观看免费网址| 成人情趣片在线观看免费| 亚洲色图13p| 国产日韩欧美中文| 欧美电影免费观看电视剧大全| 91在线观看欧美日韩| 日韩中文字幕视频| 2019中文字幕在线观看| 国产999在线观看| 日韩av中文在线| 日韩欧美第一页| 精品久久久久久久中文字幕| 国产综合香蕉五月婷在线| 亚洲欧美一区二区三区四区| 中文字幕免费精品一区高清| 日韩一区在线视频| 欧美精品久久一区二区| 日韩精品高清在线观看| 日本一区二三区好的精华液| 韩日欧美一区二区| 久久久久久久久久久久久久久久久久av| 国产午夜精品视频免费不卡69堂| www.午夜精品| 国产亚洲一级高清| 久久久久国产视频| 26uuu国产精品视频| 国产精品久久久av久久久| 九九热最新视频//这里只有精品| 欧美日韩在线视频首页| 亚洲最新av网址| 色偷偷888欧美精品久久久| 欧美性高潮床叫视频| 亚洲国产日韩欧美在线图片| 欧美日韩一区二区三区在线免费观看| 中文字幕日韩免费视频| www高清在线视频日韩欧美| 日韩最新在线视频| 亚洲毛茸茸少妇高潮呻吟| 美日韩精品免费观看视频| 红桃av永久久久| 91久久精品久久国产性色也91| 日本午夜精品理论片a级appf发布| xxxx欧美18另类的高清| 日本亚洲欧美三级| 日韩欧美一区视频| 亚洲欧洲日韩国产| 亚洲国产欧美一区二区丝袜黑人| 国产精品久久久久久久久久ktv| 中文字幕一区电影| 国产视频欧美视频| 欧美人在线观看| 亚洲视频电影图片偷拍一区| 91午夜在线播放| 91精品免费看| 精品精品国产国产自在线| 日韩网站免费观看高清| 高清欧美电影在线| 亚洲高清一二三区| 91精品国产777在线观看| 中文在线资源观看视频网站免费不卡| 欧美大全免费观看电视剧大泉洋| 成人精品福利视频| 色99之美女主播在线视频| 国产热re99久久6国产精品| 亚洲日韩欧美视频一区| 欧美激情亚洲激情| 日韩女优在线播放| 最好看的2019的中文字幕视频| 一区二区三区视频在线| 91精品国产91久久久久久不卡| 国产亚洲精品日韩| 亚洲性猛交xxxxwww| 黄色成人在线播放| 欧美日韩性生活视频| 日韩欧美成人免费视频| 中文字幕在线观看亚洲| 91人成网站www| 欧美裸体xxxxx| 777午夜精品福利在线观看| 亚洲一区二区黄| 91九色视频在线| 欧美极度另类性三渗透| 亚洲裸体xxxx| 亚洲品质视频自拍网| 中文字幕日本欧美| 色综合天天综合网国产成人网| 亚洲91精品在线| 久久视频国产精品免费视频在线| 91精品国产乱码久久久久久蜜臀| 欧美黑人极品猛少妇色xxxxx| 欧美成人一二三| 日韩精品999| 午夜精品久久久久久久99热| 国产成人在线一区二区| 中文字幕日韩av综合精品| 91九色视频在线| 日本三级久久久| 国产视频精品自拍| 日韩精品在线视频观看| 欧美国产一区二区三区| 亚洲国产欧美精品| 色午夜这里只有精品| 欧美日韩高清区| 久久久久久久成人| 国产mv免费观看入口亚洲| 国产成人精品综合| 中文字幕欧美日韩在线| 国产丝袜精品第一页| 成人免费xxxxx在线观看| 亚洲欧美在线一区| 欧美床上激情在线观看| 91亚洲va在线va天堂va国| 精品毛片网大全| 91亚洲va在线va天堂va国| 国产精品影片在线观看| 欧美日韩国产成人| 欧美性猛交xxxx乱大交极品| 国产一区二区三区在线播放免费观看| 孩xxxx性bbbb欧美| 日本a级片电影一区二区| 国产精品视频大全| 成人国产亚洲精品a区天堂华泰| 91视频8mav| 狠狠综合久久av一区二区小说| 国内精品400部情侣激情| 久久99精品久久久久久噜噜| 亚洲欧美制服第一页| 日韩欧美国产视频| 久久亚洲国产精品| 国产玖玖精品视频| 欧美国产日韩在线| 亚洲欧美综合另类中字| 欧美日韩另类在线| 自拍偷拍亚洲一区| 91精品国产综合久久久久久久久| 亚洲欧美国内爽妇网| 亚洲一区av在线播放| 亚洲欧美国内爽妇网| 久久久久久久久久亚洲| 伊人久久久久久久久久久久久| 国产午夜精品一区理论片飘花| 久久五月天色综合|