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集群不可用