Redis鍵不會自動過期 - Ably
Ably 是一個釋出/訂閱訊息傳遞的平臺。釋出是在命名頻道上進行的,訂閱給定頻道的客戶端會將該頻道上的所有訊息傳遞給他們。我們使用Redis,一個用於基於金鑰儲存的分散式記憶體資料庫,來儲存各種實體,例如身份驗證令牌和臨時通道狀態。它非常適合在我們處理訊息時臨時儲存它們。
在任何給定時間,我們都有數十億個活動的 Redis 金鑰,這些金鑰分散在眾多 Redis 例項中。分片策略將相關鍵放在同一個分片中,以便我們可以執行原子更新相關鍵的操作。我們廣泛使用 Lua Redis 指令碼來查詢和更新鍵,並依靠指令碼執行的原子性來保持相關鍵值的完整性。也就是說,指令碼中的所有命令都執行,或者根本不執行,並且沒有其他命令同時執行。
我們還廣泛使用過期金鑰;Ably 服務的本質是頻道的大部分狀態都是短暫的,並且僅保留有限的時間段(通常為 2 分鐘)。我們將金鑰設定為具有 TTL,以便它們自動過期。
問題
一組相關鍵key的完整性要求所有鍵都存在或不存在。我們曾假設指令碼執行的原子性質也適用於指令碼呼叫的過期操作,但實際上,在同一個指令碼中實現失效過期多個鍵也會保持這種完整性?這並不是真的。
雖然過期操作在同一個指令碼中自動執行(沒有機會發生干預操作),但與每個過期操作相關的時間戳不一定相同。
執行TIME顯示兩個不同的值:
-- time.lua local a = redis.call('time') local b = redis.call('time') return {a, b} $ ./redis-cli --eval /app/time.lua 1) 1) "1638280442" 2) "996960" 2) 1) "1638280442" 2) "996966" |
檢查實際到期時間:
-- expire_check.lua redis.call('set', 'foo', '1') redis.call('expire', 'foo', 1) -- slow calls... redis.call('set', 'bar', '2') redis.call('expire', 'bar', 1) local fooExpiry = redis.call('PEXPIRETIME', 'foo') local barExpiry = redis.call('PEXPIRETIME', 'bar') return {fooExpiry, barExpiry} $ ./redis-cli --eval /app/expire_check.lua 1) (integer) 1638280843717 2) (integer) 1638280843730 |
過期可能不是精確的,它可能在 0 到 1 毫秒之間。
這意味著有時某些金鑰已過期,但其他相關金鑰尚未過期,這可能導致狀態不一致。
我們的解決方案
解決方案是使用EXPIREAT為所有相關鍵key設定絕對到期時間,而不是依賴於通過 TTL 的相對到期時間。
EXPIREAT如果鍵具有相同的設定,是否保證同時發生多個鍵到期,Redis 文件不清楚。為謹慎起見,我們重新排序了鍵key到期時間,以確保無論如何我們都避免不一致。
-- expire_new.lua -- Unix time local now = redis.call('time')[1] local expiry = now + 1 redis.call('set', 'foo', '1') redis.call('expireat', 'foo', expiry) -- slow calls... redis.call('set', 'bar', '2') redis.call('expireat', 'bar', expiry) local fooExpiry = redis.call('PEXPIRETIME', 'foo') local barExpiry = redis.call('PEXPIRETIME', 'bar') return {now, fooExpiry, barExpiry} $ ./redis-cli --eval /app/expire_new.lua 2) (integer) 1638281266000 3) (integer) 1638281266000 |
相關文章
- redis 過期鍵刪除策略Redis
- Redis 的持久化與過期鍵Redis持久化
- Redis 資料庫、鍵過期的實現Redis資料庫
- Redis對於過期鍵有三種清除策略Redis
- SSL證書會不會過期?域名SSL證書過期了怎麼辦?
- C# Redis 過期機制不生效問題C#Redis
- 【Redis】過期鍵刪除策略和記憶體淘汰策略Redis記憶體
- redis過期監聽Redis
- redis 過期時間Redis
- 訂單自動過期實現方案 - 轉
- Redis 的資料過期了就會馬上刪除麼?Redis
- 當遇到美女面試官之如何理解Redis的Expire Key(過期鍵)面試Redis
- Oracle 11.2.0.4 awr過期快照無法自動清理Oracle
- redis hset hmset過期時間Redis
- redis設定過期時間Redis
- java 監聽 redis 過期事件JavaRedis事件
- 請求時token過期自動重新整理token
- 自動刪除過期的statspack統計資料
- Redis中監聽key過期通知Redis
- redis自學(46)鍵值設計Redis
- Redis過期策略及實現原理-Redis面試題Redis面試題
- 從Node Redis遷移到Ioredis後CPU 使用率減少了 30% - AblyRedis
- 關於 block 會不會被自動 copy 的實驗和猜想BloC
- Redis 修改過期 key 的一個坑Redis
- 走近原始碼:Redis如何清除過期key原始碼Redis
- Redis 中如何讓訊息永不過期Redis
- SSL證書為什麼會過期?證書過期會有哪些影響?
- 探索Redis設計與實現9:資料庫redisDb與鍵過期刪除策略Redis資料庫
- Laravel 中使用 Redis 生成自增主鍵LaravelRedis
- Redis(二十):Redis資料過期和淘汰策略詳解(轉)Redis
- 會員批次過期的方案
- oracle增加主鍵也不會了Oracle
- OkHttp+Retrofit+RxJava 實現過期Token自動重新整理HTTPRxJava
- 【手摸手玩轉 OceanBase 168】如何自動清理過期備份?
- Word 表格內容不會自動轉到下一頁
- springboot+redis做過期事件通知業務Spring BootRedis事件
- Redis 過期時間與記憶體管理Redis記憶體
- [Redis]過期刪除和記憶體淘汰Redis記憶體