Redis集群设置

  • 1. 安装依赖
  • 2. 集群介绍
  • 3.集群搭建
  • 3.1 搭建配置
  • 3.2 启动redis
  • 3.3 创建集群
  • 4. 槽
  • slot : 槽,集群共有16384个slot,索引为 0-16383。如下为【主机1,2,3】【从机a,b,c】
  • 5. 连接集群
  • 6. 集群操作
  • 7.连接集群-java【重点】
  • **`无论连接的是 单点redis,还是集群的redis,Spring-Data-Redis的所有API不变`**
  • 8. 添加主节点
  • 8.1 添加新节点
  • 8.2 重新分片
  • 9.添加从节点
  • 9.1 添加新节点
  • 10.密码
  • 10.1 添加密码
  • 10.2 登录
  • 10.3 主从
  • 10.4 多主多从集群密码
  • 10.4.1 搭建配置
  • `配置中不设置密码和主机密码`
  • 10.4.2 设置密码
  • 10.4.3 搭建集群
  • 10.4.4 连接集群
  • 10.4.5 Java连接


1. 安装依赖

按照"redis集群所需要的依赖"中的解决方案,安装依赖即可。

#Redis集群依赖资源安装流程,需要压缩包【ruby-2.4.2.tar.gz】

  • yum -y install gcc zlib-devel openssl openssl-devel
  • tar -zxvf ruby-2.4.2.tar.gz
  • cd到解压目录
  • ./configure --prefix=/usr/local/rj_ruby
  • make && make install
  • 在解压目录下操作yum -y install rubygems
  • rm -f /usr/bin/ruby
    rm -f /usr/bin/gem
    ln -s /usr/local/rj_ruby/bin/gem /usr/bin/gem**
    ln -s /usr/local/rj_ruby/bin/ruby /usr/bin/ruby
  • gem install redis -v 3.3.5 #测试3.2.1到3.3.5都可以,4.x以上的分片报错


2. 集群介绍

redis3.x 后的集群 ,是多主多从的集群,多个主机组成一个集群的主体,共同负责对外提供读写服务。

每个主机都有自己的从机,从机的主要工作是:1. 同步主机数据 2.当主机宕机时顶替主机。

redisson 集群模式配置 redis集群设置_redis集群



3.集群搭建

注意,集群的搭建,至少需要6台虚拟机,因为至少3台主机才能形成集群,每个主机至少有一个从机。

3.1 搭建配置

# 当前虚拟机的Redis,开启cluster支持
cluster-enabled yes
# 当前虚拟机的Redis 用来保存集群信息的文件,保存位置在工作目录下
cluster-config-file nodes-9001.conf
# bind配置中不配置127.0.0.1,否则redis会自动以127.0.0.1作为ip,使得无法通过java远程连接集群
bind 192.168.110.135

如上为两个核心配置,完整配置文件,详见 "rediss"目录,

将此目录直接上传给linux,放在 "/usr/local"目录即可。

如上配置目录中,定义了7份配置,用来启动7个redis服务(模拟7台虚拟机)

3.2 启动redis

这里可以配置脚本文件,用于批量开启和关闭主机和从机,配置内容如下

  • startall.sh
#!/bin/bash
redis-server /usr/local/redis/redis-4.0.14/redis-cluster/9001/redis.conf
redis-server /usr/local/redis/redis-4.0.14/redis-cluster/9002/redis.conf
redis-server /usr/local/redis/redis-4.0.14/redis-cluster/9003/redis.conf
redis-server /usr/local/redis/redis-4.0.14/redis-cluster/9004/redis.conf
redis-server /usr/local/redis/redis-4.0.14/redis-cluster/9005/redis.conf
redis-server /usr/local/redis/redis-4.0.14/redis-cluster/9006/redis.conf
echo "start all redis SUCCESS!"
  • shutall.sh
