【實踐】Redis 集群搭建

背景

在測試服務(wù)器(CentOS 系統(tǒng))上搭建 Redis 集群,這里一步步實踐并整理一些較好的步驟芋忿。

正文

簡單安裝請參照官方文檔:Redis Quick Start炸客。

  • 前提
  • 搭建
  • 測試
  • 維護

前提

在搭建集群之前,需要明確一下情況戈钢。

  • 版本
    目前安裝的是 3.2.11 版本痹仙,在有些 CentOS 上內(nèi)置的就是它,所以導(dǎo)致目前項目都用的這個版本逆趣。

  • 安裝
    默認的編譯安裝只需要使用 make install 命令蝶溶,所以依賴的無非是 gccgcc-c++ 這兩個編譯工具嗜历,install 命令也僅僅是將 redis-* 系列拷貝到 /usr/local/bin 目錄下宣渗。

  • 更正確的配置
    建立 /etc/redis/var/redis 目錄,拷貝 redis.conf/etc/redis/6380.conf梨州。
    6380.conf 中痕囱,bind 設(shè)為 192.168.1.57port 設(shè)為 6380暴匠,daemonize 設(shè)為 yes鞍恢,pidfile 指向 /var/run/redis_6380.pidlogfile 指向 /var/log/redis_6380.log每窖,dir 指向 /var/redis/6380帮掉。

搭建

有了前提條件,接下來就參考官方 Redis Cluster 文檔來實踐一番窒典。

  • 配置
  • 創(chuàng)建

配置

集群的配置稍微比【更正確的配置】要多一些蟆炊。

根據(jù) Redis Cluster 以及 redis.conf 中的解釋:

  • cluster-enable yes
    yes 表示在特定實例(以此配置文件啟動的實例)中啟用集群支持;no 表示作為獨立實例啟動瀑志。

  • cluster-config-file nodes.conf
    每個集群節(jié)點都有這個配置文件涩搓,但用戶不能手動編輯內(nèi)容,它是由節(jié)點自己創(chuàng)建和更新劈猪。每個節(jié)點需要有不同的配置文件昧甘,請確保同一個系統(tǒng)中的不同節(jié)點,不會覆蓋這個配置文件(即:不同的實例战得,配置文件中的 dir 必須指向不同的目錄)充边。

  • cluster-node-timeout 5000
    集群節(jié)點超時是節(jié)點在確認失敗的狀態(tài)下,持續(xù)不可訪問的毫秒總時長常侦,大多數(shù)其他內(nèi)部時間限制是節(jié)點超時的倍數(shù)浇冰。

  • cluster-slave-validity-factor 0
    對于主節(jié)點來說予弧,這個因數(shù)乘以超時值,表示主節(jié)點最終確認故障的時間范圍湖饱;對于從節(jié)點來說掖蛤,在因數(shù)乘以超時值的時間范圍內(nèi),將不會進行故障轉(zhuǎn)移(成為主節(jié)點)井厌。如果因數(shù)設(shè)為 0蚓庭,則始終在主節(jié)點不可用時進行故障切換,這也是唯一能保證最大可用性的參數(shù)仅仆。

  • cluster-migration-barrier 1
    默認是1器赞,表示所有主節(jié)點在正常狀態(tài)下,應(yīng)當保持的從節(jié)點數(shù)量墓拜。比如當前主節(jié)點擁有 2 個從節(jié)點港柜,另外有個主節(jié)點的從節(jié)點出現(xiàn)故障,又沒有其他從節(jié)點可用咳榜,此時當前主節(jié)點下的一個從節(jié)點會自動遷移到另外的主節(jié)點下夏醉。如果當前主節(jié)點只有 1 個從節(jié)點,那么將不會進行切換涌韩。這個值可以是 0畔柔,在調(diào)試時可用,但在生產(chǎn)中很危險臣樱。

  • cluster-require-full-coverage yes
    yes 是默認情況靶擦,表示只要有一個散列槽未被使用(沒有節(jié)點服務(wù)于它),那么集群將不可用雇毫;no 表示服務(wù)于其他散列槽的節(jié)點繼續(xù)接受查詢玄捕。

完整的配置參數(shù)如下:

