婷婷综合国产,91蜜桃婷婷狠狠久久综合9色 ,九九九九九精品,国产综合av

主頁 > 知識庫 > Redis 2.8-4.0過期鍵優化過程全紀錄

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

熱門標簽:四川穩定外呼系統軟件 一個地圖標注多少錢 南京手機外呼系統廠家 b2b外呼系統 高碑店市地圖標注app 臺灣電銷 地圖標注工廠入駐 400電話辦理的口碑 廊坊外呼系統在哪買

前言

之前 白馨(陌陌-技術保障部存儲工程師 )在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]:value
expires---expires[key]:timeout

例如:

127.0.0.1:6379> setex hello 120 world
OK
127.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非常靠譜,后面也會有文章介紹相關內容。(付磊)

總結

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

您可能感興趣的文章:
  • redis學習之RDB、AOF與復制時對過期鍵的處理教程
  • 大家都應該知道的Redis過期鍵與過期策略
  • redis鍵空間通知使用實現
  • Redis開啟鍵空間通知實現超時通知的步驟詳解
  • 使用redis實現延遲通知功能(Redis過期鍵通知)

標簽:定州 拉薩 甘南 泰州 南寧 伊春 畢節 河源

巨人網絡通訊聲明:本文標題《Redis 2.8-4.0過期鍵優化過程全紀錄》,本文關鍵詞  Redis,2.8-4.0,過期,鍵,優化,;如發現本文內容存在版權問題,煩請提供相關信息告之我們,我們將及時溝通與處理。本站內容系統采集于網絡,涉及言論、版權與本站無關。
  • 相關文章
  • 下面列出與本文章《Redis 2.8-4.0過期鍵優化過程全紀錄》相關的同類信息!
  • 本頁收集關于Redis 2.8-4.0過期鍵優化過程全紀錄的相關信息資訊供網民參考!
  • 推薦文章
    婷婷综合国产,91蜜桃婷婷狠狠久久综合9色 ,九九九九九精品,国产综合av
    久草在线在线精品观看| 毛片不卡一区二区| 国产调教视频一区| 久久先锋影音av鲁色资源网| 久久青草欧美一区二区三区| 日韩免费视频一区二区| 精品久久久影院| 久久久www成人免费无遮挡大片| 久久午夜色播影院免费高清 | 亚洲精品第1页| 亚洲欧美日本韩国| 亚洲自拍偷拍网站| 免费不卡在线观看| 韩国女主播成人在线| 夫妻av一区二区| 在线视频一区二区三区| 欧美一级在线免费| 久久久精品中文字幕麻豆发布| 欧美国产一区二区| 亚洲国产中文字幕在线视频综合| 日韩影视精彩在线| 国产麻豆精品theporn| 99热这里都是精品| 欧美一级片免费看| 亚洲人成7777| 免费成人av在线| 91婷婷韩国欧美一区二区| 欧美高清激情brazzers| 国产午夜精品美女毛片视频| 亚洲少妇30p| 久久99精品久久久久久国产越南| 成人性生交大片免费看视频在线 | 日韩视频免费直播| 国产精品女同一区二区三区| 亚洲成人777| 成人三级伦理片| 91精品国产色综合久久| 中文字幕亚洲一区二区va在线| 天涯成人国产亚洲精品一区av| 国产成人av影院| 欧美一级久久久| 亚洲精品中文在线观看| 国产精品主播直播| 欧美一级在线免费| 一区二区三区加勒比av| 成人污污视频在线观看| 日韩天堂在线观看| 亚洲成av人片在线| 91浏览器在线视频| 国产精品午夜久久| 欧美人与禽zozo性伦| 精品福利视频一区二区三区| 五月婷婷综合激情| 色狠狠综合天天综合综合| 国产精品视频免费看| 久久爱www久久做| 91麻豆精品国产91久久久久久 | 精品中文字幕一区二区小辣椒| 色老汉av一区二区三区| 中文字幕欧美国产| 国产精一品亚洲二区在线视频| 555www色欧美视频| 亚洲一区av在线| 一本到不卡精品视频在线观看 | 9191国产精品| 亚洲国产精品久久人人爱| 色视频成人在线观看免| 亚洲码国产岛国毛片在线| 成人自拍视频在线| 中文字幕日本不卡| 99精品偷自拍| 亚洲激情综合网| 欧美在线|欧美| 亚洲综合在线电影| 欧美色图片你懂的| 日韩精品一卡二卡三卡四卡无卡| 69堂精品视频| 狠狠色综合色综合网络| 欧美精品一区二区三区在线| 国产伦精品一区二区三区在线观看| 精品99999| 粉嫩13p一区二区三区| 亚洲三级理论片| 欧美精品在线一区二区| 免费在线观看视频一区| 久久色在线观看| 99久久er热在这里只有精品15| 亚洲美女视频在线| 欧美一区午夜视频在线观看| 韩国欧美国产1区| 国产精品麻豆网站| 欧美日韩一区二区三区四区五区| 奇米精品一区二区三区在线观看一 | 亚洲日穴在线视频| 欧美日韩国产综合一区二区| 美女脱光内衣内裤视频久久网站 | 日韩伦理电影网| 欧美三级电影网| 国产一区美女在线| 亚洲色图.com| 欧美成人精精品一区二区频| 成人动漫中文字幕| 午夜精品视频在线观看| 久久久久久日产精品| 欧美怡红院视频| 国产电影一区在线| 婷婷综合在线观看| 中文字幕一区在线观看| 日韩久久久精品| 色婷婷精品久久二区二区蜜臂av | 91老师国产黑色丝袜在线| 日韩 欧美一区二区三区| 国产精品久久三区| 日韩欧美国产午夜精品| www.亚洲在线| 国产美女在线精品| 日韩精品91亚洲二区在线观看| 国产无人区一区二区三区| 欧美日韩中字一区| 99这里只有久久精品视频| 秋霞成人午夜伦在线观看| 一区二区三区在线观看国产| 久久综合色播五月| 日韩一区二区免费在线电影| 色噜噜偷拍精品综合在线| 久久99热99| 青青草一区二区三区| 亚洲永久免费av| 亚洲视频 欧洲视频| 国产午夜精品一区二区 | 国产黄人亚洲片| 久久精品国内一区二区三区| 一区二区三区自拍| 国产精品久久久久久久久免费桃花| 久久综合国产精品| 精品国内二区三区| 欧美成人乱码一区二区三区| 欧美一级欧美一级在线播放| 欧美夫妻性生活| 欧美高清www午色夜在线视频| 欧美在线不卡一区| 欧美三级日韩在线| 欧美在线观看视频一区二区| 在线精品亚洲一区二区不卡| 99国产一区二区三精品乱码| 99精品国产视频| 99久久精品情趣| 91首页免费视频| 在线视频观看一区| 欧美日韩国产在线观看| 欧美性色综合网| 欧美日韩成人激情| 51精品国自产在线| 日韩一区二区在线看片| 精品国精品自拍自在线| 国产丝袜欧美中文另类| 中文字幕在线观看不卡| 亚洲精品国产一区二区精华液| 亚洲国产精品精华液网站| 日韩精品一级中文字幕精品视频免费观看| 午夜欧美在线一二页| 久草热8精品视频在线观看| 韩国一区二区视频| 成人av在线资源| 欧美中文一区二区三区| 日韩丝袜美女视频| 国产婷婷色一区二区三区四区| 亚洲欧美一区二区三区极速播放| 亚洲日本在线观看| 婷婷久久综合九色综合绿巨人| 久久精品国产精品亚洲红杏| 国产一区二区三区av电影| 福利一区二区在线| 欧美日韩一级二级三级| 精品国产免费一区二区三区四区 | 九九热在线视频观看这里只有精品| 久久成人久久爱| 99久久久精品| 日韩一区二区三区在线| 国产农村妇女精品| 舔着乳尖日韩一区| 成人av在线资源| 日韩一级成人av| 亚洲日本电影在线| 韩国精品主播一区二区在线观看| 成人福利视频在线| 日韩一二三区不卡| 亚洲欧美日韩系列| 精品无码三级在线观看视频| 色综合久久88色综合天天6| 日韩欧美第一区| 亚洲免费观看高清完整版在线观看 | 中文字幕色av一区二区三区| 亚洲v日本v欧美v久久精品| 国产福利一区在线| 8v天堂国产在线一区二区| 亚洲欧洲精品一区二区三区不卡| 九九国产精品视频| 精品视频免费看| 亚洲乱码国产乱码精品精可以看|