「碼唄學(xué)院」Redis 集群部署

簡(jiǎn)介

redis以高效的讀寫性能,被非常多的企業(yè)用戶用來(lái)做數(shù)據(jù)緩存層,很多公司會(huì)根據(jù)自己業(yè)務(wù)場(chǎng)景,部署單點(diǎn)或者是redis的集群,但是單點(diǎn)的redis如果發(fā)生故障,是無(wú)法保證服務(wù)高可用的,所以現(xiàn)在緩存服務(wù)通常都是redis的集群。

redis的集群方案目前使用的比較多的幾種方式;

????基于codis的架構(gòu),部署的redis集群。

????基于redis的哨兵模式,部署一個(gè)master多slave的集群模式。

????redis從3.0開(kāi)始支持集群的部署方式,而且是無(wú)中心化的,多master多slave模式。?

本次主要介紹redis自己支持的cluster的方式部署以及簡(jiǎn)單應(yīng)用

集群架構(gòu)

首先是我們準(zhǔn)備的三臺(tái)服務(wù)器資源,規(guī)劃每臺(tái)服務(wù)器上部署一個(gè)master實(shí)例和一個(gè)slave實(shí)例。在每臺(tái)服務(wù)器上安裝好redis,規(guī)劃服務(wù)器列表如下:


規(guī)劃服務(wù)器列表

介紹一下redis支持的cluster集群架構(gòu),redis cluster 集群節(jié)點(diǎn)類型分為master和slave,我們用組的概念理解一下,以master為類型進(jìn)行分組,一個(gè)組里面只有一個(gè)master,我們可以認(rèn)為是組長(zhǎng),其他的slave是組員,那數(shù)據(jù)存到redis集群里面,怎么存儲(chǔ)呢,redis集群默認(rèn)實(shí)現(xiàn)了一個(gè)hash slot的方式,哈希槽默認(rèn)是16384個(gè),也就是0-16383個(gè)槽,集群在創(chuàng)建的時(shí)候,每個(gè)組master會(huì)均勻分配這些槽,每個(gè)master占據(jù)一定的hash slot 范圍,往redis集群里面存儲(chǔ)數(shù)據(jù)的時(shí)候,redis默認(rèn)通過(guò)crc16(key)%16384 計(jì)算這個(gè)key的hash值,然后根據(jù)hash值找到對(duì)應(yīng)的master,直連該master進(jìn)行數(shù)據(jù)訪問(wèn)和存儲(chǔ)。redis集群里面所有實(shí)例都有hash slot對(duì)應(yīng)的master信息,所以連接任何一個(gè)實(shí)例信息,都能獲取到集群的ip和端口列表,然后根據(jù)計(jì)算出來(lái)的hash值,選擇具體的ip進(jìn)行直接訪問(wèn)。


相同顏色的實(shí)例為一組,master負(fù)責(zé)讀寫請(qǐng)求,slave為備份

安裝Redis

下載安裝redis:

## redis下載目錄可以參考:http://download.redis.io/releases/

wget http://download.redis.io/releases/redis-4.0.8.tar.gz

## 解壓文件

tar -xzf redis-4.0.8.tar.gz

## 進(jìn)入解壓目錄,編譯安裝

make

make install

centos服務(wù)器,也可以通過(guò)yum install redis 方式安裝,測(cè)試安裝結(jié)果。

redis-cli-v

在每臺(tái)服務(wù)器上啟動(dòng)redis-server,因?yàn)榉?wù)器資源有限,所以每臺(tái)服務(wù)器上部署兩個(gè)redis實(shí)例,當(dāng)然如果只有一臺(tái)服務(wù)器的情況下,也可以在一個(gè)服務(wù)器上部署多個(gè)實(shí)例,redis的配置文件如下,如果要部署多個(gè)實(shí)例注意修改端口號(hào)以及工作目錄和日志文件信息。

port 9002

bind? ? 0.0.0.0

daemonize? yes

logfile? "/root/temp/redis/redis-4.0.8/logs/node-9002.log"

cluster-enabled? yes

cluster-config-file? /root/temp/redis/redis-4.0.8/config/nodes-9002.conf

cluster-node-timeout? 5000

cluster-slave-validity-factor? ? 10

appendonly? yes

dir? /root/temp/redis/redis-4.0.8/data/9002

dbfilename? ? dump-9002.rdb

appendfilename? ? "appendonly-9002.aof"

redis-server啟動(dòng)以后可以查看每臺(tái)上的實(shí)例狀態(tài),下面開(kāi)始構(gòu)建集群。

