Redis分片機制


文章原創於公眾號:程序猿周先森。本平台不定時更新,喜歡我的文章,歡迎關注我的微信公眾號。

file

前兩篇文章對Redis主從復制和主從切換的知識點進行了介紹,但是也很明顯的有一點小弊端:

  • 需要定時進行主從復制會影響Redis性能。

  • 主節點宕機后,從所有從節點選擇進行主從切換。主從切換的過程中非服務不可用。

引入分片概念--分片機制的作用

而本篇文章主要談談Redis的分片機制,如果沒有分片機制,Redis就被局限於單機所支持的內存容量。Redis的分片機制允許數據拆分存放在不同的Redis實例上,每個Redis實例只包含所有鍵的子集。可以減輕單台Redis的壓力,提升Redis擴展能力和計算能力。如果我們只使用一個Redis實例,當Redis宕機將會直接停止服務,所以我們可以采取分片機制,將原本一台Redis實例維護的數據,改為由多個Redis實例共同維護這部分數據。

分片方案
(1)范圍分片

分片需要將不同key映射到不同Redis實例上存儲,所以key的映射規則需要制定一個算法,最簡單的一個分片方案應該是范圍分片。范圍分片理解起來很簡單,比如我們存儲用戶基本信息,我們制定一個算法將用戶user_id從0到1000映射到實例A,user_id從1000到2000映射到實例B,以此類推。這個方案很輕松可以使用,但是引發了一個問題:我們需要維護user_id范圍和映射實例之間的關系。而正是這個問題導致范圍分片雖然簡單,但是效率比其他分片方案低效許多,所以Redis中一般不會使用范圍分片作為分片方案。

(2)哈希分片

比如我們目前有四個Redis實例,我們需要存儲一個key。我們可以通過哈希函數crc32()將key名轉換成一個長整型數字,然后對長整型數字對4取余,就可以得到映射的實例。但是這種分配方案一樣存在弊端:當我們需要增加或移除Redis實例時,就會造成大量key無法被命中。所以這時候出現了一種哈希分片的高級形式--一致性哈希。一致性哈希有三大特性:

  • key哈希結果盡可能分配到不同Redis實例。

  • 當實例增加或移除,需要保護已映射的內容不會重新被分配到新實例上。

  • 對key的哈希應盡量避免重復。

但是在Redis中沒有使用一致性哈希這個概念,而是引入了哈希槽。在Redis集群中共有16384個哈希槽,然后每個key通過哈希函數crc16()將key名轉化成一個長整型數字再對16384取余,最終決定這個key存儲的哈希槽。而每個Redis實例負責維護一部分哈希槽,所有實例共同維護所有的哈希槽。使用哈希槽最顯而易見的特點就是Redis實例的增加或者移除很方便,而不需要暫停所有Redis實例服務。

分片實現

上一篇談到主從切換的哨兵模式已經提到,哨兵模式可以實現高可用以及讀寫分離,但是缺點在於所有Redis實例存儲的數據全部一致,所以Redis支持cluster模式,可以簡單將cluster理解為Redis集群管理的一個插件,通過它可以實現Redis的分布式存儲。

數據分片方式一般有三種:客戶端分片、代理分片和服務器分片。

客戶端分片

定義:客戶端自己計算key需要映射到哪一個Redis實例。

優點:客戶端分片最明顯的好處在於降低了集群的復雜度,而服務器之間沒有任何關聯性,數據分片由客戶端來負責實現。

缺點:客戶端實現分片則客戶端需要知道當前集群下不同Redis實例的信息,當新增Redis實例時需要支持動態分片,多數Redis需要重啟才能實現該功能。

代理分片

定義:客戶端將請求發送到代理,代理通過計算得到需要映射的集群實例信息,然后將客戶端的請求轉發到對應的集群實例上,然后返回響應給客戶端。

優點:降低了客戶端的復雜度,客戶端不用關心后端Redis實例的狀態信息。

缺點:多了一個中間分發環節,所以對性能有些取的損失。

服務器分片

定義:客戶端可以和集群中任意Redis實例通信,當客戶端訪問某個實例時,服務器進行計算key應該映射到哪個具體的Redis實例中存儲,如果映射的實例不是當前實例,則該實例主動引導客戶端去對應實例對key進行操作。這其實是一個重定向的過程。這個過程不是從當前Redis實例轉發到對應的Redis實例,而是客戶端收到服務器通知具體映射的Redis實例重定向到映射的實例中。當前還不能完全適用於生產環境。

優點:支持高可用,任意實例都有主從,主掛了從會自動接管。

缺點:需要客戶端語言實現服務器集群協議,但是目前大多數語言都有其客戶端實現版本。

預分片

從上面可以清楚地看出,分片機制增加或移除實例是非常麻煩的一件事,所以我們可以考慮一開始就開啟32個節點實例,當我們可以新增Redis服務器時,我們可以將一半的節點移動到新的Redis服務器。這樣我們只需要在新服務器啟動一個空節點,然后移動數據,配置新節點為源節點的從節點,然后更新被移動節點的ip信息,然后向新服務器發送slaveof命令關閉主從配置,最后關閉舊服務器不需要使用的實例並且重新啟動客戶端。這樣我們就可以在幾乎不需要停機時間時完成數據的移動。

分片機制的缺點

  • 分片是由多台Redis實例共同運轉,所以如果其中一個Redis實例宕機,則整個分片都將無法使用,所以分片機制無法實現高可用。

  • 如果有不同的key映射到不同的Redis實例,這時候不能對這兩個key做交集或者使用事務。

  • 使用分片機制因為涉及多實例,數據處理比較復雜。

  • 分片中對於實例的添加或刪除會很復雜,不過可以使用預分片技術進行改善。

歡迎關注公眾號:程序猿周先森。
file

本文由博客一文多發平台 OpenWrite 發布!


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM