Redis 集群之Redis+Codis方案

【轉(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 服務。

image.png

Codis 3.x 由以下組件組成:
  1. Codis Server:基于 redis-3.2.8 分支開發(fā)客叉。增加了額外的數(shù)據(jù)結(jié)構(gòu)诵竭,以支持 slot 有關(guān)的操作以及數(shù)據(jù)遷移指令。具體的修改可以參考文檔 redis 的修改兼搏。

  2. Codis Proxy:客戶端連接的 Redis 代理服務, 實現(xiàn)了 Redis 協(xié)議卵慰。 除部分命令不支持以外(不支持的命令列表),表現(xiàn)的和原生的 Redis 沒有區(qū)別(就像 Twemproxy)佛呻。

    • 對于同一個業(yè)務集群而言裳朋,可以同時部署多個 codis-proxy 實例;
    • 不同 codis-proxy 之間由 codis-dashboard 保證狀態(tài)同步吓著。
  3. Codis Dashboard:集群管理工具鲤嫡,支持 codis-proxy、codis-server 的添加绑莺、刪除暖眼,以及據(jù)遷移等操作。在集群狀態(tài)發(fā)生改變時纺裁,codis-dashboard 維護集群下所有 codis-proxy 的狀態(tài)的一致性诫肠。

    • 對于同一個業(yè)務集群而言司澎,同一個時刻 codis-dashboard 只能有 0個或者1個;
    • 所有對集群的修改都必須通過 codis-dashboard 完成栋豫。
  4. Codis Admin:集群管理的命令行工具挤安。

    • 可用于控制 codis-proxy、codis-dashboard 狀態(tài)以及訪問外部存儲丧鸯。
  5. Codis FE:集群管理界面蛤铜。

    • 多個集群實例共享可以共享同一個前端展示頁面;
    • 通過配置文件管理后端 codis-dashboard 列表丛肢,配置文件可自動更新围肥。
  6. 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的槽位變化,會及時同步過來祠汇。如圖:


image.png
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 提供了強制刪除工具:

    1. 確認 codis-dashboard 進程已經(jīng)退出(很重要)呢蛤;
    2. 運行 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 工具進行移除:

    1. 確認 codis-proxy 進程已經(jīng)退出(很重要)静秆;
    2. 運行 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
image.png

可以看到添加的三個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掛掉了

image.png

可以看到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掛掉了會怎么樣。

image.png

可以看到费薄,并沒有將其他節(jié)點當成master的操作硝全,此時重啟7003就可以恢復當前組的集群狀態(tài),也不需要手動更改配置文件和手動加入組楞抡。

添加proxy
image.png
設(shè)置Slots
image.png

使用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ù)測試

image.png

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

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市竞慢,隨后出現(xiàn)的幾起案子先紫,更是在濱河造成了極大的恐慌,老刑警劉巖筹煮,帶你破解...
    沈念sama閱讀 221,406評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件遮精,死亡現(xiàn)場離奇詭異,居然都是意外死亡败潦,警方通過查閱死者的電腦和手機本冲,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,395評論 3 398
  • 文/潘曉璐 我一進店門准脂,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人眼俊,你說我怎么就攤上這事意狠。” “怎么了疮胖?”我有些...
    開封第一講書人閱讀 167,815評論 0 360
  • 文/不壞的土叔 我叫張陵环戈,是天一觀的道長。 經(jīng)常有香客問我澎灸,道長院塞,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 59,537評論 1 296
  • 正文 為了忘掉前任性昭,我火速辦了婚禮拦止,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘糜颠。我一直安慰自己汹族,他們只是感情好,可當我...
    茶點故事閱讀 68,536評論 6 397
  • 文/花漫 我一把揭開白布其兴。 她就那樣靜靜地躺著顶瞒,像睡著了一般。 火紅的嫁衣襯著肌膚如雪元旬。 梳的紋絲不亂的頭發(fā)上榴徐,一...
    開封第一講書人閱讀 52,184評論 1 308
  • 那天,我揣著相機與錄音匀归,去河邊找鬼坑资。 笑死,一個胖子當著我的面吹牛穆端,可吹牛的內(nèi)容都是我干的袱贮。 我是一名探鬼主播,決...
    沈念sama閱讀 40,776評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼体啰,長吁一口氣:“原來是場噩夢啊……” “哼攒巍!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起狡赐,我...
    開封第一講書人閱讀 39,668評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎钦幔,沒想到半個月后枕屉,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,212評論 1 319
  • 正文 獨居荒郊野嶺守林人離奇死亡鲤氢,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,299評論 3 340
  • 正文 我和宋清朗相戀三年搀擂,在試婚紗的時候發(fā)現(xiàn)自己被綠了西潘。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,438評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡哨颂,死狀恐怖喷市,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情威恼,我是刑警寧澤品姓,帶...
    沈念sama閱讀 36,128評論 5 349
  • 正文 年R本政府宣布,位于F島的核電站箫措,受9級特大地震影響腹备,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜斤蔓,卻給世界環(huán)境...
    茶點故事閱讀 41,807評論 3 333
  • 文/蒙蒙 一植酥、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧弦牡,春花似錦友驮、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,279評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至稻据,卻和暖如春艾猜,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背捻悯。 一陣腳步聲響...
    開封第一講書人閱讀 33,395評論 1 272
  • 我被黑心中介騙來泰國打工匆赃, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人今缚。 一個月前我還...
    沈念sama閱讀 48,827評論 3 376
  • 正文 我出身青樓算柳,卻偏偏與公主長得像,于是被迫代替她去往敵國和親姓言。 傳聞我的和親對象是個殘疾皇子瞬项,可洞房花燭夜當晚...
    茶點故事閱讀 45,446評論 2 359