背景:今天系統多個服務突然告警,限制響應時間超時,原本不到400ms的介面響應時間,好多都變成2s左右,但是過了2分鐘就恢復正常
分析:根據檢視監控顯示,乙個使用的第三方的redis超時導致。
結論:刪除了乙個大key
1.什麼是大key? 業務場景中經常會有各種大key的情況, 比如: (1)單個簡單的key儲存的value很大 (2)hash、set、zset、list中儲存過多的元素(以萬為單位)
2.大key的風險? (1).讀寫大key會導致超時嚴重,甚至阻塞服務。
(2).如果刪除大key,del命令可能阻塞redis程序數十秒,使得其他請求阻塞,對應用程式和redis集群可用性造成嚴重的影響。
(3).建議每個key不要超過m級別。
3.儲存優化方案 由於redis是單執行緒執行的,如果一次操作的value很大會對整個redis的響應時間造成負面影響,應該想辦法把這些大key化整為零。 首先是第一種情況 (1)單個簡單的key儲存的value很大
該物件需要每次都整存整取 可以嘗試將物件分拆成幾個key-value, 使用multiget獲取值,這樣分拆的意義在於分拆單次操作的壓力,將操作壓力平攤到多個redis例項中,降低對單個redis的io影響;
該物件每次只需要訪問部分資料 可以像第一種做法一樣,分拆成幾個key-value,也可以將這個儲存在乙個hash中,每個field代表乙個具體的屬性,使用hget,hmget來獲取部分的value,使用hset,hmset來更新部分屬性
(2)hash、set、zset、list 中儲存過多的元素 類似於場景一中的第乙個做法,可以將這些元素分拆。 以hash為例,原先的正常訪問流程是: hget(hashkey, field); hset(hashkey, field, value)
現在,固定乙個桶的數量,比如10000,每次訪問的時候,先在本地計算field的hash值,模除10000,確定該field落在哪個key上。 newhashkey = hashkey + (hash(field) % 10000); hset(newhashkey, field, value); hget(newhashkey, field)
set, zset, list 也可以類似上述做法。 但也有些不適合的場景,比如要保證lpop的資料的確是最早push到list中去的,這個就需要一些附加的屬性,或者是在key的拼接上做一些工作(比如list按照時間來分拆)。
4.如何優雅地刪除各類大key 從redis2.8版本開始支援scan命令,通過m次時間複雜度為o(1)的方式,遍歷包含n個元素的大key.這樣避免單個o(n)的大命令,導致redis阻塞。
5.redis lazy free 應該從3.4版本開始,redis會支援lazy delete free的方式,刪除大鍵的過程不會阻塞正常請求。
redis的大key和熱key問題
redis的大key和熱key實際上就是經常被訪問的key或者占用空間比較大的key。有什麼影響?舉個栗子,比如說某個明星出軌了,這個明星的搜尋量就會暴增,對redis造成很大的衝擊。redis檢視大key命令 redis cli bigkeys redis檢視熱key命令 redis cli ho...
在不影響線上服務情況下,刪除大表資料表
在不影響線上資料庫服務情況下,如何刪除資料庫中的大表 分析 資料庫中表涉及到db和os兩個層面 1 db層面刪表涉及到table cache的全域性唯一鎖,一旦資料表過大,會長時間占用全域性為一鎖,導致db卡死。2 os層面涉及到資料表物理檔案的儲存,包括時間的資料block和元資料inode 在e...
蘋果根證書異常刪除導致 App 閃退的問題
dyld library not loaded rpath libswiftassetslibrary reason no suitable image found.did find lldb 後來新建了乙個工程,什麼 都不寫,也是無法在真機上執行,報的錯誤和前面差不多的樣子。想來想去,覺得以前遇到...