Bootstrap

Redis5.0.14集群搭建+springboot2.X整合redis集群

1.redis安装包下载

Redishttps://redis.io/download如果要选择其他版本

 这里有全部的redis版本Index of /releases/https://download.redis.io/releases/

我这里选择的版本是5.0.14 因为版本低于5.0需要基于ruby来搭建集群,而5.0以后不需要ruby 省了很多麻烦.

2.安装单台redis 

这里下载redis可以选择在线下载 我们将安装包下载到/usr/local目录下

1.首先在local目录创建一个redis目录 并且进入目录

[root@localhost local]# mkdir redis
[root@localhost local]# cd redis

2. 在该目录下解压并安装redis

# 下载
wget http://download.redis.io/releases/redis-5.0.14.tar.gz

# 解压
tar -zxvf redis-5.0.14.tar.gz 

# 安装c语言开发环境
yum install -y gcc 

# 进入到解压后的redis目录
cd  redis-5.0.14/

# 编译
make

# 安装到指定的目录
make install PREFIX=/usr/local/redis/redis-cluster

进入安装目录查看 

 在redis-cluster目录中有一个bin文件夹

3.拷贝配置文件

将解压目录中的redis.config文件复制到bin目录下

 

 找到解压文件中的redis.config,复制到安装目录下的bin文件夹下

 现在可以启动一下单机的redis

 使用命令 ./redis-server ./redis.config启动redis ./表示当前目录  后面的redis.config表示使用指定的配置文件启动

3.集群搭建 (三个节点 每个节点一主一从 共6台)

1.复制多台redis  

 

# 改名
mv bin/ 7001

# 复制
cp -r 7001/ 7002

2.修改   配置文件

分别修改7001-7006中的redis.config文件 ,需要修改的内容如下

# 注释掉端口绑定 
# 这里我们的redis是安装在vm虚拟机中的 访问的时候我们是通过windows中的代码访问,相当于跨机器了
# 如果不注释 跨机器是无法访问的
# bind 127.0.0.1

# 关闭保护模式 不关跨机器也无法连接到
protected-mode no

# 修改端口号 与我们文件夹名字一致
port 7001

# 开启后台运行 否则启动串口不能关闭
daemonize yes

# 修改后台运行时pid文件 与端口名一致
pidfile /var/run/redis_7001.pid

# 开启集群模式
cluster-enabled yes

# 集群配置文件 redis自动生成 
cluster-config-file nodes-7001.conf

# 打开超时设置
cluster-node-timeout 15000

修改完成后启动 7001-7006

一个一个的启动比较麻烦 我们可以添加一个启动脚本 一起启动

vim start.sh

在文件中添加以下启动的代码

cd /usr/local/redis/redis-cluster/7001
./redis-server ./redis.config

cd /usr/local/redis/redis-cluster/7002
./redis-server ./redis.config

cd /usr/local/redis/redis-cluster/7003
./redis-server ./redis.config

cd /usr/local/redis/redis-cluster/7004
./redis-server ./redis.config

cd /usr/local/redis/redis-cluster/7005
./redis-server ./redis.config

cd /usr/local/redis/redis-cluster/7006
./redis-server ./redis.config
给启动文件赋权

chmod a+x start.sh 

启动

./start.sh

查看 ps -ef | grep redis

将启动结果如下 

 3.集群

链接一个客户端

进入到7001-7006任意一个中 

./redis-cli -h 127.0.0.1 -p 7001

 -h 表示ip -p表示端口

我们链接客户端 现在直接存数据是不能用的 需要先创建集

 集群

1.先查看虚拟机ip地址 ifconfig

 2.集群

在7001-6中的任意一个 目录下执行

./redis-cli --cluster create 192.168.48.128:7001 192.168.48.128:7002 192.168.48.128:7003 192.168.48.128:7004 192.168.48.128:7005 192.168.48.128:7006 --cluster-replicas 1

 --cluster-replicas 1的意思是 每个节点只要一台备机 也就是slave节点 6台就是三主三从

 

 输入yes 可以看到集群成功