#!/bin/bash
redis-cli -p 9001 -h 192.168.80.128 shutdown
redis-cli -p 9002 -h 192.168.80.128 shutdown
redis-cli -p 9003 -h 192.168.80.128 shutdown
redis-cli -p 9004 -h 192.168.80.128 shutdown
redis-cli -p 9005 -h 192.168.80.128 shutdown
redis-cli -p 9006 -h 192.168.80.128 shutdown
echo "start all redis SUCCESS!"

开启主从机器

# 在/usr/local/redis_cluster目录下执行,启动6个redis服务
# 注意是否有执行权限ll
./startall.sh
# 添加权限
chmod u+x startall.sh
# 查看redis服务
ps -ef | grep redis
root      1448     1  1 17:33 ?        00:00:00 redis-server 127.0.0.1:9001 [cluster]         
root      1450     1  1 17:33 ?        00:00:00 redis-server 127.0.0.1:9002 [cluster]         
root      1455     1  1 17:33 ?        00:00:00 redis-server 127.0.0.1:9003 [cluster]         
root      1460     1  1 17:33 ?        00:00:00 redis-server 127.0.0.1:9004 [cluster]         
root      1465     1  0 17:33 ?        00:00:00 redis-server 127.0.0.1:9005 [cluster]         
root      1470     1  1 17:33 ?        00:00:00 redis-server 127.0.0.1:9006 [cluster]

3.3 创建集群

# 在 /usr/local/redis-4.0.14/src 目录下执行,开始创建集群
./redis-trib.rb create --replicas 1 192.168.80.128:9001  192.168.80.128:9002  192.168.80.128:9003 192.168.80.128:9004 192.168.80.128:9005 192.168.80.128:9006

如下,最后输入 “yes”

>>> Creating cluster
>>> Performing hash slots allocation on 6 nodes...
Using 3 masters:
192.168.110.135:9001
192.168.110.135:9002
192.168.110.135:9003
Adding replica 192.168.110.135:9005 to 192.168.110.135:9001
Adding replica 192.168.110.135:9006 to 192.168.110.135:9002
Adding replica 192.168.110.135:9004 to 192.168.110.135:9003
>>> Trying to optimize slaves allocation for anti-affinity
[WARNING] Some slaves are in the same host as their master
M: c3e026595c56e989cbcef7bcb6ac868b458141df 192.168.110.135:9001
   slots:0-5460 (5461 slots) master
M: 29fe6ceb1d7b698bfe161f8d8e15f9ee8d735527 192.168.110.135:9002
   slots:5461-10922 (5462 slots) master
M: 67e692825590b41b5017e93c9090eed82fc9f3b1 192.168.110.135:9003
   slots:10923-16383 (5461 slots) master
S: 27ecc39812069e764d880002d67bd252c78b051d 192.168.110.135:9004
   replicates 29fe6ceb1d7b698bfe161f8d8e15f9ee8d735527
S: 721c200f8e5cff46ab5b3332d9be01c988e37c9e 192.168.110.135:9005
   replicates 67e692825590b41b5017e93c9090eed82fc9f3b1
S: 07401d81b187002cbca95ec979580436a14e0d5d 192.168.110.135:9006
   replicates c3e026595c56e989cbcef7bcb6ac868b458141df
Can I set the above configuration? (type 'yes' to accept): yes

见到如下输出,集群即创建完毕:

M: c3e026595c56e989cbcef7bcb6ac868b458141df 192.168.110.135:9001
   slots:0-5460 (5461 slots) master
   1 additional replica(s)
M: 67e692825590b41b5017e93c9090eed82fc9f3b1 127.0.0.1:9003
   slots:10923-16383 (5461 slots) master
   1 additional replica(s)
S: 721c200f8e5cff46ab5b3332d9be01c988e37c9e 127.0.0.1:9005
   slots: (0 slots) slave
   replicates 67e692825590b41b5017e93c9090eed82fc9f3b1
