Redis3.0版本以後開始支持了Redis Cluster,Redis也開始有了分佈式緩存的概念。關於Redis Cluster的相關說明,能夠看以前的幾篇文章:Redis Cluster 原理相關說明、redis-cli --cluster help說明。其架構以下:html
由於 Redis Cluster 內部使用的是P2P中的Gossip協議,每一個節點既能夠從其餘節點獲得服務,也能夠向其餘節點提供服務,沒有中心的概念,經過一個節點能夠獲取到整個集羣的全部信息。因此若是應用鏈接Redis Cluster能夠配置一個節點地址,也能夠配置多個節點地址。但須要注意若是集羣進行了上下節點的的操做,其應用也須要進行修改,這樣會致使須要重啓應用,很是的不友好。從Redis 6.0開始支持了Prxoy,能夠直接用Proxy來管理各個集羣節點。本文來介紹下如何使用官方自帶的proxy:redis-cluster-proxynode
經過使用 redis-cluster-proxy 能夠與組成Redis集羣的一組實例進行通信,就像是單個實例同樣。Redis羣集代理是多線程的,使用多路複用通訊模型,所以每一個線程都有本身的與羣集的鏈接,該鏈接由屬於該線程自己的全部客戶端共享。git
在某些特殊狀況下(例如MULTI事務或阻塞命令),多路複用將被禁用;而且客戶端將擁有本身的集羣鏈接。這樣客戶端僅發送諸如GET和SET之類的簡單命令就不須要Redis集羣的專有鏈接。github
redis-cluster-proxy的主要功能:
redis
git clone https://github.com/RedisLabs/redis-cluster-proxy.git
-- 安裝 make -- 32位二進制文件 make 32bit -- 安裝詳細信息,請使用V選項 make V=1 -- 重建依賴關係 make distclean -- 啓動測試 make test
注意:默認狀況下,安裝redis-cluster-proxy,須要配置環境變量REDIS_HOME(/etc/profile),gcc版本必須大於4.9,即:
api
REDIS_HOME=/usr/local/redis6.0/ export PATH=$PATH:$REDIS_HOME/bin
使用make安裝,安裝成功以後,執行文件proxy目錄的在src下,若是使用 make install,則安裝成功以後,執行文件在/usr/local/bin目錄中數組
./redis-cluster-proxy CLUSTER_ADDRESS
說明:CLUSTER_ADDRESS是任何羣集實例的主機地址(入口點),經過IP:PORT的形式表示TCP鏈接,或者經過指定文件名將其表示爲UNIX套接字。如:
緩存
./redis-cluster-proxy 127.0.0.1:6379 ./redis-cluster-proxy /path/to/entry-point.socket
redis-cluster-proxy -h Usage: redis-cluster-proxy [OPTIONS] [node1_host:node1_port,node2_host:node2_port,...] -c <file> 指定配置文件 -p, --port <port> Proxy端口,默認7777;使用0禁止TCP鏈接Proxy --maxclients <n> 最大客戶端鏈接,默認10000 --threads <n> 線程數配置,默認8,最大500 --tcpkeepalive TCP活躍鏈接時間,默認300秒 --tcp-backlog TCP鏈接中已完成隊列(完成三次握手以後)的長度,默認511 --daemonize 是否後臺執行 --pidfile <path> 指定pid文件,如/var/run/redis-cluster-proxy.pid --logfile <path> 定日誌文件,默認情使用STDOUT。若是daemonize開啓,並未指定日誌文件,則該代理徹底不會記錄日誌。 --unixsocket <sock_file> 套接字路徑,默認空 --unixsocketperm <mode> 套接字權限,默認0 --bind <address> 綁定一個地址(能夠屢次使用綁定多個地址) --connections-pool-size <size> 鏈接池的大小,0禁用鏈接池。默認值:10,最大值:50 --connections-pool-min-size <size> 鏈接池中的最小鏈接數。 低於此值,線程將以定義的速率開始從新生成鏈接,直到池再次變滿。 默認值:10 --connections-pool-spawn-every <ms> 從新生成鏈接池中鏈接的時間間隔(以毫秒爲單位)。 默認值:50 --connections-pool-spawn-rate <num> 每一個週期在鏈接池中從新產生的鏈接數。 默認值:2 --disable-multiplexing <opt> 什麼時候應禁用多路複用值:(auto|always)(默認值:auto) --enable-cross-slot 啓用跨槽查詢(注意:路由到多個節點的跨槽查詢不能是原子的) -a, --auth <passw> 鏈接密碼 --auth-user <name> 鏈接用戶 --disable-colors 禁止彩色輸出 --log-level <level> 日誌級別:debug|info|success|warning|error,默認info --dump-queries 轉儲查詢參數(僅適用於日誌級別的debug) --dump-buffer 轉儲查詢緩衝區(僅用於日誌級別的debug) --dump-queues 轉儲請求隊列(僅適用於日誌級別的debug) -h, --help 打印幫助
說明:默認狀況下,redis-cluster-proxy端口是7777,使用-p或--port選項對其進行更改。 此外,默認狀況下,Redis羣集端口將綁定全部可用的網絡接口以偵聽傳入的鏈接。使用--bind選項綁定到特定接口。 能夠綁定一個接口,也能夠經過屢次使用--bind選項來綁定多個接口。安全
還能夠經過使用--unixsocket選項指定套接字文件名,或者使用--unixsocketperm設置套接字文件權限,來告訴Redis集羣端口偵聽UNIX套接字。若是隻想在UNIX套接字上偵聽,請將--port設置爲0,以使代理徹底不在TCP套接字上偵聽。服務器
① 監聽7888端口
./redis-cluster-proxy --port 7888 127.0.0.1:7000
② 綁定地址:127.0.0.1
./redis-cluster-proxy --bind 127.0.0.1 127.0.0.1:7000
③ 綁定多個接口
./redis-cluster-proxy --port 7888 --bind 192.168.0.10 --bind 10.0.0.10 127.0.0.1:7000
④ 在UNIX套接字上偵聽並禁用TCP鏈接
./redis-cluster-proxy --unixsocket /path/to/proxy.socket --port 0 127.0.0.1:7000
⑤ 更改線程數
./redis-cluster-proxy --port 7888 127.0.0.1:7000 --threads 16
⑥ 使用配置文件:在Redis Cluster Proxy的主目錄內找到一個示例proxy.conf文件
redis-cluster-proxy -c /path/to/my/proxy.conf 127.0.0.1:7000
啓動後,鏈接到代理,就好像是普通的Redis服務器同樣(可是請確保瞭解當前的限制)。
每一個線程都有本身的鏈接池,其中包含到集羣的隨時可用的專用鏈接,該集羣的套接字在建立時即已預先鏈接。這容許須要專用鏈接(即在執行諸如MULTI之類的命令或阻塞命令以後)的客戶端當即使用可能已經鏈接到羣集的鏈接,而不是從頭開始從新鏈接到羣集(這種狀況可能會減慢順序的速度)從客戶端自己的角度執行查詢)。
每一個鏈接池都有預約義的大小,而且不容許建立超出其大小容許的鏈接數的鏈接。能夠經過--connections-pool-size選項配置鏈接池的大小(默認爲10)。當池中的鏈接用完時,每一個須要專用鏈接的新客戶端都將從頭開始建立一個新的專用鏈接,它必須鏈接到集羣並等待鏈接創建。在這種狀況下,鏈接模型將是「惰性的」,這意味着僅當查詢須要與該節點的鏈接時,新鏈接的套接字纔會鏈接到羣集的特定節點。
若是鏈接數降至指定的最小值如下後,每一個線程將從新填充其本身的池,默認狀況下,該數量與池自己的大小相同,而且能夠經過--connections-pool-min-大小選項。填充速率和間隔能夠由--connections-pool-spawn-every(間隔以毫秒爲單位)和--connections-pool-spawn-rate(每一個間隔的新鏈接數)定義。如:
redis-cluster-proxy --connections-pool-size 20 connections-pool-min-size 15 --connections-pool-spawn-rate 2 --connections-pool-spawn-every 500 127.0.0.1:7000
說明:建立一個包含20個鏈接(最大)的鏈接池,並在鏈接數降至15如下時從新填充它,方法是每500毫秒建立2個新鏈接。記住,代理啓動時,每一個池都將徹底填充。 一樣重要的是要注意,當擁有專用鏈接的客戶端斷開鏈接時,若是池自己還沒有滿,則他們的線程將嘗試回收其專用鏈接,以便再次將其添加到池中。
若是集羣節點受密碼保護,則可使用-a,-auth命令行選項或auth配置文件選項,以指定身份驗證密碼。此外,若是集羣使用ACL,而且有多個用戶,則可使用--auth-user命令行選項(或配置文件中的auth-user)向特定用戶進行身份驗證。如:
redis-cluster-proxy -a MYPASSWORD 127.0.0.1:7000 redis-cluster-proxy --auth MYPASSWORD 127.0.0.1:7000 redis-cluster-proxy --auth-user MYUSER --auth MYPASSWORD 127.0.0.1:7000
proxy將使用這些憑據對集羣進行身份驗證並獲取羣集的內部配置,它還將對全部客戶端進行身份驗證。所以使用--auth-user指定的用戶或默認用戶(若是未指定用戶)對將要鏈接到proxy的全部客戶端進行身份驗證,而無需本身調用AUTH命令:在這種狀況下,客戶端將使用專用鏈接而不是共享的多路複用鏈接。
跨槽查詢使用屬於不一樣槽甚至不一樣節點的多個鍵。 不能保證執行是原子的(它們實際上能夠破壞許多Redis命令的原子設計),所以默認狀況下將其禁用。 若是想要此功能,則能夠在啓動時經過使用--enable-cross-slot或經過在配置文件中設置enable-cross-slot yes來啓用它。 您還能夠在代理運行時經過使用特殊的PROXY命令激活此功能。
注意:即便啓用了此功能,也不是全部命令都支持跨槽查詢(即,不能將其與EVAL或ZUNIONSTORE以及許多其餘命令一塊兒使用)。 在這種狀況下,將收到特定的錯誤回覆。 可使用PROXY命令來獲取在跨槽查詢中沒法使用的命令列表
PROXY命令容許獲取特定的信息或執行特定的操做。該命令具備各類子命令,下面是一些清單:
PROXY CONFIG GET threads PROXY CONFIG SET log-level debug PROXY CONFIG SET enable-cross-slot 1 PROXY MULTIPLEXING STATUS|OFF
-> PROXY MULTIPLEXING STATUS -> Reply: "on" -> PROXY MULTIPLEXING off
PROXY CLIENT ID: -- 獲取當前客戶的內部ID PROXY CLIENT THREAD: -- 獲取當前客戶端的線程
status:集羣的當前狀態,能夠更新,更新或破壞 connection:鏈接類型,若是客戶端在多路複用上下文中(所以鏈接與線程的全部客戶端共享),則能夠共享;若是客戶端使用其本身的專用鏈接,則能夠共享。 nodes:一個嵌套數組,其中包含集羣的全部主節點的列表。 每一個節點都是另外一個嵌套的數組,其中包含名稱/值對。
PROXY CLUSTER UPDATE:請求更新當前集羣的配置。
如:
-> PROXY CLUSTER 1) status 2) updated 3) connection 4) shared 5) nodes 6) 1) 1) name 2) 8d829c8b66f67dd9c4adad16e5c0a4c82aadd810 3) ip 4) 127.0.0.1 5) port 6) (integer) 7002 7) slots 8) (integer) 5462 9) replicas 10) (integer) 1 11) connected 12) (integer) 1 ...
PROXY LOG [level] MESSAGE
將MESSAGE記錄到代理的日誌中,以進行調試。可選級別可用於定義日誌級別:debug
, info
, success
, warning
, error
(默認爲debug)
PROXY DEBUG
爲調試目的執行不一樣的操做,其中子命令能夠是:SEGFAULT:使用sigsegv使代理崩潰;ASSERT:因爲斷言失敗而使代理崩潰。
PROXY SHUTDOWN [ASAP]
關閉代理。 可選的ASAP選項使代理當即退出(不安全退出)。
PROXY HELP
PROXY命令的幫助
目前,該項目是alpha代碼,旨在由社區評估以獲取建議和貢獻。 不建議在任何生產環境中使用它。
# Redis Cluster Proxy configuration file example. # 經過配置文件啓動方式 # ./redis-cluster-proxy -c /path/to/proxy.conf ################################## INCLUDES ################################### # include /path/to/local.conf # include /path/to/other.conf ######################## CLUSTER ENTRY POINT ADDRESS ########################## #與在redis-cluster-proxy命令行參數中指示的方式相同的方式指示入口點地址,能夠被命令行參數自己覆蓋。 能夠經過添加更多行來指定多個入口點 cluster 192.168.163.134:8379 cluster 192.168.163.134:8380 cluster 192.168.163.134:8381 ################################### MAIN ###################################### #設置Redis集羣代理端口 port 7777 #綁定地址,經過聲明多行綁定來綁定多個接口 bind 192.168.163.134 bind 127.0.0.1 # Unix套接字的路徑 unixsocket /usr/local/redis-cluster-proxy/proxy.socket # 設置Unix套接字權限 unixsocketperm 760 # 設置線程數 threads 8 #TCP活躍鏈接時間,默認300秒 tcpkeepalive 300 #TCP鏈接中已完成隊列(完成三次握手以後)的長度 tcp-backlog 511 #鏈接池的大小,使用0徹底禁用鏈接池,每一個線程都有其隨時可用的鏈接池。 當代理啓動時,每一個線程將填充一個池,該池包含與集羣全部節點的鏈接。 每當客戶端須要專用鏈接時,它均可以從池中創建鏈接(若是有)。 這將加速客戶端從線程的共享鏈接到其本身的專用鏈接的轉換,由於來自線程池的鏈接應該已經鏈接而且可使用。 不然,具備優先鏈接的客戶端必須從新鏈接羣集的節點(這種從新鏈接將以「惰性」方式進行) connections-pool-size 10 #鏈接池中最小鏈接數。 低於此值,線程將以定義的速率開始從新生成鏈接,直到池再次變滿。 connections-pool-min-size 10 #用於從新生成池中鏈接的時間間隔(以毫秒爲單位),當池中的鏈接數降低到最小值如下(connections-pool-min-size)時,線程將開始從新分配池中的鏈接,直到池再次充滿。 新鏈接將按此指定間隔添加。 connections-pool-spawn-every 50 #在每一個週期中從新生成的鏈接數,每一個週期的間隔由connections-pool-spawn-every定義 connections-pool-spawn-rate 50 # 後臺運行 daemonize yes #pid文件路徑 pidfile /usr/local/redis-cluster-proxy/redis-cluster-proxy.pid #指定日誌文件名,空字符串還可用於強制Redis Cluster Porxy登陸標準輸出。 若是使用標準輸出進行日誌記錄但進行守護進程,則日誌將發送到/dev/null logfile /usr/local/redis-cluster-proxy/proxy.log # 啓用使用不一樣插槽甚至不一樣節點的多個鍵的跨插槽查詢。 警告:這些查詢將破壞許多Redis命令的原子性設計。 注意:即便啓用了此功能,也不是全部命令都支持跨槽查詢 enable-cross-slot yes # 最大客戶端鏈接數 maxclients 10000 #若是集羣的節點受密碼保護,則用於在集羣上進行認證的認證密碼, 還用於獲取集羣的配置以及自動驗證代理與集羣自己的內部鏈接。 auth dba # 用戶認證,支持Redis 6.0 ACL auth-user dba ################################# LOGGING ##################################### # 日誌等級: debug, info, success, warning o error. log-level error # 轉儲從客戶端收到的查詢到日誌中(log-level debug) # dump-queries no # 轉儲緩衝區到日誌中(log-level debug) # dump-buffer no # 轉儲請求的隊列到日誌中(log-level debug) # dump-queues no
條件:
Host:192.168.163.134 Port:8379、8380、8381 # ACL User:dba Pwd:dba
啓動:
redis-cluster-proxy -c /usr/local/redis-cluster-proxy/proxy.conf
登錄:
redis-cli -h 127.0.0.1 -p 7777 127.0.0.1:7777>
管理:
> proxy help 1) PROXY <subcommand> arg arg ... arg 2) INFO [section] -- 查看Proxy信息 3) CONFIG GET <param> -- 查看Proxy參數 4) CONFIG SET <param> <value> -- 設置Proxy參數 5) MULTIPLEXING STATUS|OFF -- 獲取當前客戶端的多路複用狀態或將其關閉 6) COMMAND [type] -- 當前已知的列表命令可用於過濾(unsupported|crosslots-unsupported) 7) CLIENT <subcmd> -- 執行特定於客戶的操做(有關詳細信息,請鍵入「PROXY CLIENT HELP」: PROXY CLIENT ID(獲取當前客戶端id),PROXY CLIENT THREAD(獲取當前線程)) 8) CLUSTER [subcmd] -- 執行特定於羣集的操做(有關詳細信息,請鍵入「PROXY CLUSTER HELP」:INFO、STATUS、CONNECTION、NODES、UPDATE) 9) DEBUG <subcmd> -- 用於調試代理的實用程序(更多信息,請鍵入「PROXY DEBUG HELP」) 10) SHUTDOWN [ASAP] -- 關閉代理。 若是使用`ASAP`,請當即執行(不安全退出),不然發送SIGINT。 11) LOG [level] <message> -- 將消息記錄到日誌中,以進行調試 > PROXY CLIENT HELP 1) PROXY CLIENT <subcommand> [arg arg ... arg] 2) ID -- 獲取客戶端內部ID 3) THREAD -- 獲取當前客戶端的線程ID > PROXY CLUSTER HELP 1) PROXY CLUSTER [subcommand] 2) -,INFO -- 獲取與調用客戶端關聯的集羣的信息 3) STATUS -- 獲取與呼叫客戶端關聯的羣集的狀態。 狀態能夠是:更新(updated)|更新(updating)|中斷(broken) 4) CONNECTION -- 獲取與調用客戶端關聯的羣集的鏈接類型。 類型能夠是:公有(shared)|私有(private) 5) NODES -- 獲取與調用客戶端關聯的羣集的主節點列表。 類型能夠是:公有(shared)|私有(private) 6) UPDATE -- 請求更新與當前客戶端關聯的羣集的配置。 > PROXY DEBUG HELP 1) PROXY DEBUG <subcommand> [ARGS...] 2) SEGFAULT -- Cause a SEGFAULT on the proxy 3) ASSERT -- Cause an assertion failure on the proxy 4) KILL <thread> [sig] -- Send signal to thread (can be MAIN,SELF or the thread ID). Signal can be TERM,INT,KILL or a signal number.
測試:
①:管理命令測試
-- 設置參數 > proxy config get connections-pool-size 1) connections-pool-size 2) (integer) 10 > proxy config get enable-cross-slot 1) enable-cross-slot 2) (integer) 0 > proxy config set enable-cross-slot 1 OK > proxy config set connections-pool-size 5 OK -- 查看Proxy信息 > proxy info # Proxy proxy_version:999.999.999 proxy_git_sha1:ac83840d proxy_git_dirty:0 proxy_git_branch:unstable os:Linux 4.15.0-99-generic x86_64 arch_bits:64 multiplexing_api:epoll gcc_version:7.5.0 process_id:64512 threads:8 tcp_port:7777 uptime_in_seconds:1262 uptime_in_days:0 config_file:/usr/local/redis-cluster-proxy/proxy.conf acl_user:dba unix_socket:/usr/local/redis-cluster-proxy/proxy.socket unix_socket_permissions:760 # Memory used_memory:6736984 used_memory_human:6.42M total_system_memory:2065895424 total_system_memory_human:1.92G # Clients connected_clients:1 max_clients:10000 thread_0_clinets:1 thread_1_clinets:0 thread_2_clinets:0 thread_3_clinets:0 thread_4_clinets:0 thread_5_clinets:0 thread_6_clinets:0 thread_7_clinets:0 # Cluster address:192.168.163.134:8379 entry_node:192.168.163.134:8379 -- 查看集羣信息 > proxy cluster info 1) status 2) updated 3) connection 4) shared 5) nodes 6) 1) 1) name 2) 91463f2fbb73cbbda4203fe88de465cafa0423fb 3) ip 4) 192.168.163.134 5) port 6) (integer) 8380 7) slots 8) (integer) 5462 9) replicas 10) (integer) 0 11) connected 12) (integer) 1 2) 1) name 2) afec09788ceeacad2b9c4d5cd92aa986e161d93e 3) ip 4) 192.168.163.134 5) port 6) (integer) 8379 7) slots 8) (integer) 5461 9) replicas 10) (integer) 1 11) connected 12) (integer) 1 3) 1) name 2) ff7a6f8ba650540cee8355f8042854b4131d49da 3) ip 4) 192.168.163.134 5) port 6) (integer) 8381 7) slots 8) (integer) 5461 9) replicas 10) (integer) 0 11) connected 12) (integer) 1
②:應用命令測試
127.0.0.1:7777> get a "a" 127.0.0.1:7777> 127.0.0.1:7777> get b "b" 127.0.0.1:7777> get c "c" 127.0.0.1:7777> get d "d" 127.0.0.1:7777> mget a b c d (error) ERR Cross-slot queries are disabled. They can be enabled by using the --enable-cross-slot option, or by calling `PROXY CONFIG SET enable-cross-slot 1`. WARN: cross-slot queries can break the atomicity of the query itself. 127.0.0.1:7777> PROXY CONFIG SET enable-cross-slot 1 OK 127.0.0.1:7777> mget a b c d 1) "a" 2) "b" 3) "c" 4) "d" 127.0.0.1:7777> mset a abc b cbd c cba d dba OK 127.0.0.1:7777> dbsize --支持全部節點key的彙總統計 (integer) 18 127.0.0.1:7777> SDIFF a b (error) ERR Cross-slot queries are not supported for this command 127.0.0.1:7777> SINTER a b (error) ERR Cross-slot queries are not supported for this command 127.0.0.1:7777> SMOVE a b (error) ERR Cross-slot queries are not supported for this command 127.0.0.1:7777> SUNION a b (error) ERR Cross-slot queries are not supported for this command 127.0.0.1:7777> hmget hd (error) ERR wrong number of arguments for 'hmget' command 127.0.0.1:7777> rename a aaaaa (error) ERR Cross-slot queries are not supported for this command
說明:經過測試發現,redis-cluster-proxy可使用mset、mget、dbsize等跨節點和slot的操做,還有一些操做都不支持。
③:更多測試
目前沒有使用redis-cluster-proxy,等須要的時候再作測試。若是正打算用的同窗須要作更多的功能和性能測試。
④:更多的問題
好比如何避免Proxy的單點,Proxy的配置優化等等。
目前Redis之父在本身博客裏聲明:退出開源項目維護,將 Redis 交給 Redis 社區。我的感受後面Redis 社區會穩定和逐步完善本身的Proxy。拭目以待吧!