其中m开头表示master节点 s表示slave节点 

master 

7001 slots 0-5460

7003 slots 10923 - 16383

7002 5461 - 10922

slave

7006

7004

7005

上述的slots是哈希槽对应的值 有点类似hashmap 中获取数组的索引,利用hashcode计算key在数组中的索引,不一样的是 这里的索引在某个范围之类 都会指向同一个redis节点 

这里有个大坑,集群的时候千万不能使用127.0.0.1:7001这个ip去创建集群,否则跨机器的时候 连接不上 (在idea中 一直显示连接不上 但是在redis gui中又可以连上 ) 一定要使用本机的ip去创建.

查看集群信息

插入数据

可以看到 插入test这个key 要链接7002 端口  

 我们也可以用另外一种智能的方式去链接客户端

 ./redis-cli -c -h 127.0.0.1 -p 7001

 我们在链接客户端的时候添加一个 -c的参数

slot [6918]表示的test这个key通过某种方式计算得出的哈希值 6198 在 5461 - 10922之间 这个值应该属于7002这个master节点管理的范围 所以 redirected 到7002这个节点进行的保存操作

 4.springboot2.X整合redis集群

使用idea此创建一个springboot项目,勾选redis组件,也可以在已存在的项目(springboot项目)中添加redis的依赖

 添加redis集群配置

server:
  port: 8085

spring:
  redis:
    cluster:
      nodes:
        - 192.168.48.128:7001
        - 192.168.48.128:7002
        - 192.168.48.128:7003
        - 192.168.48.128:7004
        - 192.168.48.128:7005
        - 192.168.48.128:7006
      max-redirects: 3
    timeout: 5000ms
    lettuce:
      pool:
        max-wait: -1
        max-idle: 10
        max-active: 100
        min-idle: 5
       # enabled: true
   # host: 192.168.48.128
   # client-type: lettuce

测试

 由于没有指定序列化的方式,默认使用的是jdk序列化JdkSerializationRedisSerializer 这个序列化会出现上图中的看不懂的编码

于是我们需要指定序列化方式,添加redis配置类

import org.springframework.boot.autoconfigure.AutoConfigureAfter;
import org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.JdkSerializationRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;

@Configuration
@AutoConfigureAfter(RedisAutoConfiguration.class)
public class RedisConfig {
    @Bean
    public RedisTemplate<String, Object> redisCacheTemplate(LettuceConnectionFactory redisConnectionFactory) {
        RedisTemplate<String, Object> template = new RedisTemplate<>();
        template.setKeySerializer(new StringRedisSerializer());
        template.setValueSerializer(new GenericJackson2JsonRedisSerializer());
        //template.setValueSerializer(new JdkSerializationRedisSerializer());
        template.setConnectionFactory(redisConnectionFactory);
        return template;
    }

}

如果注入的redistemplate未指定key和value的数据类型 默认key与value都是object类型的 通过上图中 第二个bean修改序列化方式 

如果我们导入的是指定类型的RedisTemplate<K,V> 必须要配置RedisTemplate,否则会抛出异常

NoSuchBeanDefinitionException: No qualifying bean of type 'org.springframework.data.redis.core.RedisTemplate<java.lang.String, java.lang.Object>'  

关于redis不可用 

 先链接任意客户端:查看集群信息如下:

 可以看出7003端口为master节点

再链接7003端口 查看7003的从节点

 结合第一个图可以看出 7006是7003的从节点 现在我们shutdown关掉7003

 当我们关掉7003这个master的时候 它的从节点7006自动升级为master节点

此时 向redis集群插入数据是ok的

现在我们将7006也关掉

现在7006 与 7003都挂掉了 原来的3个master只剩下2个 这时集群将不可用,

哈希槽是16384个 被三个节点均匀分配 现在缺失一个节点,会导致部分哈希槽值的key没有地方存,而导致redis集群不可用

;