bind 192.168.1.57
protected-mode yes
port 6380
tcp-backlog 511
timeout 0
tcp-keepalive 300
daemonize yes
supervised no
pidfile /var/run/redis_6380.pid
loglevel notice
logfile "/var/log/redis_6380.log"
database 16
save 900 1
save 300 10
save 60 10000
stop-writes-on-bgsave-error yes
rdbcompression yes
rdbchecksum yes
dbfilename dump.rdb
dir /var/redis/6380
slave-serve-stale-data yes
slave-read-only yes
repl-diskless-sync no
repl-diskless-sync-delay 5
repl-disable-tcp-nodelay on
slave-priority 100
appendonly yes
appendfilename "appendonly.aof"
appendfsync everysec
no-appendfsync-on-rewrite no
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb
aof-load-truncated yes
lua-time-limit 5000
cluster-enabled yes
cluster-config-file nodes.conf
cluster-node-timeout 5000
cluster-slave-validity-factor 0
cluster-migration-barrier 1
cluster-require-full-coverage yes
slowlog-log-slower-than 10000
slowlog-max-len 128
latency-monitor-threshold 0
notify-keyspace-events ""
hash-max-ziplist-entries 512
hash-max-ziplist-value 64
list-max-ziplist-size -2
list-compress-depth 0
set-max-intset-entries 512
zset-max-ziplist-entries 128
zset-max-ziplist-value 64
hll-sparse-max-bytes 3000
activerehashing yes
client-output-buffer-limit normal 0 0 0
client-output-buffer-limit slave 256mb 64mb 60
client-output-buffer-limit pubsub 32mb 8mb 60
hz 10
aof-rewrite-incremental-fsync yes

創(chuàng)建

為了建立主從模式,將 6380.conf 拷貝一份 6381.conf棚放,然后 修改所有端口相關(guān)參數(shù)枚粘,以及建立相應(yīng)的 /var/redis/6380/var/redis/6381 目錄。

集群的創(chuàng)建需要先啟動實例席吴,可以拷貝啟動腳本 /usr/local/redis/redis-3.2.11/utils/redis_init_script
/etc/init.d/redis_6380/etc/init.d/redis_6381赌结,修改所有相關(guān)端口參數(shù) 后,再使用 sudo /etc/init.d/redis_6380 start 命令啟動實例孝冒。

實例啟動狀態(tài)如下:

為了保證集群最小可用性柬姚,需要在 192.168.1.127192.168.1.8 上面也啟動 63806381 實例品山。

另外需要安裝:

sudo gem install redis

對于 Redis 3.2.11 版本來說鹅龄,應(yīng)該安裝(否則度帮,會遇到后面【重新分片】的坑):

sudo gem install redis -v 3.3.3

注意:gem 需要 ruby 2.2.2 以上版本,請知悉撮抓。

隨后使用命令創(chuàng)建集群:

redis-trib.rb create --replicas 1 192.168.1.8:6380 192.168.1.8:6381 192.168.1.127:6380 192.168.1.127:6381 192.168.1.57:6380 192.168.1.57:6381

注意:--replicas 參數(shù)表示希望每個主節(jié)點都有指定的從節(jié)點往衷,這里是 1 個骑篙。后面的 IP 地址 + 端口號削彬,就是初始創(chuàng)建的集群列表。

創(chuàng)建成功:

如果多臺服務(wù)器配置起來很繁瑣忧风,可以試著用一下:Redis Cluster 腳本默色。

測試

參考官方文檔進行測試。

嘗試連接:

redis-cli -c -p 6380

連接失斒ㄍ取:

這是集群 bind 了一個局域網(wǎng)地址腿宰,需要使用 -h 設(shè)置 IP 地址參數(shù):

redis-cli -c -h 192.168.1.8 -p 6380

成功連接:

測試通過:

維護

首先,需要有 2.2.2 以上的 Ruby 環(huán)境缘厢,然后去 redis-rb-cluster 下載文件:

  • 簡單示例 + 重新分片
  • 有趣示例 + 故障轉(zhuǎn)移
  • 其他維護命令

簡單示例 + 重新分片

對于 example.rb 文件吃度,需要修改的地方是:

if ARGV.length != 2
        startup_nodes = [
                {:host => "192.168.1.8", :port => 6380},
                {:host => "192.168.1.8", :port => 6381}
        ]
else

然后開始運行 ruby ./example.rb,接著會得到一長串的數(shù)字遞增贴硫,此時可以保留這個窗口椿每。

打開新的窗口,準備重新分片:

redis-trib.rb reshard 192.168.1.8:6380

顯示結(jié)果:

移動 1000 個哈希槽(建議保持 example.rb 在運行狀態(tài)):

需要一個目標節(jié)點的 ID英遭,這從【顯示結(jié)果】的圖中可以找到:

輸入 0471fb34c39dbb9338b56c474f59b3e745a1cc8f 之后间护,會被詢問從哪些節(jié)點獲取哈希槽:

官方指引輸入 all

但我這邊 出現(xiàn)錯誤,那么使用 check 參數(shù)檢查哪里出了問題:

再按照提示贪绘,使用 fix 參數(shù)修復(fù)問題(我嘗試過從編譯文件更新 redis-trib.rb 文件):

