【轉(zhuǎn)載請注明出處】:http://www.reibang.com/p/41f97c494fc4
Redis 集群解決方案有哪些
Redis 的集群解決方案有社區(qū)的,也有官方的怜跑,社區(qū)的解決方案有 Codis 和Twemproxy柿顶,Codis是由我國的豌豆莢團隊開源的独旷,Twemproxy是Twitter團隊的開源的埃脏;官方的集群解決方案就是 Redis Cluster障般,這是由 Redis 官方團隊來實現(xiàn)的默勾。下面的列表可以很明顯地表達出三者的不同點袍镀。
Codis | Twemproxy | Redis Cluster | |
---|---|---|---|
resharding without restarting cluster | Yes | No | Yes |
pipeline | Yes | Yes | No |
hash tags for multi-key operations | Yes | Yes | Yes |
multi-key operations while resharding | Yes | - | No(details) |
Redis clients supporting | Any clients | Any clients | Clients have to support cluster protocol |
codis和twemproxy最大的區(qū)別有兩個:
- codis支持動態(tài)水平擴展,對client完全透明不影響服務的情況下可以完成增減redis實例的操作;
- codis是用go語言寫的并支持多線程漱办,twemproxy用C并只用單線程这刷。 后者又意味著:codis在多核機器上的性能會好于twemproxy;codis的最壞響應時間可能會因為GC的STW而變大娩井,不過go1.5發(fā)布后會顯著降低STW的時間暇屋;如果只用一個CPU的話go語言的性能不如C,因此在一些短連接而非長連接的場景中洞辣,整個系統(tǒng)的瓶頸可能變成accept新tcp連接的速度咐刨,這時codis的性能可能會差于twemproxy。
codis和redis cluster的區(qū)別:
- redis cluster基于smart client和無中心的設(shè)計扬霜,client必須按key的哈希將請求直接發(fā)送到對應的節(jié)點定鸟。這意味著:使用官方cluster必須要等對應語言的redis driver對cluster支持的開發(fā)和不斷成熟;client不能直接像單機一樣使用pipeline來提高效率著瓶,想同時執(zhí)行多個請求來提速必須在client端自行實現(xiàn)異步邏輯联予。 而codis因其有中心節(jié)點、基于proxy的設(shè)計材原,對client來說可以像對單機redis一樣去操作proxy(除了一些命令不支持)沸久,還可以繼續(xù)使用pipeline并且如果后臺redis有多個的話速度會顯著快于單redis的pipeline。
- codis使用zookeeper來作為輔助余蟹,這意味著單純對于redis集群來說需要額外的機器搭zk卷胯。
Codis介紹
Codis 是一個分布式 Redis 解決方案, 對于上層的應用來說, 連接到 Codis Proxy 和連接原生的 Redis Server 沒有顯著區(qū)別 (不支持的命令列表), 上層應用可以像使用單機的 Redis 一樣使用, Codis 底層會處理請求的轉(zhuǎn)發(fā), 不停機的數(shù)據(jù)遷移等工作, 所有后邊的一切事情, 對于前面的客戶端來說是透明的, 可以簡單的認為后邊連接的是一個內(nèi)存無限大的 Redis 服務。
Codis 3.x 由以下組件組成:
Codis Server:基于 redis-3.2.8 分支開發(fā)客叉。增加了額外的數(shù)據(jù)結(jié)構(gòu)诵竭,以支持 slot 有關(guān)的操作以及數(shù)據(jù)遷移指令。具體的修改可以參考文檔 redis 的修改兼搏。
-
Codis Proxy:客戶端連接的 Redis 代理服務, 實現(xiàn)了 Redis 協(xié)議卵慰。 除部分命令不支持以外(不支持的命令列表),表現(xiàn)的和原生的 Redis 沒有區(qū)別(就像 Twemproxy)佛呻。
- 對于同一個業(yè)務集群而言裳朋,可以同時部署多個 codis-proxy 實例;
- 不同 codis-proxy 之間由 codis-dashboard 保證狀態(tài)同步吓著。
-
Codis Dashboard:集群管理工具鲤嫡,支持 codis-proxy、codis-server 的添加绑莺、刪除暖眼,以及據(jù)遷移等操作。在集群狀態(tài)發(fā)生改變時纺裁,codis-dashboard 維護集群下所有 codis-proxy 的狀態(tài)的一致性诫肠。
- 對于同一個業(yè)務集群而言司澎,同一個時刻 codis-dashboard 只能有 0個或者1個;
- 所有對集群的修改都必須通過 codis-dashboard 完成栋豫。
-
Codis Admin:集群管理的命令行工具挤安。
- 可用于控制 codis-proxy、codis-dashboard 狀態(tài)以及訪問外部存儲丧鸯。
-
Codis FE:集群管理界面蛤铜。
- 多個集群實例共享可以共享同一個前端展示頁面;
- 通過配置文件管理后端 codis-dashboard 列表丛肢,配置文件可自動更新围肥。
-
Storage:為集群狀態(tài)提供外部存儲。
- 提供 Namespace 概念蜂怎,不同集群的會按照不同 product name 進行組織虐先;
- 目前僅提供了 Zookeeper、Etcd派敷、Fs 三種實現(xiàn),但是提供了抽象的 interface 可自行擴展撰洗。
Codis 分片原理
在Codis中篮愉,Codis會把所有的key分成1024個槽,這1024個槽對應著的就是Redis的集群差导,這個在Codis中是會在內(nèi)存中維護著這1024個槽與Redis實例的映射關(guān)系试躏。這個槽是可以配置,可以設(shè)置成 2048 或者是4096個设褐〉咴蹋看你的Redis的節(jié)點數(shù)量有多少,偏多的話助析,可以設(shè)置槽多一些犀被。
Codis中key的分配算法,先是把key進行CRC32 后外冀,得到一個32位的數(shù)字寡键,然后再hash%1024后得到一個余數(shù),這個值就是這個key對應著的槽雪隧,這槽后面對應著的就是redis的實例西轩。
CRC32:CRC本身是“冗余校驗碼”的意思,CRC32則表示會產(chǎn)生一個32bit(8位十六進制數(shù))的校驗值脑沿。由于CRC32產(chǎn)生校驗值時源數(shù)據(jù)塊的每一個bit(位)都參與了計算藕畔,所以數(shù)據(jù)塊中即使只有一位發(fā)生了變化,也會得到不同的CRC32值庄拇。
Codis之間的槽位同步
Codis把槽位信息同步的工作交給了ZooKeeper來管理注服,當Codis的Codis Dashbord 改變槽位的信息的時候,其他的Codis節(jié)點會監(jiān)聽到ZooKeeper的槽位變化,會及時同步過來祠汇。如圖:
Codis中的擴容
因為Codis是一個代理中間件仍秤,所以這個當需要擴容Redis實例的時候,可以直接增加redis節(jié)點可很。在槽位分配的時候诗力,可以手動指定Codis Dashbord來為新增的節(jié)點來分配特定的槽位。
在Codis中實現(xiàn)了自定義的掃描指令SLOTSSCAN我抠,可以掃描指定的slot下的所有的key苇本,將這些key遷移到新的Redis的節(jié)點中(話外語:這個是Codis定制化的其中一個好處)。
首先菜拓,在遷移的時候瓣窄,會在原來的Redis節(jié)點和新的Redis里都保存著遷移的槽位信息,在遷移的過程中纳鼎,如果有key打進將要遷移或者正在遷移的舊槽位的時候俺夕,這個時候Codis的處理機制是,先是將這個key強制遷移到新的Redis節(jié)點中贱鄙,然后再告訴Codis,下次如果有新的key的打在這個槽位中的話劝贸,那么轉(zhuǎn)發(fā)到新的節(jié)點。
自動均衡策略
面對著上面講的遷移策略逗宁,如果有成千上萬個節(jié)點新增進來映九,都需要我們手動去遷移嗎?那豈不是得累死啊瞎颗。當然件甥,Codis也是考慮到了這一點,所以提供了自動均衡策略哼拔。自動均衡策略是這樣的引有,Codis 會在機器空閑的時候,觀察Redis中的實例對應著的slot數(shù)管挟,如果不平衡的話就會自動進行遷移轿曙。
Codis安裝
依賴環(huán)境準備
下面這兩個依賴環(huán)境的搭建這里不再介紹。
- 安裝Zookeeper
- 安裝Go
1. 下載Codis安裝包
在官方的發(fā)布頁找到最新的發(fā)布版本下載最新版3.2.2僻孝,如需要編譯安裝請參考官方的編譯安裝說明导帝。
下載安裝包之后解壓并重命名目錄,進入解壓目錄創(chuàng)建config
文件夾用來放置配置文件地址穿铆,創(chuàng)建logs
文件夾將來放日志文件您单。
2.安裝codis-dashboard(集群管理工具)
在config
文件夾中創(chuàng)建配置文件dashboard.toml
(這些配置文件模板在源碼config
目錄中可以找到),文件內(nèi)容:
##################################################
# #
# Codis-Dashboard #
# #
##################################################
# Set Coordinator, only accept "zookeeper" & "etcd" & "filesystem".
# for zookeeper/etcd, coorinator_auth accept "user:password"
# Quick Start
#coordinator_name = "filesystem"
#coordinator_addr = "/tmp/codis"
coordinator_name = "zookeeper"
coordinator_addr = "zk1:2181,zk2:2182,zk3:2183"
coordinator_auth = ""
# Set Codis Product Name/Auth.
product_name = "codis-demo"
product_auth = ""
# Set bind address for admin(rpc), tcp only.
admin_addr = "0.0.0.0:18080"
# Set arguments for data migration (only accept 'sync' & 'semi-async').
migration_method = "semi-async"
migration_parallel_slots = 100
migration_async_maxbulks = 200
migration_async_maxbytes = "32mb"
migration_async_numkeys = 500
migration_timeout = "30s"
# Set configs for redis sentinel.
sentinel_client_timeout = "10s"
sentinel_quorum = 2
sentinel_parallel_syncs = 1
sentinel_down_after = "30s"
sentinel_failover_timeout = "5m"
sentinel_notification_script = ""
sentinel_client_reconfig_script = ""
為了方便管理創(chuàng)建啟動腳本start-dashboard.sh
荞雏,腳本內(nèi)容:
#!/bin/sh
#set -x
nohup ./codis-dashboard --ncpu=4 --config=./config/dashboard.toml --log=./logs/dashboard.log --log-level=WARN &>/dev/null &
執(zhí)行啟動腳本啟動dashboard虐秦,然后瀏覽器訪問18080端口已經(jīng)可以返回當前集群信息平酿。
啟動參數(shù)說明:
$ ./codis-dashboard -h
Usage:
codis-dashboard [--ncpu=N] [--config=CONF] [--log=FILE] [--log-level=LEVEL] [--host-admin=ADDR]
codis-dashboard --default-config
codis-dashboard --version
Options:
--ncpu=N 最大使用 CPU 個數(shù)
-c CONF, --config=CONF 指定啟動配置文件
-l FILE, --log=FILE 設(shè)置 log 輸出文件
--log-level=LEVEL 設(shè)置 log 輸出等級:INFO,WARN,DEBUG,ERROR盈厘;默認INFO羡忘,推薦WARN
默認配置文件:
$ ./codis-dashboard --default-config | tee dashboard.toml
##################################################
# #
# Codis-Dashboard #
# #
##################################################
# Set Coordinator, only accept "zookeeper" & "etcd"
coordinator_name = "zookeeper"
coordinator_addr = "127.0.0.1:2181"
# Set Codis Product {Name/Auth}.
product_name = "codis-demo"
product_auth = ""
# Set bind address for admin(rpc), tcp only.
admin_addr = "0.0.0.0:18080"
參數(shù) | 說明 |
---|---|
coordinator_name | 外部存儲類型,接受 zookeeper/etcd |
coordinator_addr | 外部存儲地址 |
product_name | 集群名稱总滩,滿足正則 \w[\w.-]* |
product_auth | 集群密碼俺驶,默認為空 |
admin_addr | RESTful API 端口 |
3.安裝codis-proxy(客戶端連接的 Redis 代理服務)
在config
文件夾中創(chuàng)建配置文件proxy.toml
幸逆,文件內(nèi)容:
##################################################
# #
# Codis-Proxy #
# #
##################################################
# Set Codis Product Name/Auth.
product_name = "codis-demo"
product_auth = ""
# Set auth for client session
# 1. product_auth is used for auth validation among codis-dashboard,
# codis-proxy and codis-server.
# 2. session_auth is different from product_auth, it requires clients
# to issue AUTH <PASSWORD> before processing any other commands.
session_auth = ""
# Set bind address for admin(rpc), tcp only.
admin_addr = "0.0.0.0:11080"
# Set bind address for proxy, proto_type can be "tcp", "tcp4", "tcp6", "unix" or "unixpacket".
proto_type = "tcp4"
proxy_addr = "0.0.0.0:19000"
# Set jodis address & session timeout
# 1. jodis_name is short for jodis_coordinator_name, only accept "zookeeper" & "etcd".
# 2. jodis_addr is short for jodis_coordinator_addr
# 3. jodis_auth is short for jodis_coordinator_auth, for zookeeper/etcd, "user:password" is accepted.
# 4. proxy will be registered as node:
# if jodis_compatible = true (not suggested):
# /zk/codis/db_{PRODUCT_NAME}/proxy-{HASHID} (compatible with Codis2.0)
# or else
# /jodis/{PRODUCT_NAME}/proxy-{HASHID}
jodis_name = "zookeeper"
jodis_addr = "zk1:2181,zk2:2182,zk3:2183"
jodis_auth = ""
jodis_timeout = "20s"
jodis_compatible = false
# Set datacenter of proxy.
proxy_datacenter = ""
# Set max number of alive sessions.
proxy_max_clients = 1000
# Set max offheap memory size. (0 to disable)
proxy_max_offheap_size = "1024mb"
# Set heap placeholder to reduce GC frequency.
proxy_heap_placeholder = "256mb"
# Proxy will ping backend redis (and clear 'MASTERDOWN' state) in a predefined interval. (0 to disable)
backend_ping_period = "5s"
# Set backend recv buffer size & timeout.
backend_recv_bufsize = "128kb"
backend_recv_timeout = "30s"
# Set backend send buffer & timeout.
backend_send_bufsize = "128kb"
backend_send_timeout = "30s"
# Set backend pipeline buffer size.
backend_max_pipeline = 20480
# Set backend never read replica groups, default is false
backend_primary_only = false
# Set backend parallel connections per server
backend_primary_parallel = 1
backend_replica_parallel = 1
# Set backend tcp keepalive period. (0 to disable)
backend_keepalive_period = "75s"
# Set number of databases of backend.
backend_number_databases = 16
# If there is no request from client for a long time, the connection will be closed. (0 to disable)
# Set session recv buffer size & timeout.
session_recv_bufsize = "128kb"
session_recv_timeout = "30m"
# Set session send buffer size & timeout.
session_send_bufsize = "64kb"
session_send_timeout = "30s"
# Make sure this is higher than the max number of requests for each pipeline request, or your client may be blocked.
# Set session pipeline buffer size.
session_max_pipeline = 10000
# Set session tcp keepalive period. (0 to disable)
session_keepalive_period = "75s"
# Set session to be sensitive to failures. Default is false, instead of closing socket, proxy will send an error response to client.
session_break_on_failure = false
# Set metrics server (such as http://localhost:28000), proxy will report json formatted metrics to specified server in a predefined period.
metrics_report_server = ""
metrics_report_period = "1s"
# Set influxdb server (such as http://localhost:8086), proxy will report metrics to influxdb.
metrics_report_influxdb_server = ""
metrics_report_influxdb_period = "1s"
metrics_report_influxdb_username = ""
metrics_report_influxdb_password = ""
metrics_report_influxdb_database = ""
# Set statsd server (such as localhost:8125), proxy will report metrics to statsd.
metrics_report_statsd_server = ""
metrics_report_statsd_period = "1s"
metrics_report_statsd_prefix = ""
編寫啟動腳本start-proxy.sh
,文件內(nèi)容:
#!/bin/sh
#set -x
nohup ./codis-proxy --ncpu=4 --config=./config/proxy.toml --log=./logs/proxy.log --log-level=WARN &>/dev/null &
執(zhí)行啟動腳本暮现,然后訪問11080
端口可以查看代理信息还绘。
codis-proxy 啟動后,處于 waiting 狀態(tài)栖袋,監(jiān)聽 proxy_addr 地址拍顷,但是不會 accept 連接,添加到集群并完成集群狀態(tài)的同步塘幅,才能改變狀態(tài)為 online昔案。添加的方法有以下兩種:
- 通過 codis-fe 添加:通過 Add Proxy 按鈕,將 admin_addr 加入到集群中电媳;
- 通過 codis-admin 命令行工具添加爱沟,方法如下:
$ ./codis-admin --dashboard=127.0.0.1:18080 --create-proxy -x 127.0.0.1:11080
其中 127.0.0.1:18080 以及 127.0.0.1:11080 分別為 dashboard 和 proxy 的admin_addr
地址;
添加過程中匆背,dashboard 會完成如下一系列動作:
- 獲取 proxy 信息,對集群 name 以及 auth 進行驗證身冀,并將其信息寫入到外部存儲中钝尸;
- 同步 slots 狀態(tài);
- 標記 proxy 狀態(tài)為 online搂根,此后 proxy 開始 accept 連接并開始提供服務珍促;
啟動參數(shù)說明:
$ ./codis-proxy -h
Usage:
codis-proxy [--ncpu=N] [--config=CONF] [--log=FILE] [--log-level=LEVEL] [--host-admin=ADDR] [--host-proxy=ADDR] [--ulimit=NLIMIT]
codis-proxy --default-config
codis-proxy --version
Options:
--ncpu=N 最大使用 CPU 個數(shù)
-c CONF, --config=CONF 指定啟動配置文件
-l FILE, --log=FILE 設(shè)置 log 輸出文件
--log-level=LEVEL 設(shè)置 log 輸出等級:INFO,WARN,DEBUG,ERROR;默認INFO剩愧,推薦WARN
--ulimit=NLIMIT 檢查 ulimit -n 的結(jié)果猪叙,確保運行時最大文件描述不少于 NLIMIT
默認配置文件:
$ ./codis-proxy --default-config | tee proxy.toml
##################################################
# #
# Codis-Proxy #
# #
##################################################
# Set Codis Product {Name/Auth}.
product_name = "codis-demo"
product_auth = ""
# Set bind address for admin(rpc), tcp only.
admin_addr = "0.0.0.0:11080"
# Set bind address for proxy, proto_type can be "tcp", "tcp4", "tcp6", "unix" or "unixpacket".
proto_type = "tcp4"
proxy_addr = "0.0.0.0:19000"
# Set jodis address & session timeout.
jodis_addr = ""
jodis_timeout = 10
jodis_compatible = false
# Proxy will ping-pong backend redis periodly to keep-alive
backend_ping_period = 5
# If there is no request from client for a long time, the connection will be droped. Set 0 to disable.
session_max_timeout = 1800
# Buffer size for each client connection.
session_max_bufsize = 131072
# Number of buffered requests for each client connection.
# Make sure this is higher than the max number of requests for each pipeline request, or your client may be blocked.
session_max_pipeline = 1024
# Set period between keep alives. Set 0 to disable.
session_keepalive_period = 60
參數(shù) | 說明 |
---|---|
product_name | 集群名稱,參考 dashboard 參數(shù)說明 |
product_auth | 集群密碼仁卷,默認為空 |
admin_addr | RESTful API 端口 |
proto_type | Redis 端口類型穴翩,接受 tcp/tcp4/tcp6/unix/unixpacket |
proxy_addr | Redis 端口地址或者路徑 |
jodis_addr | Jodis 注冊 zookeeper 地址 |
jodis_timeout | Jodis 注冊 session timeout 時間,單位 second |
jodis_compatible | Jodis 注冊 zookeeper 的路徑 |
backend_ping_period | 與 codis-server 探活周期锦积,單位 second芒帕,0 表示禁止 |
session_max_timeout | 與 client 連接最大讀超時,單位 second丰介,0 表示禁止 |
session_max_bufsize | 與 client 連接讀寫緩沖區(qū)大小背蟆,單位 byte |
session_max_pipeline | 與 client 連接最大的 pipeline 大小 |
session_keepalive_period | 與 client 的 tcp keepalive 周期鉴分,僅 tcp 有效,0 表示禁止 |
注:Codis3 會將 jodis 節(jié)點注冊在 /jodis/{PRODUCT_NAME} 下带膀,這點與 Codis2 不太兼容志珍,所以為了兼容性,可以考慮將 jodis_compatible 設(shè)置成 true垛叨。
4.安裝codis-server(優(yōu)化版的Redis)
codis-server的配置文件和redis一樣伦糯,其本身就是在redis上改進而來。
創(chuàng)建配置文件config/codis-server/7001/redis.conf
点额,文件內(nèi)容:
bind 127.0.0.1
port 7001
daemonize no
pidfile /var/run/codis_7001.pid
logfile "./logs/codis-server/7001/redis.log"
save 900 1
save 300 10
save 60 10000
dir ./config/codis-server/7001
appendonly yes
appendfsync always
創(chuàng)建啟動腳本start-server-7001.sh
舔株,腳本內(nèi)容:
#!/bin/sh
#set -x
nohup ./codis-server ./config/codis-server/7001/redis.conf &>/dev/null &
同樣的方法可以配置多個codis-server。
啟動完成后还棱,可以通過 codis-fe 提供的界面或者 codis-admin 命令行工具添加到集群中载慈。
5.啟動codis-fe(集群管理界面)
這是個可選組件,也可以通過codis-admin命令行工具來管理集群珍手。
編寫啟動腳本start-fe.sh
办铡,腳本內(nèi)容:
#!/bin/sh
#set -x
nohup ./codis-fe --ncpu=1 --log=./logs/fe.log --log-level=WARN --zookeeper=zk1:2181,zk2:2182,zk3:2183 --listen=0.0.0.0:8090 &>/dev/null &
執(zhí)行啟動腳本,然后訪問8090端口即可看到集群管理界面琳要。
啟動參數(shù)說明:
$ ./codis-fe -h
Usage:
codis-fe [--ncpu=N] [--log=FILE] [--log-level=LEVEL] [--assets-dir=PATH] (--dashboard-list=FILE|--zookeeper=ADDR|--etcd=ADDR|--filesystem=ROOT) --listen=ADDR
codis-fe --version
Options:
--ncpu=N 最大使用 CPU 個數(shù)
-d LIST, --dashboard-list=LIST 配置文件寡具,能夠自動刷新
-l FILE, --log=FILE 設(shè)置 log 輸出文件
--log-level=LEVEL 設(shè)置 log 輸出等級:INFO,WARN,DEBUG,ERROR;默認INFO稚补,推薦WARN
--listen=ADDR HTTP 服務端口
配置文件 codis.json 可以手動編輯童叠,也可以通過 codis-admin 從外部存儲中拉取,例如:
$ ./codis-admin --dashboard-list --zookeeper=127.0.0.1:2181 | tee codis.json
[
{
"name": "codis-demo",
"dashboard": "127.0.0.1:18080"
},
{
"name": "codis-demo2",
"dashboard": "127.0.0.1:28080"
}
]
6.使用codis-admin(集群管理的命令行工具)
執(zhí)行./codis-admin -h
可以查看可執(zhí)行的命令及參數(shù)课幕。
-
dashboard服務和proxy服務的停用
./codis-admin --proxy=127.0.0.1:11080 --shutdown ./codis-admin --dashboard=127.0.0.1:18080 --shutdown
-
codis-dashboard 異常退出的修復
當 codis-dashboard 啟動時厦坛,會在外部存儲上存放一條數(shù)據(jù),用于存儲 dashboard 信息乍惊,同時作為 LOCK 存在杜秸。當 codis-dashboard 安全退出時,會主動刪除該數(shù)據(jù)润绎。當 codis-dashboard 異常退出時撬碟,由于之前 LOCK 未安全刪除,重啟往往會失敗莉撇。因此 codis-admin 提供了強制刪除工具:- 確認 codis-dashboard 進程已經(jīng)退出(很重要)呢蛤;
- 運行 codis-admin 刪除 LOCK:
./codis-admin --remove-lock --product=codis-demo --zookeeper=zk1:2181,zk2:2182,zk3:2183
-
codis-proxy 異常退出的修復
通常 codis-proxy 都是通過 codis-dashboard 進行移除,移除過程中 codis-dashboard 為了安全會向 codis-proxy 發(fā)送offline
指令棍郎,成功后才會將 proxy 信息從外部存儲中移除顾稀。如果 codis-proxy 異常退出,該操作會失敗坝撑。此時可以使用 codis-admin 工具進行移除:- 確認 codis-proxy 進程已經(jīng)退出(很重要)静秆;
- 運行 codis-admin 刪除 proxy:
$ ./codis-admin --dashboard=127.0.0.1:18080 --remove-proxy --addr=127.0.0.1:11080 --force
選項
--force
表示粮揉,無論offline
操作是否成功,都從外部存儲中將該節(jié)點刪除抚笔。所以操作前扶认,一定要確認該 codis-proxy 進程已經(jīng)退出。
7.配置codis-ha
創(chuàng)建啟動腳本start-ha.sh
殊橙,腳本內(nèi)容:
#!/bin/sh
#set -x
nohup ./codis-ha --log=./logs/ha.log --log-level=WARN --dashboard=127.0.0.1:18080 &>/dev/null &
因為 codis-proxy 是無狀態(tài)的辐宾,可以比較容易的搭多個實例,達到高可用性和橫向擴展膨蛮。
對 Java 用戶來說叠纹,可以使用基于 Jedis 的實現(xiàn) Jodis ,來實現(xiàn) proxy 層的 HA:
- 它會通過監(jiān)控 zookeeper 上的注冊信息來實時獲得當前可用的 proxy 列表敞葛,既可以保證高可用性誉察;
- 也可以通過輪流請求所有的proxy實現(xiàn)負載均衡。
如果需要異步請求惹谐,可以使用基于Netty開發(fā)的 Nedis持偏。
對下層的 redis 實例來說,當一個 group 的 master 掛掉的時候氨肌,應該讓管理員清楚鸿秆,并手動的操作,因為這涉及到了數(shù)據(jù)一致性等問題(redis的主從同步是最終一致性的)怎囚。因此 codis 不會自動的將某個 slave 升級成 master卿叽。
關(guān)于外部 codis-ha 工具,這是一個通過 codis-dashboard 開放的 RESTful API 實現(xiàn)自動切換主從的工具恳守。該工具會在檢測到 master 掛掉的時候主動應用主從切換策略附帽,提升單個 slave 成為新的 master。
需要注意井誉,codis 將其中一個 slave 升級為 master 時,該組內(nèi)其他 slave 實例是不會自動改變狀態(tài)的整胃,這些 slave 仍將試圖從舊的 master 上同步數(shù)據(jù)颗圣,因而會導致組內(nèi)新的 master 和其他 slave 之間的數(shù)據(jù)不一致。因此當出現(xiàn)主從切換時屁使,需要管理員手動創(chuàng)建新的 sync action 來完成新 master 與 slave 之間的數(shù)據(jù)同步(codis-ha 不提供自動操作的工具在岂,因為這樣太不安全了)。
Codis使用
訪問http://IP:8090打開集群管理蛮寂,左側(cè)的菜單顯示了codis集群列表蔽午。
添加組和sever
可以看到添加的三個codis-sever中7002是master,7001和7003是slave酬蹋,這里的主從關(guān)系不用在配置文件中來配置主從關(guān)系及老,codis會自己配置主從抽莱,可以使用redis客戶端做個測試:
$ ./redis-cli -c -p 7002
127.0.0.1:7002> set k1 v1
OK
127.0.0.1:7002> set k2 v2
OK
127.0.0.1:7002> exit
$ ./redis-cli -c -p 7001
127.0.0.1:7001> get k1
"v1"
127.0.0.1:7001> get k2
"v2"
127.0.0.1:7001> set k3 v3
# (error) READONLY You can't write against a read only slave.
127.0.0.1:7001> exit
$ ./redis-cli -c -p 7003
127.0.0.1:7003> get k1
"v1"
127.0.0.1:7003> get k2
"v2"
127.0.0.1:7003> set k3 v3
# (error) READONLY You can't write against a read only slave.
127.0.0.1:7003> exit
可以看到只能在master寫入,寫入的數(shù)據(jù)也同步到了slave上骄恶。此時去看7003和7001的配置文件發(fā)現(xiàn)codis自動在配置文件上加了slaveof 127.0.0.1 7002
食铐,假設(shè)此時master掛掉了
可以看到codis-ha自動將7003當成master,然后將7001和7002都停止了(進程不在)僧鲁,好危險虐呻,因為redis是最終一致性,此時的數(shù)據(jù)一致性也無法保證寞秃,而且將其他節(jié)點直接停止斟叼,此時的7003壓力將非常大。此時再將7001和7002重啟春寿,然后再次加入朗涩,發(fā)現(xiàn)codis會將這兩個實例再次停止,原因很簡單堂淡,因為原來7002是master馋缅,7001是7002的slave,配置并沒有變绢淀,不允許有兩個master萤悴,而且當前7003是master,因此需要手動更改配置文件才能加入這個組皆的。
假設(shè)現(xiàn)在沒有codis-ha覆履,master 7003掛掉了會怎么樣。
可以看到费薄,并沒有將其他節(jié)點當成master的操作硝全,此時重啟7003就可以恢復當前組的集群狀態(tài),也不需要手動更改配置文件和手動加入組楞抡。
添加proxy
設(shè)置Slots
使用redis客戶端連接proxy測試:
$ ./redis-cli -c -p 19000
127.0.0.1:19000> get k1
"v1"
127.0.0.1:19000> set k001 v001
OK
127.0.0.1:19000> get k001
"v001"
127.0.0.1:19000> exit
此時假設(shè)master 7003掛了(沒用codis-ha)會怎么樣伟众?
$ ./redis-cli -c -p 19000
127.0.0.1:19000> get k1
(error) ERR handle response, backend conn reset
127.0.0.1:19000> set k002 v002
(error) ERR handle response, backend conn reset
127.0.0.1:19000> exit
可以看到變成了既不可讀也不可寫了,這時啟動codis-ha繼續(xù)測試
codis-ha選擇了7001作為master召廷,使用redis客戶端連接proxy測試:
$ ./redis-cli -c -p 19000
127.0.0.1:19000> get k1
"v1"
127.0.0.1:19000> get k001
"v001"
127.0.0.1:19000> set k0002 v0002
OK
127.0.0.1:19000> get k0002
"v0002"
127.0.0.1:19000> exit
可以看到當前是可以讀也可以寫的凳厢。
【轉(zhuǎn)載請注明出處】:http://www.reibang.com/p/41f97c494fc4