首頁 >常見問題 >redis阻塞怎麼辦

redis阻塞怎麼辦

(*-*)浩
(*-*)浩原創
2019-05-31 14:14:133018瀏覽

Redis的事件循環在一個執行緒中處理,作為一個單執行緒程序,重要的是要確保事件處理的延遲短,這樣,事件循環中的後續任務才不會阻塞; 當redis的資料量達到一定等級後(例如20G),阻塞操作對效能的影響特別嚴重; 

redis阻塞怎麼辦

#下面我們總結下在redis中有哪些耗時的場景及應對方法;

耗時長的指令造成阻塞

keys、sort等指令

keys指令用於尋找所有符合給定模式pattern 的key,時間複雜度為O(N), N 為資料庫中key 的數量。當資料庫中的個數達到千萬時,這個指令會造成讀寫執行緒阻塞數秒; 類似的指令有sunion sort等作業; 如果業務需求中一定要使用keys、sort等作業怎麼辦?

解決方案: 

在架構設計中,有「分流」一招,說的是將處理快的請求和處理慢的請求分開來開,否則,慢的影響到了快的,讓快的也快不起來;這在redis的設計中體現的非常明顯,redis的純內存操作,epoll非阻塞IO事件處理,這些快的放在一個線程中搞定,而持久化,AOF重寫、Master-slave同步資料這些耗時的操作就單開一個進程來處理,不要慢的影響到快的; 同樣,既然需要使用keys這些耗時的操作,那麼我們就將它們剝離出去,例如單開一個redis slave結點,專門用於keys、sort等耗時的操作,這些查詢一般不會是線上的實時業務,查詢慢點就慢點,主要是能完成任務,而對於線上的耗時快的任務沒有影響;

smembers命令

#smembers命令用於獲取集合全集,時間複雜度為O(N) ,N為集合中的數量; 如果一個集合中保存了千萬量級的數據,一次取回也會造成事件處理線程的長時間阻塞;

解決方案: 

和sort,keys等指令不一樣,smembers可能是線上即時應用場景中使用頻率非常高的一個指令,這里分流一招並不適合,我們更多的需要從設計層面來考慮; 在設計時,我們可以控制集合的數量,將集合數一般保持在500個以內; 例如原來使用一個鍵來存儲一年的記錄,數據量大,我們可以使用12個鍵來分別保存12個月的記錄,或365個鍵來保存每一天的記錄,將集合的規模控制在可接受的範圍;

如果不容易將集合劃分為多個子集合,而堅持用一個大集合來存儲,那麼在取集合的時候可以考慮使用SRANDMEMBER key [count];隨機傳回集合中的指定數量,當然,如果要遍歷集合中的所有元素,這個指令就不適合了;

以上是redis阻塞怎麼辦的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn