redis集羣之分片集羣的原理和常用代理環境部署

上篇文章剛剛介紹完redis的主從複製集羣,但主從複製集羣主要是爲了解決redis集羣的單點故障問題,通過整合哨兵能實現集羣的高可用;但是卻無法解決數據容量以及單節點的壓力問題,所以本文繼續介紹redis的分片集羣;分片集羣即將不同的數據分發到不同的redis實例(或者主從集羣),每個redis實例沒有關聯,這樣當數據量過大時就做到了數據的分治,如果某個實例故障也不至於丟失所有的數據;下面我會首先解決分片集羣的常用實現方案,然後介紹如何搭建Twitter和predixy兩種代理實現的redis集羣,正常情況,按照我的步驟做完就能夠搭建一套可以的redis集羣了;下面開始

一、分片集羣的解決方案

這裏我們不單一討論redis,我們從分片集羣的根本出發,分片即將數據分發到不同的後端服務上去,那麼顯然我們可以從客戶端和服務端這兩個方面下手;

1、客戶端實現

(1)、通過業務分類

  • 可以根據業務分類,由客戶端控制,將不同業務線的數據打到不同的實例

(2)、hash+取模(modula)

  • 思路:通過對key進行hash+取模然後根據結果打到不同的實例上;模幾取決於redis集羣的實例數量;
  • 缺點:模數是固定的,如果集羣拓展時需要調整,且拓展前的數據就不好取到了;

(3)、通過隨機數選擇redis實例(random)

  • 思路:數據到達時隨機往集羣中的某個實例扔數據,這樣存數據是容易了但是取數據難
  • 使用場景:這種情況適用於實現消息隊列,往不同的redis裏仍相同key的不同數據,客戶端消費集羣中的每個實例後就能獲取到完整數據

(4)、一致性哈希環(ketama)

  • 思路:維護一個虛擬的環形結構,該環有N個點組成;將redis集羣中的所有實例通過一致性哈希算法計算後映射到該哈希環上,作爲環中唯一的物理節點,如果集羣有三個實例,那麼環中就會有三個物理節點;當數據進來時,對key做哈希運算最終也要落到這個哈希環上,然後找出離自己最近的物理節點,再將數據打到該節點上即可
  • 缺點:
    • 由於每個實例參與計算的信息不一樣,並不總能保證集羣的各節點在環上是均勻分佈的,所以爲了解決數據傾斜的問題,可以將每個實例多映射幾份一起參與計算,這樣散在環上的節點變多了,也就一定程度上解決了數據傾斜的問題
    • 當有新的實例上線時,會丟失一定長度數據;可以通過改變尋找實例的邏輯解決,當key打到環上時,我們不再是找離它最近的一個節點,而是找離他最近的兩個節點取數據

2、服務端實現(redis cluster)

(1)、基本概念介紹(概念摘自redis官網)

  • Redis集羣是一個提供在多個Redis間節點間共享數據的程序集,能夠自動分發數據到不同實例;其並沒有使用一致性哈希算法,而是引入了哈希槽的概念;Redis集羣有16384個哈希槽,每個key通過CRC16校驗後對16384取模來決定放置哪個槽.集羣的每個節點負責一部分hash槽,舉個例子,比如當前集羣有3個節點,那麼:
    • 節點 A 包含 0 到 5500號哈希槽.
    • 節點 B 包含5501 到 11000 號哈希槽.
    • 節點 C 包含11001 到 16384號哈希槽.

這種結構很容易添加或者刪除節點. 比如如果我想新添加個節點D, 我需要從節點 A, B, C中得部分槽到D上. 如果我想移除節點A,需要將A中的槽移到B和C節點上,然後將沒有任何槽的A節點從集羣中移除即可. 由於從一個節點將哈希槽移動到另一個節點並不會停止服務,所以無論添加刪除或者改變某個節點的哈希槽的數量都不會造成集羣不可用的狀態.

(2)、redis的集羣搭建

  • 這裏的搭建很簡單,按照中文官網的步驟往下走就行了,這裏就不一一介紹了,需要搭建的可以移步http://redis.cn/topics/cluster-tutorial.html

二、通過Twitter的twemproxy代理搭建redis集羣