問題依然存在兑牡,自動修復(fù)出錯央碟。

搜索 錯誤提示 后税灌,找到:redis cluster3.2.0注意點

登陸客戶端:

redis-cli -c -h 192.168.1.8 -p 6380

執(zhí)行命令:

cluster setslot 5461 stable

效果如圖:

再檢查一下:

有可能還需要對 192.168.1.127:6380 進行同樣的操作:

OK亿虽!總算恢復(fù)了正常菱涤。

再試試在停止 example.rb 腳本的情況下,執(zhí)行重新分片:

這是從 192.168.1.8 的 主節(jié)點 6380 開始洛勉,執(zhí)行 1000 個哈希槽的重新分片粘秆,從所有節(jié)點轉(zhuǎn)移到 192.168.1.127 的 主節(jié)點 6380 中,依然是同樣的錯誤收毫。

說明應(yīng)該是 redis-trib.rb 腳本出了問題攻走,但我嘗試過拷貝相同版本編譯后的文件,問題依然得不到解決此再。

百度不出來什么結(jié)果昔搂,于是谷歌一下,立即得到答案:

Just installing an earlier version of redis.rb fixes the issue. This worked for me:
gem install redis -v 3.3.3

原問題貼在這里:https://github.com/antirez/redis/issues/4272

執(zhí)行效果:

那么输拇,我最后再嘗試一下 reshard摘符,再不行不搞了。

當然,得先啟動 example.rb逛裤,得到最佳效果瘩绒,然后再重新分片:

完美!4濉锁荔!沒有出錯:

測試一下運行狀態(tài):

正如預(yù)期的那樣,從其他主節(jié)點分配總共 1000 個哈希槽到 192.168.1.127 主節(jié)點中蝙砌。

可以將 重新分片 的操作匯合成一條命令:

./redis-trib.rb reshard --from <node-id> --to <node-id> --slots <number of slots> --yes <host>:<port>

有趣示例 + 故障轉(zhuǎn)移

接下來我們運行 consistency-test.rb 來看看一致性問題:

ruby ./consistency-test.rb 192.168.1.8 6380

效果如圖:

手動重置計數(shù)器:

redis-cli -c -h 192.168.1.8 -p 6380 set key_217 0

并沒有出現(xiàn) 114 lost堕战,但我已經(jīng)不想追究根源,還不如測試一下故障轉(zhuǎn)移:

redis-cli -c -h 192.168.1.8 -p 6380 debug segfault

看到了信息:

現(xiàn)在我們重新啟動 192.168.1.8:6380拍霜,然后查看集群狀態(tài):

可以發(fā)現(xiàn):192.168.1.8:6380 成為新主節(jié)點 192.168.1.127:6381 的從節(jié)點嘱丢,原來的從節(jié)點 192.168.1.8:6381 成為主節(jié)點 192.168.1.127:6380 的從節(jié)點(意味著并沒有升級為主節(jié)點)。

其他維護命令

  • 手動故障轉(zhuǎn)移:cluster failover(需要用 redis-cli 登錄從節(jié)點)
    通常在沒有故障但需要切換主從節(jié)點時使用祠饺,具體細節(jié)參考:cluster-failover越驻。
    效果如圖:

  • 添加新節(jié)點:redis-trib.rb add-node 192.168.1.8:6382 192.168.1.8:6380
    第一個參數(shù)是新建立的 Redis 實例,它是一個空節(jié)點道偷;第二個參數(shù)是集群中任何一個已存在的節(jié)點缀旁。
    效果如圖:


    通過 192.168.1.8:6382 客戶端,檢查集群:

    提示:空節(jié)點已加入集群勺鸦,但它沒有分配哈希槽并巍,因此也沒有任何數(shù)據(jù),不會被其他從節(jié)點選擇作為主人换途。
    可以重新分片懊渡,以便重新分配哈希槽,但基本上無用军拟,只是在重新分區(qū)剃执。

  • 添加新節(jié)點為副本:redis-trib.rb add-node --slave 192.168.1.8:6382 192.168.1.8:6380
    但這是不可能有效的:


    必須要是一個空節(jié)點,才能這樣做懈息,那已經(jīng)成為主節(jié)點的 192.168.1.8:6382 怎么辦肾档?
    可以使用 cluster replicate [id] 來成為目標節(jié)點的從節(jié)點:

  • 刪除節(jié)點:redis-trib.rb del-node 192.168.1.8:6380 f049c4f7a81a34f5a66248306f82e6317404b84d
    第一個參數(shù)是集群中任何一個節(jié)點;第二個參數(shù)是需要刪除的節(jié)點 ID辫继。
    效果如圖:


    如果要用這個命令刪除主節(jié)點怒见,那么此主節(jié)點 必須為空,否則就要把它的數(shù)據(jù)重新分配給所有其他主節(jié)點姑宽。另外一種辦法是使用 cluster replicate [id] 將主節(jié)點降級遣耍,成為從節(jié)點之后,可以繼續(xù)刪除節(jié)點低千。如果你必須減少集群中的主節(jié)點數(shù)量配阵,那么你應(yīng)該重新分片馏颂,使某些主節(jié)點不再擁有哈希槽和數(shù)據(jù),然后再刪除它們棋傍。

  • 副本遷移:cluster replicate [id]
    簡單來說救拉,當你不希望某個主節(jié)點下的從節(jié)點先掛掉,然后主節(jié)點相繼掛掉瘫拣,此時集群處于不可用狀態(tài)(沒有掛掉主節(jié)點的哈希槽副本)亿絮,那么你就應(yīng)該執(zhí)行這些步驟:

    1. 每個主節(jié)點至少分配一個從節(jié)點
    2. 額外增加一些從節(jié)點,可以是集群中的任意主節(jié)點
    3. 所有集群節(jié)點的配置參數(shù)麸拄,cluster-migration-barrier 設(shè)為 1派昧,保證遷移功能正常
  • 升級節(jié)點:cluster replicate [id]
    同樣的命令,但可以做很多事情拢切。概念比較復(fù)雜蒂萎,建議閱讀官方文檔 Redis Cluster,在此不做誤人解釋淮椰。

  • 遷移群集
    概念比較復(fù)雜五慈,建議同上。