如果是通過(guò)源碼安裝的redis,在src目錄下會(huì)有redis-trib.rb文件,這是ruby寫的一個(gè)腳本文件,redis的集群創(chuàng)建管理就是通過(guò)這個(gè)腳本來(lái)操作,所以在執(zhí)行這個(gè)腳本之前,首先還要保證服務(wù)器可以執(zhí)行ruby文件。執(zhí)行該腳本需要ruby版本>=2.2.2或者以上,檢查本機(jī)ruby的版本,如果版本過(guò)舊,可以通過(guò)以下操作升級(jí)ruby版本:

## 安裝rvm,Ruby version manager,Ruby的一個(gè)版本管理工具,如果使用過(guò)node,就跟nvm一樣,通過(guò)rvm可以看到ruby版本列表,可以很方便的進(jìn)行安裝和刪除。

## 安裝rvm的方式;

## gpg2是mac上的命令,linux服務(wù)器命令是gpg

gpg2 --keyserver hkp://keys.gnupg.net --recv-keys \ 409B6B1796C275462A1703113804BB82D39DC0E3 \ 7D2BAF1CF37B13E2069D6956105BD0E739499BDB

curl -sSL https://get.rvm.io | bash -s stable

執(zhí)行命令安裝好以后,會(huì)有提示讓執(zhí)行source命令,讓rvm生效:

source $HOME/.rvm/scripts/rvm

## 查看安裝好的信息

rvm -v

## 查看ruby 版本列表

rvm list known

##安裝ruby版本2.5

rvm install 2.5

##安裝好ruby以后,還需要安裝redis的模塊。

gem install redis

## 如果在安裝redis模塊的時(shí)候很慢,可以更換ruby倉(cāng)庫(kù)源,使用aliyun的源倉(cāng)庫(kù)。

## gem source -a http://mirrors.aliyun.com/rubygems/

以上就安裝好ruby相關(guān)的環(huán)境了,然后我們就可以通過(guò)redis-trib.rb命令來(lái)管理集群了。

Redis集群創(chuàng)建

redis-trib.rb我是通過(guò)腳本的形式執(zhí)行的,也可以把他放到/usr/bin/目錄下,然后就可以執(zhí)行redis-trib命令了,可以查看redis-trib命令的先關(guān)幫助信息:

ruby redis-trib.rb help

Usage: redis-trib <command> <options> <arguments ...>

? create? ? ? ? ? host1:port1 ... hostN:portN

? ? ? ? ? ? ? ? ? --replicas <arg>

? check? ? ? ? ? host:port

? info? ? ? ? ? ? host:port

? fix? ? ? ? ? ? host:port

? ? ? ? ? ? ? ? ? --timeout <arg>

? reshard? ? ? ? host:port

? ? ? ? ? ? ? ? ? --from <arg>

? ? ? ? ? ? ? ? ? --to <arg>

? ? ? ? ? ? ? ? ? --slots <arg>

? ? ? ? ? ? ? ? ? --yes

? ? ? ? ? ? ? ? ? --timeout <arg>

? ? ? ? ? ? ? ? ? --pipeline <arg>

? rebalance? ? ? host:port

? ? ? ? ? ? ? ? ? --weight <arg>

? ? ? ? ? ? ? ? ? --auto-weights

? ? ? ? ? ? ? ? ? --use-empty-masters

? ? ? ? ? ? ? ? ? --timeout <arg>

? ? ? ? ? ? ? ? ? --simulate

? ? ? ? ? ? ? ? ? --pipeline <arg>

? ? ? ? ? ? ? ? ? --threshold <arg>

? add-node? ? ? ? new_host:new_port existing_host:existing_port

? ? ? ? ? ? ? ? ? --slave

? ? ? ? ? ? ? ? ? --master-id <arg>

? del-node? ? ? ? host:port node_id

? set-timeout? ? host:port milliseconds

? call? ? ? ? ? ? host:port command arg arg .. arg

? import? ? ? ? ? host:port

? ? ? ? ? ? ? ? ? --from <arg>

? ? ? ? ? ? ? ? ? --copy

? ? ? ? ? ? ? ? ? --replace

? help? ? ? ? ? ? (show this help)

For check, fix, reshard, del-node, set-timeout you can specify the host and port of any working node in the cluster.

上面的幫助詳細(xì)介紹了redis-trib的使用說(shuō)明,首先我們創(chuàng)建一個(gè)集群:

