喫透Redis系列:Redis代理twemproxy和predixy詳細介紹

一,實現Redis集羣方案

Redis在3.0版本前只支持單實例模式,雖然Redis的開發者Antirez早在博客上就提出在Redis 3.0版本中加入集羣的功能,但3.0版本等到2015年才發佈正式版。各大企業等不急了,在3.0版本還沒發佈前爲了解決Redis的存儲瓶頸,紛紛推出了各自的Redis集羣方案。這些方案的核心思想是把數據分片(sharding)存儲在多個Redis實例中,每一片就是一個Redis實例。

爲了實現集羣的功能,從服務端、客戶端分片的角度來看,可以分爲以下三類:

客戶端分片: 典型的是支持一致性哈希的客戶端

代理層分片: 典型代表twemproxy、codis

redis服務端分片: redis cluster

1,客戶端分片

客戶端分片是把分片的邏輯放在Redis客戶端實現,(比如:jedis已支持Redis Sharding功能,即ShardedJedis),通過Redis客戶端預先定義好的路由規則(使用一致性哈希),把對Key的訪問轉發到不同的Redis實例中,查詢數據時把返回結果彙集。

客戶端分片的優缺點:

優點:

客戶端sharding技術使用hash一致性算法分片的好處是所有的邏輯都是可控的,不依賴於第三方分佈式中間件。服務端的Redis實例彼此獨立,相互無關聯,每個Redis實例像單服務器一樣運行,非常容易線性擴展,系統的靈活性很強。開發人員清楚怎麼實現分片、路由的規則,不用擔心踩坑。

缺點:

這是一種靜態的分片方案,需要增加或者減少Redis實例的數量,需要手工調整分片的程序。

運維成本比較高,集羣的數據出了任何問題都需要運維人員和開發人員一起合作,減緩了解決問題的速度,增加了跨部門溝通的成本。

在不同的客戶端程序中,維護相同的路由分片邏輯成本巨大。比如:java項目、PHP項目裏共用一套Redis集羣,路由分片邏輯分別需要寫兩套一樣的邏輯,以後維護也是兩套。

客戶端分片有一個最大的問題就是,服務端Redis實例羣拓撲結構有變化時,每個客戶端都需要更新調整。如果能把客戶端分片模塊單獨拎出來,形成一個單獨的模塊(中間件),作爲客戶端 和 服務端連接的橋樑就能解決這個問題了,此時代理分片就出現了。

2,代理分片

代理基本原理是:通過中間件的形式,Redis客戶端把請求發送到代理,代理根據路由規則發送到正確的Redis實例,最後代理把結果彙集返回給客戶端。

2.1,twemproxy

在redis 3.0推出redis cluster之前,代理層實現redis集羣是首選方案,twemproxy和codis是最常見的兩個代理。

然而twemproxy不支持的redis功能太多,像列表的阻塞命令、事物、發佈訂閱等都不支持,而且也沒有直接支持redis的高可用。

twemproxy github地址:https://github.com/twitter/twemproxy

2.2,predixy

基於上述原因,2017年推出了一款全新的redis代理:predixy。

predixy完美的實現了對redis單例模式及集羣模式的支持,幾乎完整的實現了redis原生的所有用於客戶端的命令。多key命令、列表阻塞操作、發佈訂閱、腳本、掃描等高級功能全支持,在使用redis單例模式下也支持事物。

predixy github地址:https://github.com/joyieldInc/predixy

3,服務端分片redis cluster

Redis Cluster是一種服務器Sharding技術(分片和路由都是在服務端實現),採用多主多從,每一個分區都是由一個Redis主機和多個從機組成,片區和片區之間是相互平行的。Redis Cluster集羣採用了P2P的模式,完全去中心化。

redis cluster原理上和codis差不多,同樣是引入了slot的概念,不過redis cluster有16384個slot。redis cluster自身集成了高可用的功能,可擴展也是通過遷移slot來實現的。但是對客戶端來說,redis cluster和單個redis實例相比它在請求響應上帶來了MOVE/ASK語義,也就意味着之前的redis客戶端無法直接獲得全部集羣功能,需要增加對MOVE/ASK響應的支持纔可以訪問整個集羣。

爲了讓客戶端透明的訪問redis cluster,可以在中間加一層代理,predixy是一個不錯的選擇

4,方案選擇

基於客戶端的方案任何時候都要慎重考慮,在此我們不予推薦。

