如何解決 Redis 資料傾斜、熱點等問題
大家好,我是Tom哥。
問題描述:
向你提問:tom哥,在複習redis時,有些疑問,麻煩看看:
1.如果redis叢集出現資料傾斜,資料分配不均,該如何解決?2.處理hotKey時,為key建立多個副本,如k-1,k-2…, 如何讓這些副本能均勻寫入?如何均勻訪問?3.redis使用hash slot來維護叢集。與一致性雜湊類似,都可以避免全量遷移。為什麼不直接使用一致性hash?
Tom哥 回覆:
分散式快取作為效能加速器,在系統最佳化中承擔著非常重要的角色。相比本地快取,雖然增加了一次網路傳輸,大約佔用不到 1 毫秒外,但是卻有集中化管理的優勢,並支援非常大的儲存容量。
分散式快取領域,目前應用比較廣泛的要數 Redis 了,該框架是純記憶體儲存,單執行緒執行命令,擁有豐富的底層資料結構,支援多種維度的資料儲存和查詢。
當然,資料量一大,各種問題就出現了,比如:資料傾斜、資料熱點等
什麼是資料傾斜?
單臺機器的硬體配置有上限制約,一般我們會採用分散式架構將多臺機器組成一個叢集,下圖的叢集就是由三臺Redis單機組成。客戶端透過一定的路由策略,將讀寫請求轉發到具體的例項上。
由於業務資料特殊性,按照指定的分片規則,可能導致不同的例項上資料分佈不均勻,大量的資料集中到了一臺或者幾臺機器節點上計算,從而導致這些節點負載多大,而其他節點處於空閒等待中,導致最終整體效率低下。
資料傾斜有哪些原因呢?
1、存在大key
比如儲存一個或多個 String 型別的 bigKey 資料,記憶體佔用很大。
Tom哥之前排查過這種問題,有同事開發時為了省事,採用JSON格式,將多個業務資料合併到一個 value,只關聯一個key,導致了這個鍵值對容量達到了幾百M。
頻繁的大key讀寫,記憶體資源消耗比較重,同時給網路傳輸帶了極大的壓力,進而導致請求響應變慢,引發雪崩效應,最後系統各種超時報警。
解決方案:
辦法非常簡單,採用化整為零
的策略,將一個bigKey拆分為多個小key,獨立維護,成本會降低很多。當然這個拆也講究些原則,既要考慮業務場景也要考慮訪問場景,將關聯緊密的放到一起。
比如:有個RPC介面內部對 Redis 有依賴,之前訪問一次就可以拿到全部資料,拆分將要控制單值的大小,也要控制訪問的次數,畢竟呼叫次數增多了,會拉大整體的介面響應時間。
浙江的政府機構都在提倡最佳化流程,最多跑一次,都是一個道理。
2、HashTag 使用不當
Redis 採用單執行緒執行命令,從而保證了原子性。當採用叢集部署後,為了解決mset、lua 指令碼等對多key 批次操作,為了保證不同的 key 能路由到同一個 Redis 例項上,引入了 HashTag 機制。
用法也很簡單,使用{}
大括號,指定key只計算大括號內字串的雜湊,從而將不同key的健值對插入到同一個雜湊槽。
舉個例子:
192.168.0.1:6380> CLUSTER KEYSLOT testtag
(integer) 764
192.168.0.1:6380> CLUSTER KEYSLOT {testtag}
(integer) 764
192.168.0.1:6380> CLUSTER KEYSLOT mykey1{testtag}
(integer) 764
192.168.0.1:6380> CLUSTER KEYSLOT mykey2{testtag}
(integer) 764
check 下業務程式碼,有沒有引入HashTag,將太多的key路由到了一個例項。結合具體場景,考慮如何做下拆分。
就像 RocketMQ 一樣,很多時候只要能保證分割槽有序,就可以滿足我們的業務需求。具體實戰中,要找到這個平衡點,而不是為了解決問題而解決問題。
3、slot 槽位分配不均
如果採用 Redis Cluster 的部署方式,叢集中的資料庫被分為16384個槽(slot),資料庫中的每個健都屬於這16384個槽的其中一個,叢集中的每個節點可以處理的0個或最多16384個槽。
你可以手動做遷移,將一個比較大的 slot 遷移到稍微空閒的機器上,保證儲存和訪問的均勻性。
什麼是快取熱點?
快取熱點是指大部分甚至所有的業務請求都命中同一份快取資料,給快取伺服器帶來了巨大壓力,甚至超過了單機的承載上限,導致伺服器當機。
解決方案:
1、複製多份副本
我們可以在key的後面拼上有序編號,比如key#01、key#02。。。key#10多個副本,這些加工後的key位於多個快取節點上。
客戶端每次訪問時,只需要在原key的基礎上拼接一個分片數上限的隨機數,將請求路由不到的例項節點。
注意:快取一般都會設定過期時間,為了避免快取的集中失效,我們對快取的過期時間儘量不要一樣,可以在預設的基礎上增加一個隨機數。
至於資料路由的均勻性,這個由 Hash 演算法來保證。
2、本地記憶體快取
把熱點資料快取在客戶端的本地記憶體中,並且設定一個失效時間。對於每次讀請求,將首先檢查該資料是否存在於本地快取中,如果存在則直接返回,如果不存在再去訪問分散式快取的伺服器。
本地記憶體快取徹底“解放”了快取伺服器,不會對快取伺服器有任何壓力。
缺點:實時感知最新的快取資料有點麻煩,會產生資料不一致的情況。我們可以設定一個比較短的過期時間,採用被動更新。當然,也可以用監控機制,如果感知到資料已經發生了變化,及時更新本地快取。
Redis Cluster 為什麼不用一致性Hash?
Redis Cluster 叢集有16384個雜湊槽,每個key
透過CRC16
校驗後對16384
取模來決定放置哪個槽。叢集的每個節點負責一部分hash槽,舉個例子,比如當前叢集有3個節點,那麼 node-1
包含 0 到 5460 號雜湊槽,node-2
包含 5461 到 10922 號雜湊槽,node-3
包含 10922 到 16383 號雜湊槽。
一致性雜湊演算法是 1997年麻省理工學院的 Karger 等人提出了,為的就是解決分散式快取的問題。
一致性雜湊演算法本質上也是一種取模演算法,不同於按伺服器數量取模,一致性雜湊是對固定值 2^32 取模。
公式 = hash(key) % 2^32
其取模的結果必然是在 [0, 2^32-1] 這個區間中的整數,從圓上對映的位置開始順時針方向找到的第一個節點即為儲存key的節點
一致性雜湊演算法大大緩解了擴容或者縮容導致的快取失效問題,隻影響本節點負責的那一小段key。如果叢集的機器不多,且平時單機的負載水位很高,某個節點當機帶來的壓力很容易引發雪崩效應。
舉個例子:
Redis 叢集 總共有4臺機器,假設資料分佈均衡,每臺機器承擔 四分之一的流量,如果某一臺機器突然掛了,順時針方向下一臺機器將要承擔這多出來的 四分之一 流量,最終要承擔 二分之一 的流量,還是有點恐怖。
但是如果採用 CRC16
計算後,並結合槽位與例項的繫結關係,無論是擴容還是縮容,只需將相應節點的key做下資料平滑遷移,廣播儲存新的槽位對映關係,不會產生快取失效,靈活性很高。
另外,如果伺服器節點配置存在差異化,我們可以自定義分配不同節點負責的 slot 編號,調整不同節點的負載能力,非常方便。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/70024924/viewspace-2927957/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- IoT資料傾斜如何解決
- 如何解決Hive中經常出現的資料傾斜問題Hive
- 【Spark篇】---Spark解決資料傾斜問題Spark
- 大資料常見問題之資料傾斜大資料
- 實戰 | Hive 資料傾斜問題定位排查及解決Hive
- 資料傾斜解決辦法
- Redis 切片叢集的資料傾斜分析Redis
- Hive資料傾斜Hive
- Spark 資料傾斜及其解決方案Spark
- 【系統架構】如何解決熱點資料更新問題架構
- Hive千億級資料傾斜解決方案Hive
- Spark學習——資料傾斜Spark
- Oracle資料傾斜導致的問題-有繫結變數Oracle變數
- Oracle資料傾斜導致的問題-無繫結變數Oracle變數
- 大資料SQL優化之資料傾斜解決案例全集大資料SQL優化
- 【原創】談談redis的熱key問題如何解決Redis
- 巧用函式索引解決資料傾斜列查詢函式索引
- Redis 資料傾斜與 JD 開源 hotkey 原始碼分析揭秘Redis原始碼
- hive優化-資料傾斜優化Hive優化
- 一種自平衡解決資料傾斜的分表方法
- 【Hive】資料傾斜優化 shuffle, join, group byHive優化
- hadoop 透過cachefile來避免資料傾斜Hadoop
- PostgreSQL DBA(193) - 資料傾斜下的HashJoinSQL
- 如何解決大資料安全問題大資料
- 如何解決資料庫配置問題資料庫
- ORACLE通過BIND_AWARE+SQL PATCH解決SQL繫結變數中資料傾斜的問題OracleSQL變數
- 索引資料列傾斜度(skew)問題索引
- 【分享】資料庫的熱點塊問題資料庫
- Spark SQL三種join和資料傾斜的產生和解決辦法SparkSQL
- 傾斜攝影三維模型的立體裁剪的問題分析模型
- 深度分析資料庫的熱點塊問題資料庫
- Spark效能最佳化篇三:資料傾斜調優Spark
- Oracle中利用函式索引處理資料傾斜案例Oracle函式索引
- 淺析 Hadoop 中的資料傾斜(R0.1)Hadoop
- 聊一聊Redis熱點key儲存問題Redis
- 如何解決Redis中的key過期問題Redis
- emiya-canvas.js 解決ios下拍照傾斜與canvas高清屏下繪圖模糊問題CanvasJSiOS繪圖
- 【Java面試】什麼是冪等?如何解決冪等性問題?Java面試