S: 27ecc39812069e764d880002d67bd252c78b051d 127.0.0.1:9004
   slots: (0 slots) slave
   replicates 29fe6ceb1d7b698bfe161f8d8e15f9ee8d735527
M: 29fe6ceb1d7b698bfe161f8d8e15f9ee8d735527 127.0.0.1:9002
   slots:5461-10922 (5462 slots) master
   1 additional replica(s)
S: 07401d81b187002cbca95ec979580436a14e0d5d 127.0.0.1:9006
   slots: (0 slots) slave
   replicates c3e026595c56e989cbcef7bcb6ac868b458141df
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.



4. 槽

slot : 槽,集群共有16384个slot,索引为 0-16383。如下为【主机1,2,3】【从机a,b,c】

M: c3e026595c56e989cbcef7bcb6ac868b458141df 192.168.110.135:9001 【主机1】
   slots:0-5460 (5461 slots) master 【主机1】
   1 additional replica(s) 【主机1有1个从机】
M: 67e692825590b41b5017e93c9090eed82fc9f3b1 127.0.0.1:9003 【主机2】
   slots:10923-16383 (5461 slots) master 【主机2】
   1 additional replica(s) 【主机2有1个从机】
S: 721c200f8e5cff46ab5b3332d9be01c988e37c9e 127.0.0.1:9005 【从机a】
   slots: (0 slots) slave 【从机a】
   replicates 67e692825590b41b5017e93c9090eed82fc9f3b1 【从机a的主机的id,则从机a是属于主机2的】
S: 27ecc39812069e764d880002d67bd252c78b051d 127.0.0.1:9004 【从机b】
   slots: (0 slots) slave 【从机b】
   replicates 29fe6ceb1d7b698bfe161f8d8e15f9ee8d735527  【从机b的主机的id,则从机b是属于主机3的】
M: 29fe6ceb1d7b698bfe161f8d8e15f9ee8d735527 127.0.0.1:9002 【主机3】
   slots:5461-10922 (5462 slots) master 【主机3】
   1 additional replica(s) 【主机3有1个从机】
S: 07401d81b187002cbca95ec979580436a14e0d5d 127.0.0.1:9006 【从机c】
   slots: (0 slots) slave 【从机c】
   replicates c3e026595c56e989cbcef7bcb6ac868b458141df  【从机c的主机的id,则从机c是属于主机1的】
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.

如上是集群中的3主 3从,主机1持有槽【0-5460】 主机2持有槽【10923-16383】 主机3持有槽【5461-10922】。

注意:只有主机才占有槽,槽并不是一个存储单位。槽是redis集群做负载均衡的计量。

要进一步理解槽,需要看完 5,6两个章节



5. 连接集群

# -c 即代表要连接集群
 redis-cli -c -p 9001 -h 192.168.80.128



6. 集群操作

192.168.110.135:9001> set name zhj
-> Redirected to slot [5798] located at 127.0.0.1:9002 【经计算 name应该由9002存储】
OK

192.168.110.135:9002> set gender true
-> Redirected to slot [15355] located at 127.0.0.1:9003 【经计算 gender应该由9003存储】
OK

192.168.110.135:9003> set age 19
-> Redirected to slot [741] located at 127.0.0.1:9001  【经计算 age应该由9001存储】
OK

所谓的计算,是对读/写 操作中的 key 做一致性hash运算,得到一个数字 num, 然后 num%16384

得到 一个 [0--16383]区间的数字

如 name 的运算结果为 5798 gender的运算结果为15355 age的运算结果为741

5798,15355,741是槽的下标,则对应的key由对应主机存储



7.连接集群-java【重点】

使Java可以连接到集群,需要设置【PropertiesPropertySource】,导入ip分节点(至少两个,保证一个宕机后另一个可用)以及重试次数。

然后将【PropertiesPropertySource】导入【RedisClusterConfiguration】

最后将【RedisClusterConfiguration】导入【JedisConnectionFactory】