ruby redis-trib.rb create --replicas 1 192.168.35.66:7001 192.168.35.73:7001 192.168.35.74:7001 192.168.35.66:9002 192.168.35.73:9002 192.168.35.74:9002

介紹一下命令的參數(shù)信息:

create 是子命令,表示創(chuàng)建一個(gè)新的集群,并且創(chuàng)建集群的master節(jié)點(diǎn)必須>=3個(gè)才可以創(chuàng)建集群,replicas表示每個(gè)master有幾個(gè)slave,這里是1,表示每個(gè)master至少有一個(gè)slave實(shí)例。集群創(chuàng)建會(huì)彈出一個(gè)提示窗口,確認(rèn)沒(méi)有問(wèn)題的話,輸入yes,即可完成集群創(chuàng)建,然后通過(guò)check檢查集群狀態(tài):

ruby redis-trib.rb check 192.168.35.74:7001

>>> Performing Cluster Check (using node 192.168.35.74:7001)

M: c0be24752e6a23b566112c5389c20c35e97a5182 192.168.35.74:7001

? slots:5461-5797,10923-16383 (5798 slots) master

? 1 additional replica(s)

M: c1e9e762e553b5b62a674c439c8272447b2efc82 192.168.35.73:7001

? slots:5798-10922 (5125 slots) master

? 1 additional replica(s)

S: e00b99df51149512a4b4e6d64eec4d7550a63ede 192.168.35.73:9002

? slots: (0 slots) slave

? replicates 7a70746b2e23ee06e1bedb07f1952bfc9501a859

M: 7a70746b2e23ee06e1bedb07f1952bfc9501a859 192.168.35.66:7001

? slots:0-5460 (5461 slots) master

? 1 additional replica(s)

S: 82da7bd42cdd96785a2f131445c7b189c48c75a3 192.168.35.74:9002

? slots: (0 slots) slave

? replicates c0be24752e6a23b566112c5389c20c35e97a5182

S: 899a7a0199eeab0fcc5bce108efc2a57cf3d1d23 192.168.35.66:9002

? slots: (0 slots) slave

? replicates c1e9e762e553b5b62a674c439c8272447b2efc82

[OK] All nodes agree about slots configuration.

>>> Check for open slots...

>>> Check slots coverage...

[OK] All 16384 slots covered.

上面顯示我的集群狀態(tài)信息,slot分配的結(jié)果看上去可能不太均勻,這是因?yàn)槲易鲞^(guò)增減節(jié)點(diǎn),slot重新分配過(guò),如果想讓均衡一下,可以執(zhí)行如下命令:

##這個(gè)命令用來(lái)重新規(guī)劃集群各個(gè)勢(shì)力的負(fù)載

ruby redis-trib.rb rebalance? 192.168.35.74:7001

##重新規(guī)劃以后再通過(guò)check命令檢查,會(huì)發(fā)現(xiàn)redis的各個(gè)實(shí)例分配的slots很均勻了(命令輸出結(jié)果就不在這里貼出來(lái)了)

ruby redis-trib.rb check 192.168.35.74:7001

然后就會(huì)發(fā)現(xiàn)每個(gè)master分配的hash slot非常均衡了,有兩個(gè)是5461個(gè)slots,一個(gè)是5462個(gè)slots,執(zhí)行的命令就是rebalance。到此,我們的redis集群已經(jīng)創(chuàng)建完成了。

訪問(wèn)redis集群

現(xiàn)在通過(guò)redis-cli和應(yīng)用程序來(lái)訪問(wèn)一下集群信息。

## redis 訪問(wèn)集群的時(shí)候,需要執(zhí)行-c參數(shù)。

redis-cli -c -h 192.168.35.74 -p 7001

192.168.35.74:7001> get name

-> Redirected to slot [5798] located at 192.168.35.73:7001

"ggcc"

192.168.35.73:7001>

通過(guò)上面的執(zhí)行,發(fā)現(xiàn)獲取name值的時(shí)候一開(kāi)始我們連的是74這臺(tái)服務(wù)器,get命令執(zhí)行的時(shí)候,卻重定向到了73這臺(tái)服務(wù)器,所以client訪問(wèn)集群的時(shí)候,首先是根據(jù)key計(jì)算出來(lái)hash值,再根據(jù)hash值找到對(duì)應(yīng)的master實(shí)例節(jié)點(diǎn)信息,直連對(duì)應(yīng)的master實(shí)例,進(jìn)行數(shù)據(jù)的讀寫。

