redis-scan-rehash

Scan正則表達式

在平時線上 Redis 維護工做中,有時候須要從 Redis 實例成千上萬的 key 中找出特定前綴的 key 列表來手動處理數據,多是修改它的值,也多是刪除 key。這裏就有一個問題,如何從海量的 key 中找出知足特定前綴的 key 列表來?算法

keys * 正則表達式匹配數組

  1. 沒有 offset、limit 參數,一次性吐出全部知足條件的 key,萬一實例中有幾百 w 個 key 知足條件,當你看到滿屏的字符串刷的沒有盡頭時,你就知道難受了。
  2. keys 算法是遍歷算法,複雜度是 O(n),若是實例中有千萬級以上的 key,這個指令就會致使 Redis 服務卡頓,全部讀寫 Redis 的其它的指令都會被延後甚至會超時報錯,由於 Redis 是單線程程序,順序執行全部指令,其它指令必須等到當前的 keys 指令執行完了才能夠繼續

scan 相比 keys 具有有如下特色:服務器

  1. 複雜度雖然也是 O(n),可是它是經過遊標分步進行的,不會阻塞線程;
  2. 提供 limit 參數,能夠控制每次返回結果的最大條數,limit 只是一個 hint,返回的結果可多可少;
  3. 同 keys 同樣,它也提供模式匹配功能;
  4. 服務器不須要爲遊標保存狀態,遊標的惟一狀態就是 scan 返回給客戶端的遊標整數;
  5. 返回的結果可能會有重複,須要客戶端去重複,這點很是重要;
  6. 遍歷的過程當中若是有數據修改,改動後的數據能不能遍歷到是不肯定的;
  7. 單次返回的結果是空的並不意味着遍歷結束,而要看返回的遊標值是否爲零;

scan 參數提供了三個參數,第一個是 cursor 整數值,第二個是 key 的正則模式,第三個是遍歷的 limit hint。第一次遍歷時,cursor 值爲 0,而後將返回結果中第一個整數值做爲下一次遍歷的 cursor。一直遍歷到返回的 cursor 值爲 0 時結束。遍歷順序:高位進位加法spa

127.0.0.1:6379> scan 0 match key99* count 1000

漸進式 rehash

Java 的 HashMap 在擴容時會一次性將舊數組下掛接的元素所有轉移到新數組下面。若是 HashMap 中元素特別多,線程就會出現卡頓現象。Redis 爲了解決這個問題,它採用漸進式 rehash線程

它會同時保留舊數組和新數組,而後在定時任務中以及後續對 hash 的指令操做中漸漸地將舊數組中掛接的元素遷移到新數組上。這意味着要操做處於 rehash 中的字典,須要同時訪問新舊兩個數組結構。若是在舊數組下面找不到元素,還須要去新數組下面去尋找。code

scan 也須要考慮這個問題,對與 rehash 中的字典,它須要同時掃描新舊槽位,而後將結果融合後返回給客戶端。字符串

相關文章
相關標籤/搜索
本站公眾號
   歡迎關注本站公眾號,獲取更多信息