<!-- 为 redisClusterConfiguration定制参数配置-->
<bean id="propertySource" class="org.springframework.core.env.PropertiesPropertySource">
    <constructor-arg index="0" type="java.lang.String" value="redis_cluster"/>
    <constructor-arg index="1" type="java.util.Properties">
        <props>
            <prop key="spring.redis.cluster.nodes">192.168.80.128:9001,192.168.80.128:9002</prop>
            <prop key="spring.redis.cluster.max-redirects">5</prop>
        </props>
    </constructor-arg>
</bean>

<!--将PropertiesPropertySource放入RedisClusterConfiguration-->
<!--最后将其放入到JedisConnectionFactory-->
<bean id="redisClusterConfiguration"  class="org.springframework.data.redis.connection.RedisClusterConfiguration">
    <constructor-arg name="propertySource" ref="propertySource"/>
</bean>

<!--连接factory-->
<bean id="jedisConnectionFactory"
      class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory">
    <!-- Redis主机,非集群的可以删除了 -->
    <!--<property name="hostName" value="192.168.80.128"></property>-->
    <!--<property name="port" value="7777"></property>-->
    <!--<property name="poolConfig" ref="jedisPoolConfig"></property>-->
    <!-- Redis主机集群配置+连接池配置信息 -->
    <constructor-arg name="poolConfig" ref="jedisPoolConfig"/>
    <constructor-arg name="clusterConfig" ref="redisClusterConfiguration"/>
    <!-- 连接池配置信息 -->
</bean>
无论连接的是 单点redis,还是集群的redis,Spring-Data-Redis的所有API不变



8. 添加主节点

8.1 添加新节点

增加一套配置,并以此配置启动redis实例。并执行如下指令;

新机器的ip:port      集群某个成员的ip:port
[root@rj04 src]# ./redis-trib.rb add-node 192.168.79.128:9007 192.168.79.128:9006
如果成功,会有如下输出
>>> Adding node 192.168.79.128:9007 to cluster 192.168.79.128:9006
>>> Performing Cluster Check (using node 192.168.79.128:9006)
S: f6eb31694591a3d7d4d63a13d6775d0397ccabcc 192.168.79.128:9006
   slots: (0 slots) slave
   replicates 9a4d54b36e525118b1b9c0f94c65320e5584feb7
S: 3ababf9bd48fab51f0e786ba36dfbdab43e31741 192.168.79.128:9005
   slots: (0 slots) slave
   replicates 8c8acf426bc93340b01942b8567230db7bd82577
M: 8c8acf426bc93340b01942b8567230db7bd82577 192.168.79.128:9003
   slots:10923-16383 (5461 slots) master
   1 additional replica(s)
S: 9b7d58f0be57d54e6044dc1a8101f12e0fddc849 192.168.79.128:9004
   slots: (0 slots) slave
   replicates 798e705d85c0e6bd432e7103a6b5ccad0f30f29c
M: 9a4d54b36e525118b1b9c0f94c65320e5584feb7 192.168.79.128:9001
   slots:0-5460 (5461 slots) master
   1 additional replica(s)
M: 798e705d85c0e6bd432e7103a6b5ccad0f30f29c 192.168.79.128:9002
   slots:5461-10922 (5462 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.79.128:9007 to make it join the cluster.
[OK] New node added correctly.

8.2 重新分片

新加的主机没有slot,需要将已有主机的slot分出部分给它。最终保证所有主机的slot个数是均衡的。

执行如下指令,开始重新分片:

新机器的ip:port
[root@rj04 src]# ./redis-trib.rb reshard 192.168.79.128:9008
下一步,会有如下输出
How many slots do you want to move (from 1 to 16384)? [在此输入要给新机器分配的槽的数量]
下一步,会有如下输出
What is the receiving node ID? [在此输入新机器的节点id]
下一步,会有如下输出
Please enter all the source node IDs.
  Type 'all' to use all the nodes as source nodes for the hash slots.
  Type 'done' 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@zhj04 src]# ./redis-trib.rb check 192.168.79.128:9002