redis-cli命令是這樣執(zhí)行的,那么我們看Java程序是怎么讀寫數(shù)據(jù)的。

package redis;

import redis.clients.jedis.HostAndPort;

import redis.clients.jedis.JedisCluster;

import java.util.HashSet;

import java.util.Scanner;

import java.util.Set;

public class RedisClusterCli {

? ? public static void main(String[] args) {

? ? ? ? HostAndPort hostAndPort = new HostAndPort("192.168.35.74", 9002);

? ? ? ? Set<HostAndPort> hostAndPorts = new HashSet<>();

? ? ? ? hostAndPorts.add(hostAndPort);

? ? ? ? JedisCluster cluster = new JedisCluster(hostAndPorts);

? ? ? ? String value;

? ? ? ? while (true) {

? ? ? ? ? ? try {

? ? ? ? ? ? ? ? System.out.println("請(qǐng)輸入key:");

? ? ? ? ? ? ? ? Scanner scanner = new Scanner(System.in);

? ? ? ? ? ? ? ? String key = scanner.next();

? ? ? ? ? ? ? ? value = cluster.get(key);

? ? ? ? ? ? ? ? System.out.println(value);

? ? ? ? ? ? } catch (Exception ex) {

? ? ? ? ? ? ? ? ex.printStackTrace();

? ? ? ? ? ? ? ? System.out.println("異常信息忽略");

? ? ? ? ? ? }

? ? ? ? }

? ? }

}

測(cè)試代碼寫的比較簡(jiǎn)單,單獨(dú)執(zhí)行的話,能夠正常運(yùn)行,但是看不出具體的執(zhí)行細(xì)節(jié),我們查看一下關(guān)鍵部分的源碼,然后看一下它執(zhí)行的具體邏輯。redis.clients.jedis.JedisClusterCommand.runWithRetries方法

private T runWithRetries(byte[] key, int attempts, boolean tryRandomNode, boolean asking) {

? if (attempts <= 0) {

? ? throw new JedisClusterMaxRedirectionsException("Too many Cluster redirections?");

? }

? Jedis connection = null;

? try {

? ? if (asking) {

? ? ? // TODO: Pipeline asking with the original command to make it

? ? ? // faster....

? ? ? connection = askConnection.get();

? ? ? connection.asking();

? ? ? // if asking success, reset asking flag

? ? ? asking = false;

? ? } else {

? ? ? if (tryRandomNode) {

? ? ? ? connection = connectionHandler.getConnection();

? ? ? } else {

? ? ? ? connection = connectionHandler.getConnectionFromSlot(JedisClusterCRC16.getSlot(key));

? ? ? }

? ? }

? ? return execute(connection);

? } catch (JedisNoReachableClusterNodeException jnrcne) {

? ? throw jnrcne;

? } catch (JedisConnectionException jce) {

? ? // release current connection before recursion

? ? releaseConnection(connection);

? ? connection = null;

? ? if (attempts <= 1) {

? ? ? //We need this because if node is not reachable anymore - we need to finally initiate slots renewing,

? ? ? //or we can stuck with cluster state without one node in opposite case.

? ? ? //But now if maxAttempts = 1 or 2 we will do it too often. For each time-outed request.

? ? ? //TODO make tracking of successful/unsuccessful operations for node - do renewing only

? ? ? //if there were no successful responses from this node last few seconds

? ? ? this.connectionHandler.renewSlotCache();

? ? ? //no more redirections left, throw original exception, not JedisClusterMaxRedirectionsException, because it's not MOVED situation

? ? ? throw jce;

? ? }

? ? return runWithRetries(key, attempts - 1, tryRandomNode, asking);

? } catch (JedisRedirectionException jre) {

? ? // if MOVED redirection occurred,

? ? if (jre instanceof JedisMovedDataException) {

? ? ? // it rebuilds cluster's slot cache

? ? ? // recommended by Redis cluster specification

? ? ? this.connectionHandler.renewSlotCache(connection);

? ? }

? ? // release current connection before recursion or renewing

? ? releaseConnection(connection);

? ? connection = null;

? ? if (jre instanceof JedisAskDataException) {

? ? ? asking = true;

? ? ? askConnection.set(this.connectionHandler.getConnectionFromNode(jre.getTargetNode()));

? ? } else if (jre instanceof JedisMovedDataException) {

? ? } else {

? ? ? throw new JedisClusterException(jre);

? ? }

? ? return runWithRetries(key, attempts - 1, false, asking);

? } finally {

? ? releaseConnection(connection);

? }

}