twemproxy是由Twitter開源的一套代理分片服務,可以接受多個客戶端的訪問然後根據配置的算法將數據分配到不同的redis節點,再按原路返回;不支持redis的watch、multi等命令

  • 1、mkdir twemproxy 在/root目錄創建一個twemproxy用來存放twemproxy的源碼

  • 2、安裝git yum install git

  • 3、克隆twemproxy的代碼

  • 4、進入源碼目錄,cd twemproxy

  • 5、安裝automake和libtool

    • yum install automake libtool -y
  • 6、安裝configure,執行autoreconf -fvi

  • 7、執行 ./configure

  • 8、執行make編譯源碼,編譯完正常會有可執行程序出現

  • 9、進入源碼的/scripts目錄,將配置文件拷貝至/etc/init.d/twemproxy目錄

    • cp nutcracker.init /etc/init.d/twemproxy
  • 10、進入init.d文件, 執行chmod +x twemproxy給twemproxy賦權

  • 11、創建配置文件所在的目錄

    • mkdir /etc/nutcracker
  • 12、進入源碼安裝目錄的conf目錄,將conf目錄下的配置文件拷貝到11步創建的文件夾下

    • cd ~/soft/twemproxy/twemproxy/conf
    • cp ./* /etc/nutcracker/
  • 13、進入源碼安裝目錄的src目錄,將編譯完的可執行程序複製到/usr/bin目錄下,這樣在系統任意位置都可以運行nutcracker

    • cd ~/soft/twemproxy/twemproxy/src/
    • cp nutcracker /usr/bin
  • 14、進入nutcracker目錄,修改配置文件

    • cd /etc/nutcracker/
    • cp nutcracker.yml nutcracker.yml.bak 穩妥起見,先備份
    • vi nutcracker.yml 編輯配置文件
  • 15、啓動兩個redis實例

    • redis-server ~/testRedis/6379.conf
    • redis-server ~/testRedis/6380.conf
  • 16、啓動nutcracker

    • service twemproxy start
  • 17、啓動redis客戶端連接nutcracker對外暴露的端口

    • redis-cli -p 22121 連接成功後如圖,即可對redis進行操作

    我們通過22121端口的代理就可以直接訪問redis集羣,可以設置數據,但是由於數據分治了,所以例如keys 、watch、multi等這種聚合的命令在代理裏是不支持的;至此,通過twemproxy 代理的方式搭建的redis集羣就完成了,客戶端只需鏈接22121端口,至於後續的分片操作由代理服務進行轉發

三、通過predixy搭建redis集羣

predixy也是一款redis的代理服務,其即支持redis sentinel又支持redis cluster,在group只有一個的情況下,其還支持watch、multi等指令

  • 1、在~/soft目錄創建predixy目錄並且進入,用於下載源碼;
    • mkdir predixy
    • cd predixy
  • 2、下載源碼包
  • 3、解壓
    • tar xf predixy-1.0.5-bin-amd64-linux.tar.gz
  • 4、進入conf目錄,編輯predixy.conf文件
    • vi predixy.conf
    • 將bind 127.0.0.1:7617的註釋放開
    • 將Include try.conf註釋,將Include sentinel.conf放開
  • 5、編輯sentinel.conf 文件
    • vi sentinel.conf
    • 將SentinelServerPool配置的註釋放開,並按下圖進行配置

Sentinels{}裏填哨兵集羣的ip和端口

Group表示redis分組,shard001表示分組名稱;上圖配置表示一個哨兵集羣監控了兩套redis的主從集羣

注意:Group後面跟的名稱需要與哨兵配置文件裏的master名稱一致

  • 6、根據5中的注意,所以我們現在需要去修改哨兵的配置文件,將其監控的master名稱由默認的mymaster改爲shard001,又因爲我們需要哨兵監控兩個主從集羣,所以需要再加一個shard002的master配置,命令如下:

    • vi 26379.conf 、 vi 26380.conf 、 vi 26381.conf

    • 修改完的配置文件如下圖

    注意:上圖只截取了26379的配置,26380和81與79除了port外其餘配置均一致

  • 7、啓動哨兵集羣

    • redis-server ./26379.conf --sentinel
    • redis-server ./26380.conf --sentinel
    • redis-server ./26381.conf --sentinel
  • 8、任意位置創建文件夾test,在裏面創建36379、80和46379、80的目錄

    • 進入36379目錄執行 redis-server --port 36379

    • 進入36380目錄執行 redis-server --port 36380 --replicaof 127.0.0.1 36379追隨36379

      這樣一個主從集羣就搭建起來了,46379和80與上面一致,只需更改對應端口即可,我這裏就不再贅述了

    至此,哨兵集羣與兩套redis主從複製集羣已啓動完畢

  • 9、進入predixy安裝的bin目錄啓動predixy

    • cd soft/predixy/predixy-1.0.5/bin
    • ./predixy ../conf/predixy.conf
    • 啓動成功如下圖:
  • 10、用redis客戶端測試

    雖然上面搭建廢了九牛二虎之力,但是對客戶端而言只需關注predixy對外暴露的服務連接即可:

    • redis-cli -p 7617

    連接成功後就可以操作redis了,predixy會自動分發到不同的redis集羣中去;設置如圖:

    • 然後連接36379可以發現,k1和設置了tag的key都分發到此了,如圖:
    • 再連接46379,發現k2被分發到46379了

predixy只支持單group下的事務、watch等操作,我們這裏配置了兩個group所以不支持;但是如果只配置一個group的話那麼能寫的也只有一個master,就失去了分片集羣的意義了

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章