1、redis 使用模式
1.1 单机模式
1.1.1 编译安装方式
1.1.1.1 下载
Redis的安装非常简单,到Redis的官网(Downloads - Redis),下载对应的版本,简单几个命令安装即可。
1.1.1.2 编译安装
tar xzf redis-stable.tar.gz
cd redis-stable/
make & make install
安装完成后
cd /usr/local/bin/
1.1.1.3 安装常见问题
如果执行make命令报错:cc 未找到命令,原因是虚拟机系统中缺少gcc,执行下面命令安装gcc:
yum -y install gcc automake autoconf libtool make
如果执行make命令报错:致命错误:jemalloc/jemalloc.h: 没有那个文件或目录,则需要在make指定分配器为libc。执行下面命令即可正常编译:
make MALLOC=libc
1.1.1.4 redis单机启动
Redis编译完成后,会生成几个可执行文件,这些文件各有各的作用,我们现在先简单了解下,后面的课程会陆续说到和使用这些可执行文件。
1.1.1.4.1 默认启动
使用Redis的默认配置来启动,在bin目录下直接输入 ./redis-server
可以看到直接使用redis-server启动Redis后,会打印出一些日志,通过日志可以看到一些信息:
当前的Redis版本的是64位的6.2.7,默认端口是6379。Redis建议要使用配置文件来启动。
因为直接启动无法自定义配置,所以这种方式是不会在生产环境中使用的。
1.1.1.4.2 带参启动
redis-server加上要修改配置名和值(可以是多对),没有设置的配置将使用默认配置,例如:如果要用6380作为端口启动Redis,那么可以执行:
./redis-server --port 6380
这种方式一般我们也用得比较少。
1.1.1.4.3 配置文件启动
配置文件是我们启动的最多的模式,配置文件安装目录中有
一般会采用将redis.conf cp 到一个新文件夹的方式,并使用./redis-server <path>/redis.conf
的形式来开启一台新的redis 服务器
1.1.2 docker 安装方式
1.1.2.1 下载
docker pull redis
1.1.2.2 配置
mkdir -p /mydata/redis/conf
touch /mydata/redis/conf/redis.conf
#bind 127.0.0.1 #注释掉这部分,这是限制redis只能本地访问
#bind 127.0.0.1
#protected-mode no #默认yes,开启保护模式,限制为本地访问
protected-mode no
#daemonize no#默认no,改为yes意为以守护进程方式启动,可后台运行,除非kill进程,改为yes会使配置文件方式启动redis失败
daemonize no
#appendonly yes #redis持久化(可选)
appendonly yes
#主从复制,从读
replica-read-only yes
requirepass admin123
# min-replicas-to-write 3
# min-replicas-max-lag 10
1.1.2.3 启动
docker run -p 6379:6379 --name redis -v /mydata/redis/data:/data \
-v /mydata/redis/conf/:/etc/redis/ \
--restart=always \
-d redis --appendonly yes
1.2 主从模式
主从模式与哨兵模式的区别为,哨兵模式需要另外启动3个哨兵
1.2.1 配置
daemonize yes
#bind 127.0.0.1
protected-mode no
port 6380
appendonly yes
dir /mydata/redis/6380/dumpfiles
pidfile /var/run/redis_6380.pid
logfile "/mydata/redis-cluster/6380/redis.log"
requirepass 111111
#从机需要配置,主机不用
masterauth "111111"
replicaof 192.168.10.131 6380
#移除高危操作键
rename-command keys ""
rename-command flushdb ""
rename-command flushall ""
1.2.2 启动服务器
#主机先启动, 再启动从机
redis-server /mydata/redis-cluster/6380/redis.conf
redis-server /mydata/redis-cluster/6381/redis.conf
redis-server /mydata/redis-cluster/6382/redis.conf
1.2.3 检查结果
# 进入客户端
redis-cli -h 127.0.0.1 -p 6380 -a 111111
redis-cli -h 127.0.0.1 -p 6381 -a 111111
redis-cli -h 127.0.0.1 -p 6382 -a 111111
1.3 哨兵模式
1.3.1 sentinel 配置
bind 0.0.0.0
#是否以后台daemon方式运行
daemonize yes
#安全保护模式
protected-mode no
# 端口
port 26379
#日志文件
logfile "/mydata/redis-cluster/26379/sentinel.log"
#pid文件路径
pidfile /var/run/redis-sentinel26379.pid
#工作目录
dir /mydata/redis-cluster/26379
# sentinel monitor <master-name> <ip> <redis-port> <quorum>
#设置要监控的master服务器,quorum 表示最少要有几个哨兵认可下线,同意故障迁移的票数
sentinel monitor mymaster 192.168.10.131 6380 2
#连接master服务的密码
sentinel auth-pass mymaster 111111
1.3.2 启动哨兵
redis-sentinel /mydata/redis-cluster/26379/sentinel.conf --sentinel
redis-sentinel /mydata/redis-cluster/26380/sentinel.conf --sentinel
redis-sentinel /mydata/redis-cluster/26381/sentinel.conf --sentinel
1.3.3 检查状态
#查看进程情况
ps -ef | grep redis
#查看单机情况
#登录客户端
redis-cli -p 6380 -a 111111
#查看详情
info replication
1.4 集群模式
1.4.1 集群模式配置
#87行
#bind 127.0.0.1
#309行
daemonize yes
#111行
protected-mode no
#138行
port 6381
#341行
pidfile /mydata/redis-cluster/6381/redis.pid
#355行
logfile "/mydata/redis-cluster/6381/cluster.log"
#510行
dir /mydata/redis-cluster/6381/dumpfiles
#1387行
appendonly yes
#539 540行
requirepass 111111
masterauth 111111
# 1584 1592 1598 行
cluster-enabled yes
cluster-config-file /mydata/redis-cluster/6379/nodes.conf
cluster-node-timeout 5000
#移除高危操作键
rename-command keys ""
rename-command flushdb ""
rename-command flushall ""
1.4.2 启动服务器
# 各自启动主机
redis-server /mydata/redis-cluster/6580/redis.conf
...
#构建集群关系
redis-cli -a 111111 --cluster create --cluster-replicas 1 192.168.10.131:6580 192.168.10.131:6581 192.168.10.131:6582 192.168.10.131:6583 192.168.10.131:6584 192.168.10.131:6585
1.4.3 集群使用
#连接客户端 后面添加 -c 用来自动确认对应slot
#不加 -c 异常
# (error) MOVED 12706 192.168.10.131:6582
redis-cli -h 192.168.10.131 -p 6580 -a 111111 -c
# 查看某个Key 所在的slot
cluster keyslot k1
#master节点下线后,slave 会切换为master ,原master 会以 slave的方式回归
#手动切换从属关系
cluster failover
# 检查集群状态
redis-cli -a 111111 --cluster check 192.168.10.131:6580
2、整合
2.1 主从模式
与哨兵模式一致
2.2 哨兵模式
2.2.1 POM.XML
<!--redis-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-pool2</artifactId>
</dependency>
2.2.2 application.yml
spring:
data:
redis:
lettuce:
pool:
enabled: true
max-active: 8
max-idle: 8
min-idle: 0
max-wait: -1ms
sentinel:
master: mymaster
nodes:
- 192.168.10.131:26379
- 192.168.10.131:26380
- 192.168.10.131:26381
database: 0
password: 111111
2.2.3 添加RedisConfig类
@Configuration
public class RedisConfig {
@Bean
@ConditionalOnMissingBean
public RedisTemplate<String, Object> redisTemplate(LettuceConnectionFactory redisConnectionFactory) {
RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
redisTemplate.setConnectionFactory(redisConnectionFactory);
//设置key序列化方式string
redisTemplate.setKeySerializer(new StringRedisSerializer());
//设置value的序列化方式json,使用GenericJackson2JsonRedisSerializer替换默认序列化
redisTemplate.setValueSerializer(new GenericJackson2JsonRedisSerializer());
redisTemplate.setHashKeySerializer(new StringRedisSerializer());
redisTemplate.setHashValueSerializer(new GenericJackson2JsonRedisSerializer());
redisTemplate.afterPropertiesSet();
return redisTemplate;
}
/**
* 增加部分
* 读写分离
* @return
*/
@Bean
public LettuceClientConfigurationBuilderCustomizer clientConfigurationBuilderCustomizer() {
return clientConfigurationBuilder -> clientConfigurationBuilder.readFrom(ReadFrom.REPLICA);
}
}
业务类查阅集群模式2.3.4
2.3 集群模式
2.3.1 POM.XML
<!--redis-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-pool2</artifactId>
</dependency>
2.3.2 application.yml
server:
port: 7777
spring:
application:
name: redis-demo
data:
redis:
cluster:
nodes:
- 192.168.10.131:6580
- 192.168.10.131:6581
- 192.168.10.131:6582
- 192.168.10.131:6583
- 192.168.10.131:6584
- 192.168.10.131:6585
max-redirects: 3
password: 111111
database: 0
lettuce:
pool:
max-active: 8
max-wait: -1ms
max-idle: 8
min-idle: 0
cluster:
refresh:
#支持集群拓扑动态感应刷新,自适应拓扑刷新是否使用所有可用的更新,默认false关闭
adaptive: true
#定时刷新
period: 2000ms
2.3.3 添加Redis.config 类
@Configuration
public class RedisConfig {
@Bean
public RedisTemplate<String, Object> redisTemplate(LettuceConnectionFactory redisConnectionFactory) {
RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
redisTemplate.setConnectionFactory(redisConnectionFactory);
//设置key序列化方式string
redisTemplate.setKeySerializer(new StringRedisSerializer());
//设置value的序列化方式json,使用GenericJackson2JsonRedisSerializer替换默认序列化
redisTemplate.setValueSerializer(new GenericJackson2JsonRedisSerializer());
redisTemplate.setHashKeySerializer(new StringRedisSerializer());
redisTemplate.setHashValueSerializer(new GenericJackson2JsonRedisSerializer());
redisTemplate.afterPropertiesSet();
return redisTemplate;
}
}
2.3.4 业务类
2.3.4.1 service
#service
public interface OrderService {
/**
* 创建订单 key
* @param key
* @return
*/
void createOrder(String key);
public String getOrder(String key);
}
#serviceImpl
@Service
@Slf4j
public class OrderServiceImpl implements OrderService {
public static final String ORDER_KEY = "order:";
@Resource
private RedisTemplate<String, Object> redisTemplate;
@Override
public void createOrder(String key) {
String orderNo = UUID.randomUUID().toString();
redisTemplate.opsForValue().set(ORDER_KEY + key, orderNo);
log.info("=====>编号" + key + "的订单流水生成:{}", orderNo);
}
@Override
public String getOrder(String key) {
return Objects.requireNonNull(redisTemplate.opsForValue().get(ORDER_KEY + key)).toString();
}
}
2.3.4.2 controller
@RestController
@RequestMapping("/lettuce")
@Slf4j
public class Demo {
@Resource
private OrderService orderService;
@GetMapping("/create")
public String createOrder() {
String key = UUID.randomUUID().toString();
orderService.createOrder(key);
return key;
}
@GetMapping("/get/{key}")
public String getOrder(@PathVariable("key") String key) {
return orderService.getOrder(key);
}
}
2.3.5故障
Redis Cluster集群部署采用了3主3从拓扑结构,数据读写访问master节点, slave节点负责备份。
当master宕机主从切换成功,redis手动OK,but 2个经典故障
问题的解决方案为:
添加定时刷新参数
spring:
data:
redis:
lettuce:
cluster:
refresh:
#支持集群拓扑动态感应刷新,自适应拓扑刷新是否使用所有可用的更新,默认false关闭
adaptive: true
#定时刷新
period: 2000ms