首先注意看第21行代碼,這里是表示根據(jù)key的hash值,計(jì)算出來(lái)slot,然后根據(jù)slot信息獲取相應(yīng)的節(jié)點(diǎn)ip和端口信息,獲取具體IP的代碼邏輯在redis.clients.jedis.JedisSlotBasedConnectionHandler.getConnectionFromSlot這個(gè)方法中,具體代碼如下:

public Jedis getConnectionFromSlot(int slot) {

? ? JedisPool connectionPool = cache.getSlotPool(slot);

? ? if (connectionPool != null) {

? ? ? // It can't guaranteed to get valid connection because of node

? ? ? // assignment

? ? ? return connectionPool.getResource();

? ? } else {

? ? ? renewSlotCache(); //It's abnormal situation for cluster mode, that we have just nothing for slot, try to rediscover state

? ? ? connectionPool = cache.getSlotPool(slot);

? ? ? if (connectionPool != null) {

? ? ? ? return connectionPool.getResource();

? ? ? } else {

? ? ? ? //no choice, fallback to new connection to random node

? ? ? ? return getConnection();

? ? ? }

? ? }

? }

}

這個(gè)代碼邏輯比較簡(jiǎn)單,首先是從緩存獲取,緩存的數(shù)據(jù)結(jié)構(gòu)是個(gè)map對(duì)象,map對(duì)象用了一個(gè)最簡(jiǎn)單直接的方法,存儲(chǔ)了16384對(duì)象信息,key分別是對(duì)應(yīng)的0-16383個(gè)數(shù)字,value就是JedisPool對(duì)象,也就是保存的具體的服務(wù)器IP和端口。如果緩存沒(méi)有獲取到,執(zhí)行第8行代碼,加載信息,加載到緩存以后,如果依然沒(méi)有獲取到,那就返回一個(gè)隨機(jī)的,理論上應(yīng)該都是能獲取到的,當(dāng)然也不排除極端的情況,比如訪問(wèn)其中一個(gè)master節(jié)點(diǎn)掛機(jī),redis.clients.jedis.JedisClusterCommand.runWithRetries這個(gè)方法會(huì)拋出一個(gè)異常JedisConnectionException,但是這個(gè)異常里面會(huì)遞歸調(diào)用多次,也就是說(shuō)會(huì)默認(rèn)重試調(diào)用,默認(rèn)的次數(shù)是5次,當(dāng)最后一次調(diào)用的時(shí)候,依然報(bào)了這個(gè)異常,那么就會(huì)重新加載redis的集群信息,因?yàn)閙aster掛機(jī)以后,新的slave產(chǎn)生,slots對(duì)應(yīng)的IP信息也會(huì)出現(xiàn)變化。

redis集群中的一個(gè)master掛機(jī)以后,新的slave晉升為master,這中間有個(gè)心跳檢查時(shí)間,根據(jù)redis的參數(shù)cluster-slave-validity-factor配置,在這個(gè)時(shí)間內(nèi),如果獲取掛機(jī)master實(shí)例上的數(shù)據(jù),將會(huì)頻繁報(bào)錯(cuò),通常在應(yīng)用場(chǎng)景中,就會(huì)穿透緩存層,直接訪問(wèn)數(shù)據(jù)庫(kù)。因?yàn)槭莚edis集群,每個(gè)master上面分配的數(shù)據(jù)都只是一部分,即便是穿透緩存層,也是一部分?jǐn)?shù)據(jù)而已,而且根據(jù)我們部署的redis集群的數(shù)量,redis master實(shí)例越多,數(shù)據(jù)分配的越是均勻,故障的發(fā)生率越是低,影響的面就越小,這樣redis集群就能很好的保證我們服務(wù)的高可用性。

Redis集群擴(kuò)容

redis集群的擴(kuò)容和縮容,同樣使用redis-trib來(lái)操作,下面是操作執(zhí)行流程,執(zhí)行記錄比較多,而且比較長(zhǎng),可以直接跳過(guò),看后面操作命令的總結(jié),實(shí)際操作時(shí),有問(wèn)題再看具體的執(zhí)行流程記錄:

## 新增加一個(gè)master節(jié)點(diǎn)

ruby redis-trib.rb add-node 192.168.35.73:9003 192.168.35.74:9002

>>> Adding node 192.168.35.73:9003 to cluster 192.168.35.74:9002

>>> Performing Cluster Check (using node 192.168.35.74:9002)

S: 82da7bd42cdd96785a2f131445c7b189c48c75a3 192.168.35.74:9002