基於twemproxy的方案雖然看起來功能挺全面,但是實際使用中存在的問題同樣很多,具體見上述,目前也不推薦再用twemproxy的方案。

redis cluster自redis 3.0推出以來,目前已經在很多生產環境上得到了應用,目前來講,構建redis集羣,推薦採用redis cluster搭配一款支持redis cluster的代理方案。

二,twemproxy

1,twemproxy使用

github地址:https://github.com/twitter/twemproxy

1.1,clone代碼

git clone https://github.com/twitter/twemproxy.git

1

1.2,生成configure文件

autoreconf -fvi

1

1.3,執行./configure

./configure

1

1.4,執行make

make

1

執行完之後我們進src目錄會發現生成一個nutcracker可執行程序

1.5,拷貝nutcracker.init

cd ..

cd /scripts

sudo cp nutcracker.init /etc/init.d/twemproxy

1

2

3

1.6,給twemproxy賦可執行權限

cd /etc/init.d

sudo chmod +x twemproxy

1

2

1.7,拷貝配置文件

mkdir /etc/nutcracker

1

去源碼目錄

cd /soft/twemproxy/conf

1

拷貝當前目錄下所有文件到/etc/nutcracker目錄

sudo cp ./* /etc/nutcracker/

1

1.8,拷貝make生成的nutcracker可執行程序到/usr/bin目錄下

cd /soft/twemproxy/src

sudo cp nutcracker /usr/bin/

1

2

然後我們就可以在操作系統的任何位置來使用nutcracker命令

1.9,修改配置文件

參照https://github.com/twitter/twemproxy的configuration

cd /etc/nutcracker/

sudo gedit nutcracker.yml

1

2

配置twemproxy端口爲22121,監聽6379,6380兩個redis實例

alpha:

  listen: 127.0.0.1:22121

  hash: fnv1a_64

  distribution: ketama

  auto_eject_hosts: true

  redis: true

  server_retry_timeout: 2000

  server_failure_limit: 1

  servers:

  - 127.0.0.1:6379:1

  - 127.0.0.1:6380:1

1

2

3

4

5

6

7

8

9

10

11

1.10,啓動6379,6380兩個redis實例,啓動twemproxy代理

#啓動兩個redis實例

redis-server --port 6379

redis-server --port 6380

redis-cli -p 6379

redis-cli -p 6380

#啓動twemproxy代理

nutcracker -d -c /etc/nutcracker/nutcracker.yml

#連接twemproxy代理

redis-cli -p 22121

1

2

3

4

5

6

7

8

9

10

1.11,測試數據

在twemproxy代理也就是22121端口,設置k1 bo

然後我們發現,可以在6380讀取出來,而6379讀取不到,證明代理把k1存儲到6380實例上面了。

2,twemproxy缺點

twemproxy不支持的redis功能太多,像列表的阻塞命令、事物、發佈訂閱等都不支持,而且也沒有直接支持redis的高可用。

三,predixy

1,predixy安裝

我們打開predixy github地址:https://github.com/joyieldInc/predixy

1.1,下載代碼

你可以直接下載編譯好的包,也可以下載代碼自己make

直接下載包地址:https://github.com/joyieldInc/predixy/releases

或下載代碼:

git clone https://github.com/joyieldInc/predixy.git

#下載完成後

cd /predixy

make

1

2

3

4

make完成後會在src目錄下生成predixy可執行文件

1.2,把predixy可執行文件拷貝到/user/bin目錄下,這樣就可以全局使用了

cd /predixy/src

sudo sudo cp predixy /usr/bin/

1

2

1.3,把predixy/conf中的配置文件拷貝到/etc/predixy目錄下

cd /etc

mkdir predixy

cd /soft/predixy/conf

sudo cp ./* /etc/predixy

1

2

3

4

1.4,給predixy目錄下所有文件賦可執行權限

cd /etc

sudo chmod +x -R predixy

1

2

2,predixy+redis cluster模式

prefixy詳細使用方式可以參考官網:https://github.com/joyieldInc/predixy/blob/master/doc/config_CN.md

2.1,配置文件

predixy的配置類似redis, 具體配置項的含義在配置文件裏有詳細解釋,請參考下列配置文件:

predixy.conf,整體配置文件,會引用下面的配置文件

cluster.conf,用於Redis Cluster時,配置後端redis信息

sentinel.conf,用於Redis Sentinel時,配置後端redis信息

auth.conf,訪問權限控制配置,可以定義多個驗證密碼,可每個密碼指定讀、寫、管理權限,以及定義可訪問的健空間

dc.conf,多數據中心支持,可以定義讀寫分離規則,讀流量權重分配

latency.conf, 延遲監控規則定義,可以指定需要監控的命令以及延時時間間隔

提供這麼多配置文件實際上是按功能分開了,所有配置都可以寫到一個文件裏,也可以寫到多個文件裏然後在主配置文件裏引用進來。

2.2,配置predixy.conf

# 此代理綁定本機端口:7617

Bind 127.0.0.1:7617

# 包含集羣配置文件

Include cluster.conf

1

2

3

4

注意:這裏有一個點,配置文件中每一塊只能開啓一個配置,比如:

################################### SERVERS ####################################

Include cluster.conf

# Include sentinel.conf

#Include try.conf

1

2

3

4

在SERVERS中你如果開啓了cluster,那麼就必須把sentinel和try給註釋掉!!!

2.3,配置cluster.conf

配置7000,7001,7002三個主節點,配置8000,8001,8002三個從節點。

ClusterServerPool {

    MasterReadPriority 60

    StaticSlaveReadPriority 50

  DynamicSlaveReadPriority 50

  RefreshInterval 1

    ServerTimeout 1

    ServerFailureLimit 10

    ServerRetryTimeout 1

    KeepAlive 120

    Servers {

        + 127.0.0.1:7000

        + 127.0.0.1:7001

        + 127.0.0.1:7002

        + 127.0.0.1:8000

        + 127.0.0.1:8001

        + 127.0.0.1:8002

  }

}

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

2.4,搭建cluster集羣

1>,啓動上述6個節點

redis-server /etc/redis/redis_7000.conf

redis-server /etc/redis/redis_7001.conf

redis-server /etc/redis/redis_7002.conf

redis-server /etc/redis/redis_8000.conf

redis-server /etc/redis/redis_8001.conf

redis-server /etc/redis/redis_8002.conf

1

2

3

4

5

6

2>,節點握手

把上述節點加入到同一個集羣中,在7000節點中使用cluster meet命令,可以將所有節點加入到集羣,完成節點握手:

cluster meet 127.0.0.1 7002

cluster meet 127.0.0.1 7003

cluster meet 127.0.0.1 8000

cluster meet 127.0.0.1 8001

cluster meet 127.0.0.1 8002

1

2

3

4

5

3>,分配槽

給三個主節點7001,7002,7003分配槽

redis-cli -p 7000 cluster addslots {0..5461}

redis-cli -p 7001 cluster addslots {5462..10922}

redis-cli -p 7002 cluster addslots {10923..16383}

1

2

3

4>,設置主從關係

至此,集羣搭建成功!

2.5,啓動predixy代理

predixy /etc/predixy/predixy.conf

1

出現如下打印則證明啓動成功!

2.6,連接predixy客戶端,設置set k1 bo

2.7,查詢k1

可以看到,k1被分配到了7002主節點,那麼7002的從節點8002應該也能查詢到:

可以看到在從節點8002也可以查詢到!

2.8,驗證

驗證發佈/訂閱

驗證多key命令支持: mset/msetnx/mget/del/unlink/touch/exists

3,predixy優點

高性能並輕量級

支持多線程

多平臺支持:Linux、OSX、BSD、Windows(Cygwin)

支持Redis Sentinel,可配置一組或者多組redis

支持Redis Cluster

支持redis阻塞型命令,包括blpop、brpop、brpoplpush

支持scan命令,無論是單個redis還是多個redis實例都支持

多key命令支持: mset/msetnx/mget/del/unlink/touch/exists

支持redis的多數據庫,即可以使用select命令

支持事務,當前僅限於Redis Sentinel下單一redis組可用

支持腳本,包括命令:script load、eval、evalsha

支持發佈訂閱機制,也即Pub/Sub系列命令

多數據中心支持,讀寫分離支持

擴展的AUTH命令,強大的讀、寫、管理權限控制機制,健空間限制機制

日誌可按級別採樣輸出,異步日誌記錄避免線程被io阻塞

日誌文件可以按時間、大小自動切分

豐富的統計信息,包括CPU、內存、請求、響應等信息

延遲監控信息,可以看到整體延遲,分後端redis實例延遲

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