9.添加从节点

9.1 添加新节点

此过程和 8.1章节一样,先复制一套配置,然后开启新的redis节点.

然后,执行如下指令:

从机             主机id
[root@rj04 src]# ./redis-trib.rb  add-node --slave --master-id ad27f044c31b8c3e0e43a5b1dff080144d9ca85f 192.168.79.128:9008 192.168.79.128:9006
    新机器ip:port        已有及其ip:port



10.密码

10.1 添加密码

# 在/usr/local/redis/redis-4.0.14/redis_conf/redis.conf中修改,也就是主机修改,而非集群机
# 设置访问密码
# 这在您不信任的环境中可能很有用,其他可以随意访问主机的用户,却不能随意访问redis。
requirepass zhj

10.2 登录

# 连接
redis-cli -p 8000
# 连接后无法执行任何读写操作,需要如下,输入密码
auth zhj
// Jedis使用密码
Jedis jedis = new Jedis("192.168.110.135", 8000);
jedis.auth("zhj");
<!-- SpringData-Redis 使用密码 -->
<bean id="jedisConnectionFactory"
      class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory">
    <!-- Redis主机 -->
    <property name="hostName" value="192.168.110.135"></property>
    <property name="port" value="8000"></property>
    <!-- 连接池配置信息 -->
    <property name="poolConfig" ref="jedisPoolConfig"></property>
    <!-- 指定密码 -->
    <property name="password" value="zhj"/>
</bean>

10.3 主从

# 从机端需要设置 主机的密码,否则从机无法连接主机
# 同样是在从机的redis.conf文件中配置主机密码
masterauth zhj

10.4 多主多从集群密码

10.4.1 搭建配置

配置中不设置密码和主机密码

10.4.2 设置密码

在每个主机下执行如下指令:

config set masterauth zhj

config set requirepass zhj

auth zhj

config rewrite

[root@claz rediss]# redis-cli -h 192.168.110.135 -p 9001
192.168.110.135:9001> config set masterauth zhj #设置主机密码,用于从机连接主机
OK
192.168.110.135:9001> config set requirepass zhj #设置连接密码
OK
192.168.110.135:9001> auth  zhj #输入密码
OK
192.168.110.135:9001> config rewrite #将配置写入到配置文件redis.conf中
OK

10.4.3 搭建集群

/usr/local/rj_ruby/lib/ruby/gems/2.4.0/gems/redis-3.3.5/lib/redisruby安装目录下的client.rb,修改

class Redis
  class Client

    DEFAULTS = {
      :url => lambda { ENV["REDIS_URL"] },
      :scheme => "redis",
      :host => "127.0.0.1",
      :port => 6379,
      :path => nil,
      :timeout => 5.0,
      :password => "zhj", #此处指定密码,在执行ruby指令时,即可自动通过。 如 create check,info,reshard等等
      :db => 0,
      :driver => nil,
      :id => nil,
      :tcp_keepalive => 0,
      :reconnect_attempts => 1,
      :inherit_socket => false
    }
    ....

创建集群
注意,如果没有上一步设置,ruby不能通过redis的身份认证(密码)

./redis-trib.rb create --replicas 1 192.168.110.135:9001 192.168.110.135:9002 192.168.110.135:9003 192.168.110.135:9004 192.168.110.135:9005 192.168.110.135:9006

10.4.4 连接集群

[root@rj redis_cluster]redis-cli -c -a zhj -h 192.168.110.135 -p 9001

如上用 -a 指定密码即可,官方不建议用此参数

10.4.5 Java连接

两个重点:

  1. 不用指定所有节点,但如果能多指定几个更好,防止节点宕机
  2. 集群密码指定

在最后注入的工厂【JedisConnectionFactory】中,配置如下属性

<property name="password" value="zhj"/>