總結(jié)

Redis 集群比其他 NoSQL 數(shù)據(jù)庫復(fù)雜得多主穗,據(jù)我所知泻拦,CassnadraElasticsearch 只需要修改配置,啟動忽媒,然后便是正常使用争拐。即使前面以單機形式啟動過,也只需要刷新一下系統(tǒng)信息表而已晦雨。

復(fù)雜的事物總顯得高大上架曹,希望后面維護起來會比 CassandraElasticsearch 要輕松很多吧。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末金赦,一起剝皮案震驚了整個濱河市音瓷,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌夹抗,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,311評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件纵竖,死亡現(xiàn)場離奇詭異漠烧,居然都是意外死亡,警方通過查閱死者的電腦和手機靡砌,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,339評論 2 382
  • 文/潘曉璐 我一進店門已脓,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人通殃,你說我怎么就攤上這事度液〔拮冢” “怎么了?”我有些...
    開封第一講書人閱讀 152,671評論 0 342
  • 文/不壞的土叔 我叫張陵堕担,是天一觀的道長已慢。 經(jīng)常有香客問我,道長霹购,這世上最難降的妖魔是什么佑惠? 我笑而不...
    開封第一講書人閱讀 55,252評論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮齐疙,結(jié)果婚禮上膜楷,老公的妹妹穿的比我還像新娘。我一直安慰自己贞奋,他們只是感情好赌厅,可當我...
    茶點故事閱讀 64,253評論 5 371
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著轿塔,像睡著了一般察蹲。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上催训,一...
    開封第一講書人閱讀 49,031評論 1 285
  • 那天洽议,我揣著相機與錄音,去河邊找鬼漫拭。 笑死亚兄,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的采驻。 我是一名探鬼主播审胚,決...
    沈念sama閱讀 38,340評論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼礼旅!你這毒婦竟也來了膳叨?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 36,973評論 0 259
  • 序言:老撾萬榮一對情侶失蹤痘系,失蹤者是張志新(化名)和其女友劉穎菲嘴,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體汰翠,經(jīng)...
    沈念sama閱讀 43,466評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡龄坪,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 35,937評論 2 323
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了复唤。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片健田。...
    茶點故事閱讀 38,039評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖佛纫,靈堂內(nèi)的尸體忽然破棺而出妓局,到底是詐尸還是另有隱情总放,我是刑警寧澤,帶...
    沈念sama閱讀 33,701評論 4 323
  • 正文 年R本政府宣布好爬,位于F島的核電站局雄,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏抵拘。R本人自食惡果不足惜哎榴,卻給世界環(huán)境...
    茶點故事閱讀 39,254評論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望僵蛛。 院中可真熱鬧尚蝌,春花似錦、人聲如沸充尉。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,259評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽驼侠。三九已至姿鸿,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間倒源,已是汗流浹背苛预。 一陣腳步聲響...
    開封第一講書人閱讀 31,485評論 1 262
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留笋熬,地道東北人热某。 一個月前我還...
    沈念sama閱讀 45,497評論 2 354
  • 正文 我出身青樓,卻偏偏與公主長得像胳螟,于是被迫代替她去往敵國和親昔馋。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 42,786評論 2 345

推薦閱讀更多精彩內(nèi)容