? slots: (0 slots) slave

? replicates c0be24752e6a23b566112c5389c20c35e97a5182

S: e00b99df51149512a4b4e6d64eec4d7550a63ede 192.168.35.73:9002

? slots: (0 slots) slave

? replicates 7a70746b2e23ee06e1bedb07f1952bfc9501a859

M: 7a70746b2e23ee06e1bedb07f1952bfc9501a859 192.168.35.66:7001

? slots:0-5460 (5461 slots) master

? 1 additional replica(s)

M: c1e9e762e553b5b62a674c439c8272447b2efc82 192.168.35.73:7001

? slots:5461-10922 (5462 slots) master

? 1 additional replica(s)

S: 899a7a0199eeab0fcc5bce108efc2a57cf3d1d23 192.168.35.66:9002

? slots: (0 slots) slave

? replicates c1e9e762e553b5b62a674c439c8272447b2efc82

M: c0be24752e6a23b566112c5389c20c35e97a5182 192.168.35.74:7001

? slots:10923-16383 (5461 slots) master

? 1 additional replica(s)

[OK] All nodes agree about slots configuration.

>>> Check for open slots...

>>> Check slots coverage...

[OK] All 16384 slots covered.

>>> Send CLUSTER MEET to node 192.168.35.73:9003 to make it join the cluster.

[OK] New node added correctly.


以上記錄很多,但是實(shí)際上操作步驟沒(méi)有多少,這里總結(jié)一下:

##第一個(gè)命令,首先是增加一個(gè)master實(shí)例,第一個(gè)IP:PORT信息是需要新增的實(shí)例地址,后面的IP:PORT是集群中任意一個(gè)實(shí)例的端口和ip信息,就是集群的入口。

ruby redis-trib.rb add-node 192.168.35.73:9003 192.168.35.74:9002

##第二個(gè)命令,這個(gè)命令就是為剛才新增的那個(gè)master增加一個(gè)slave實(shí)例,注意--slave參數(shù)表示增加的是slave實(shí)例,master-id就是剛才增加的master的node id值,可以通過(guò)check查看。第一個(gè)IP:PORT信息就是新增的slave實(shí)例信息,第二個(gè)參數(shù)和第一個(gè)命令一樣,就是告訴集群的入口。

ruby redis-trib.rb add-node --slave --master-id 67d82f2e6e1f9c0afbc15090732d7f2f41064fbc 192.168.35.73:9004 192.168.35.74:9002

##第三個(gè)命令,新增的實(shí)例信息,其實(shí)是沒(méi)有分配slot值的,即便是執(zhí)行rebalance也是沒(méi)有值的,就是認(rèn)為該實(shí)例還沒(méi)有啟用,所以需要執(zhí)行一下,給他分配一些slots值過(guò)去。reshard就是slots遷移命令,from和to 分別表示從哪里遷移到目標(biāo)實(shí)例。如果我們需要下掉某一個(gè)master實(shí)例,我們就可以通過(guò)這個(gè)操作把當(dāng)前實(shí)例的所有slots值全部遷移走。

ruby redis-trib.rb reshard --from e00b99df51149512a4b4e6d64eec4d7550a63ede --to 67d82f2e6e1f9c0afbc15090732d7f2f41064fbc --slots 3099 --yes --timeout 30 192.168.35.74:9002

##最后一步命令是可選的,因?yàn)槟闶謩?dòng)遷移的slots值,其實(shí)是不夠均衡的,所以對(duì)于強(qiáng)迫癥的用戶來(lái)說(shuō),必須要執(zhí)行一下rebalance命令,然后系統(tǒng)會(huì)重新分配slots信息,均勻分配

ruby redis-trib.rb rebalance 192.168.35.74:9002

以上操作對(duì)于應(yīng)用程序來(lái)說(shuō)都是無(wú)感知的,除非是遷移的時(shí)候搞down機(jī)了,應(yīng)用程序會(huì)報(bào)錯(cuò),但是報(bào)錯(cuò)的范圍也會(huì)很小。

總結(jié)

Redis Cluster方案,適合高并發(fā)讀寫的場(chǎng)景,無(wú)中心化的配置,保障集群的高可用性,并且通過(guò)指定多個(gè)slave的方式,保障了數(shù)據(jù)的安全性,而且提供了相對(duì)簡(jiǎn)單的集群管理配置,沒(méi)有三方服務(wù)的依賴,用來(lái)構(gòu)建成產(chǎn)線緩存服務(wù)集群,再合適不過(guò)。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容