首頁  >  文章  >  資料庫  >  Redis高可用集群詳細介紹

Redis高可用集群詳細介紹

尚
轉載
2019-11-26 17:11:581835瀏覽

Redis高可用集群詳細介紹

Redis的叢集主從模型是一種高可用的叢集架構。本章主要內容有:高可用集群的搭建,Jedis連接集群,新增集群節點,刪除集群節點,其他配置補充說明。 (推薦:redis影片教學

高可用叢集搭建

叢集(cluster)技術是一種較新的技術,透過集群技術,可以在付出較低成本的情況下獲得在性能、可靠性、靈活性方面的相對較高的收益,其任務調度則是集群系統中的核心技術。

Redis 3.0 之後便支援叢集。 Redis 集群中內建了 16384 個哈希槽。 Redis 會根據節點數量大致均等的將哈希槽映射到不同的節點。
所有節點之間彼此互聯(PING-PONG機制),當超過半數的主機認為某台主機掛了,則該主機就是真的掛掉了,整個集群就不可用了。
若給叢集中的每台主機指派多台從機。主機掛了,從機上位,還是能正常運作。但是若叢集中超過一半的主機掛了,無論是否有從機,則該叢集也是不可用的。

搭建前的準備工作

建置ruby環境

redis叢集管理工具 redis-trib.rb 是依賴 ruby​​ 環境。

[root@itdragon ~]# yum install ruby
[root@itdragon ~]# yum install rubygems
[root@itdragon ~]# gem install redis
[root@itdragon ~]# cd redis-4.0.2/src/
[root@itdragon src]# cp redis-trib.rb /usr/local/redis-4/bin/

第一步:安裝 ruby​​ 環境

第二步:安裝 gem 軟體包(gem是用來擴充或修改Ruby應用程式的)。

第三步:在redis解壓縮目錄中找到 redis-trib.rb 文件,將其拷貝到啟動redis服務的目錄下,方便管理。

可能存在的問題

1 redis requires Ruby version >= 2.2.2,解決方法如下

2 沒有/usr/local/rvm/scripts/rvm 這個目錄.可能是上一步執行失敗

[root@itdragon ~]# ruby --version
ruby 1.8.7 (2013-06-27 patchlevel 374) [x86_64-linux]
[root@itdragon ~]# yum install curl
[root@itdragon ~]# curl -L get.rvm.io | bash -s stable
[root@itdragon ~]# source /usr/local/rvm/scripts/rvm 
[root@itdragon ~]# rvm list known
[root@itdragon ~]# rvm install 2.3.3
[root@itdragon ~]# rvm use 2.3.3
[root@itdragon ~]# gem install redis

準備六台redis伺服器

和主從複製邏輯一樣,將redis.conf檔拷貝6次,連接埠從6000~6005

[root@itdragon bin]# cp redis.conf redis6000.conf
[root@itdragon bin]# vim redis6000.conf  
port xxxx                           #修改端口
cluster-enabled yes                 #打开注释,开启集群模式
cluster-config-file nodes-xxxx.conf #集群的配置文件
pidfile /var/run/redis_xxxx.pid     #pidfile文件
logfile "xxxx.log"                  #日志文件
dbfilename dump_xxxx.rdb            #rdb持久化文件
cluster-node-timeout 5000           #请求超时,单位毫秒
appendonly yes                      #开启aof持久化方式
[root@itdragon bin]# vim start-all.sh
./redis-server redis6000.conf
./redis-server redis6001.conf
./redis-server redis6002.conf
./redis-server redis6003.conf
./redis-server redis6004.conf
./redis-server redis6005.conf
[root@itdragon bin]# chmod u+x start-all.sh
[root@itdragon bin]# ./start-all.sh 
[root@itdragon bin]# ps aux | grep redis
root     28001  0.0  0.9 145964  9696 ?        Ssl  17:45   0:00 ./redis-server 112.74.83.71:6000 [cluster]
root     28003  0.0  0.9 145964  9696 ?        Ssl  17:45   0:00 ./redis-server 112.74.83.71:6001 [cluster]
root     28008  0.0  0.9 145964  9656 ?        Ssl  17:45   0:00 ./redis-server 112.74.83.71:6002 [cluster]
root     28013  0.0  0.9 145964  9656 ?        Ssl  17:45   0:00 ./redis-server 112.74.83.71:6003 [cluster]
root     28018  0.1  0.9 145964  9652 ?        Ssl  17:45   0:00 ./redis-server 112.74.83.71:6004 [cluster]
root     28023  0.0  0.9 145964  9656 ?        Ssl  17:45   0:00 ./redis-server 112.74.83.71:6005 [cluster]

第一步:複製六個redis.conf 並修改相關配置,如果我覺得麻煩可以用我配置的檔案:https://github.com/ITDragonBlog/daydayup/tree/master /Redis/reids.conf
第二步:新增批次開啟redis服務程序,並增加執行權限

第三個步驟:查看六台redis服務是否啟動成功

主從集群搭建

集群建立命令: ./redis-trib.rb create 建立集群,--replicas 1 給每個主機分配一個從機,後面其他參數都是redis服務的ip:port。最後輸入yes來接受建議的設定

[root@itdragon bin]# ./redis-trib.rb create --replicas 1 112.74.83.71:6000 112.74.83.71:6001 112.74.83.71:6002 112.74.83.71:6003 112.74.83.71:6004 112.74.83.71:6005
>>> Creating cluster
>>> Performing hash slots allocation on 6 nodes...
Using 3 masters:
112.74.83.71:6000
112.74.83.71:6001
112.74.83.71:6002
Adding replica 112.74.83.71:6003 to 112.74.83.71:6000
Adding replica 112.74.83.71:6004 to 112.74.83.71:6001
Adding replica 112.74.83.71:6005 to 112.74.83.71:6002
...... #省略
Can I set the above configuration? (type 'yes' to accept): yes
...... #省略
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered. #有16384个可用的插槽提供服务说明搭建成功

[root@itdragon bin]# ./redis-cli -h 112.74.83.71 -p 6002 -c
112.74.83.71:6002> set testKey value
-> Redirected to slot [5203] located at 112.74.83.71:6000
OK

112.74.83.71:6000> cluster info
cluster_state:ok
......

112.74.83.71:6000> cluster nodes
0968ef8f5ca96681da4abaaf4ca556c2e6dd0242 112.74.83.71:6002@16002 master - 0 1512035804722 3 connected 10923-16383
13ddd4c1b8c00926f61aa6daaa7fd8d87ee97830 112.74.83.71:6005@16005 slave 0968ef8f5ca96681da4abaaf4ca556c2e6dd0242 0 1512035803720 6 connected
a3bb22e04deec2fca653c606edf5b02b819f924f 112.74.83.71:6003@16003 slave 1d4779469053930f30162e89b6711d27a112b601 0 1512035802000 4 connected
1d4779469053930f30162e89b6711d27a112b601 112.74.83.71:6000@16000 myself,master - 0 1512035802000 1 connected 0-5460
a3b99cb5d22f5cbd293179e262f5eda931733c88 112.74.83.71:6001@16001 master - 0 1512035802719 2 connected 5461-10922
915a47afc4f9b94389676b4e14f78cba66be9e5d 112.74.83.71:6004@16004 slave a3b99cb5d22f5cbd293179e262f5eda931733c88 0 1512035801717 5 connected

第一步:建立叢集./redis-trib.rb create ,選擇yes接受建議的設定

第二步:進入叢集客戶端./redis-cli -h 任意主機host -p 任意主機port -c,-c表示以集群方式連接redis

第三步:保存資料

第四步:cluster info查詢群集狀態資訊

第五步:cluster nodes 查詢群集結點信息,這裡有一個坑,後面會介紹

可能存在的問題

Sorry, the cluster configuration file nodes.conf is already used by a different Redis Cluster node. Please make sure that different nodes use different cluster configuration files.

說的很明確,修改cluster-config--file nodes.conf 檔案避免重讀名,或刪除該檔案重新建立叢集。

cluster nodes 查詢叢集節點資訊

這是很重要的指令,我們需要關心的資訊有:

第一個參數:節點ID

第二個參數:IP:PORT@TCP 這裡一個坑,jedis-2.9.0之前的版本解析@出錯

第三個參數:標誌(Master,Slave,Myself,Fail...)

第四個參數:如果是從機則是主機的節點ID

最後兩個參數:連線的狀態和插槽的位置。

Jedis 連線叢集

首先要設定防火牆

[root@itdragon ~]# vim /etc/sysconfig/iptables
-A INPUT -p tcp -m tcp --dport 6000 -j ACCEPT
-A INPUT -p tcp -m tcp --dport 6001 -j ACCEPT
-A INPUT -p tcp -m tcp --dport 6002 -j ACCEPT
-A INPUT -p tcp -m tcp --dport 6003 -j ACCEPT
-A INPUT -p tcp -m tcp --dport 6004 -j ACCEPT
-A INPUT -p tcp -m tcp --dport 6005 -j ACCEPT
[root@itdragon ~]# service iptables restart

最後是整合Spring

<!-- jedis集群版配置 -->
<bean id="redisClient" class="redis.clients.jedis.JedisCluster">
    <constructor-arg name="nodes">
        <set>
            <bean class="redis.clients.jedis.HostAndPort">
                <constructor-arg name="host" value="${redis.host}"></constructor-arg>
                <constructor-arg name="port" value="6000" />
            </bean>
            <bean class="redis.clients.jedis.HostAndPort">
                <constructor-arg name="host" value="${redis.host}"></constructor-arg>
                <constructor-arg name="port" value="6001" />
            </bean>
            <bean class="redis.clients.jedis.HostAndPort">
                <constructor-arg name="host" value="${redis.host}"></constructor-arg>
                <constructor-arg name="port" value="6002" />
            </bean>
            <bean class="redis.clients.jedis.HostAndPort">
                <constructor-arg name="host" value="${redis.host}"></constructor-arg>
                <constructor-arg name="port" value="6003" />
            </bean>
            <bean class="redis.clients.jedis.HostAndPort">
                <constructor-arg name="host" value="${redis.host}"></constructor-arg>
                <constructor-arg name="port" value="6004" />
            </bean>
            <bean class="redis.clients.jedis.HostAndPort">
                <constructor-arg name="host" value="${redis.host}"></constructor-arg>
                <constructor-arg name="port" value="6005" />
            </bean>
        </set>
    </constructor-arg>
    <constructor-arg name="poolConfig" ref="jedisPoolConfig" />
</bean>
<bean id="jedisClientCluster" class="com.itdragon.service.impl.JedisClientCluster"></bean>

單元測試

/**
 * 集群版测试
 * 若提示以下类似的错误:
 * java.lang.NumberFormatException: For input string: "6002@16002"
 * 若安装的redis 版本大于4,则可能是jedis 的版本低了。选择 2.9.0
 * 因为 cluster nodes 打印的信息中,4版本之前的是没有 @16002 tcp端口信息
 * 0968ef8f5ca96681da4abaaf4ca556c2e6dd0242 112.74.83.71:6002@16002 master - 0 1512035804722 3 connected 10923-16383
 */
@Test
public void testJedisCluster() throws IOException {
    HashSet<HostAndPort> nodes = new HashSet<>();
    nodes.add(new HostAndPort(HOST, 6000));
    nodes.add(new HostAndPort(HOST, 6001));
    nodes.add(new HostAndPort(HOST, 6002));
    nodes.add(new HostAndPort(HOST, 6003));
    nodes.add(new HostAndPort(HOST, 6004));
    nodes.add(new HostAndPort(HOST, 6005));
    JedisCluster cluster = new JedisCluster(nodes);
    cluster.set("cluster-key", "cluster-value");
    System.out.println("集群测试 : " + cluster.get("cluster-key"));
    cluster.close();
}

可能存在的問題

java.lang.NumberFormatException: For input string: "6002@16002"

#若redis 的版​​本在4.0.0之上,建議使用jedis-2.9.0以上。

原始碼:
https://github.com/ITDragonBlog/daydayup/tree/master/Redis/ssm-redis

叢集節點運算

新增主節點

[root@itdragon bin]# cp redis6005.conf redis6006.conf
[root@itdragon bin]# ./redis-server redis6006.conf
[root@itdragon bin]# ./redis-trib.rb add-node 112.74.83.71:6006 112.74.83.71:6000
[root@itdragon bin]# ./redis-cli -h 112.74.83.71 -p 6000 cluster nodes
916d26e9638dc51e168f32969da11e19c875f48f 112.74.83.71:6006@16006 master - 0 1512115612162 0 connected   # 没有分配槽
[root@itdragon bin]# ./redis-trib.rb reshard 112.74.83.71:6000
How many slots do you want to move (from 1 to 16384)? 500
What is the receiving node ID? 916d26e9638dc51e168f32969da11e19c875f48f
Please enter all the source node IDs.
  Type &#39;all&#39; to use all the nodes as source nodes for the hash slots.
  Type &#39;done&#39; once you entered all the source nodes IDs.
Source node #1:all
Do you want to proceed with the proposed reshard plan (yes/no)? yes
[root@itdragon bin]# ./redis-cli -h 112.74.83.71 -p 6000 cluster nodes
916d26e9638dc51e168f32969da11e19c875f48f 112.74.83.71:6006@16006 master - 0 1512116047897 7 connected 0-165 5461-5627 10923-11088

第一步:建立redis6006.conf 的新主機,並啟動Redis服務

第二步:新增主機節點,若列印"[OK] New node added correctly." 表示添加成功

第三步:查詢集群節點信息,發現6006端口的主機雖然已經添加,但連接狀態後面沒有內容,即沒分配槽

第四步:给6006端口主机分配槽,

第一个参数:需要移动槽的个数,

第二个参数:接受槽的节点ID,

第三个参数:输入"all"表示从所有原节点中获取槽,

第四个参数:输入"yes"开始移动槽到目标结点id

第五步:查询集群节点信息,发现6006端口的主机已经分配了槽

核心命令:
./redis-trib.rb add-node 新增主机ip:port 集群任意节点ip:port
./redis-trib.rb reshard 集群任意节点ip:port

可能存在的问题
[ERR] Sorry, can't connect to node 112.74.83.71:6006
说明:新增的主机必须要是启动状态。

添加从节点

[root@itdragon bin]# cp redis6006.conf redis6007.conf
[root@itdragon bin]# vim redis6007.conf 
[root@itdragon bin]# ./redis-server redis6007.conf
[root@itdragon bin]# ./redis-trib.rb add-node --slave --master-id 916d26e9638dc51e168f32969da11e19c875f48f 112.74.83.71:6007 112.74.83.71:6006
[root@itdragon bin]# ./redis-cli -h 112.74.83.71 -p 6000 cluster nodes
80315a4dee2d0fa46b8ac722962567fc903e797a 112.74.83.71:6007@16007 slave 916d26e9638dc51e168f32969da11e19c875f48f 0 1512117377000 7 connected

第一步:创建 redis6007.conf 的新主机,并启动Redis服务
第二步:新增从机节点,在原来的命令上多了 --slave --master-id 主节点ID
第三步:查询集群节点信息

删除结点

删除节点前,要确保该节点没有值,否则提示:is not empty! Reshard data away and try again. 若该节点有值,则需要把槽分配出去

./redis-trib.rb del-node 112.74.83.71:6006 916d26e9638dc51e168f32969da11e19c875f48f

配置文件补充

前几章Redis教程中介绍了以下配置

1 开启Redis 的守护进程 :daemonize yes

2 指定pid文件写入文件名 :pidfile /var/run/redis.pid

3 指定Redis 端口:port 6379

4 绑定的主机地址 :bind 127.0.0.1

5 Redis持久化默认开启压缩数据:rdbcompression yes

6 指定rdb文件名:dbfilename dump.rdb

7 指定rdb文件位置:dir ./

8 从机启动时,它会自动从master进行数据同步:slaveof 3b8f36e8511915bce7c9b299b6ebb319 740e73133ae348627555b474d9c495f6

9 开启aof持久化方式:appendonly yes

10 指定aof文件名:appendfilename appendonly.aof

11 触发aof快照机制:appendfsync everysec (no/always)

本章节是Redis教程中的最后一章,把剩下的配置也一起说了吧

1 设置客户端连接超时时间,0表示关闭 :timeout 300

2 设置Redis日志级别,debug、verbose(默认)、notice、warning:loglevel verbose

3 设置数据库的数量:databases 1

4 设置Redis连接密码:requirepass foobared

5 设置同一时间最大客户端连接数,默认无限制:maxclients 128

6 指定Redis最大内存限制:maxmemory e6ea25fe04e706feb596307d341ecaa0

7 指定是否启用虚拟内存机制:vm-enabled no

8 指定虚拟内存文件路径:vm-swap-file /tmp/redis.swap

9 指定包含其它的配置文件:include /path/to/local.conf

更多redis知识请关注redis数据库教程栏目。

以上是Redis高可用集群詳細介紹的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文轉載於:cnblogs.com。如有侵權,請聯絡admin@php.cn刪除