redis基础
概念:基于c的 k-v的内存型非关系型数据库
作用:缓存、模拟session、消息队列
特点:命令执行是单线程的、线程安全
数据类型
Redis存储的是key-value结构的数据,其中key是字符串类型,value有5种常用的数据类型:
- 字符串 string
- 哈希 hash
- 列表 list
- 集合 set
- 有序集合 sorted set / zset
简单使用方式
导包
代码语言:javascript复制<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
配置
代码语言:javascript复制sky:
redis:
host: localhost
port: 6379
password: 123456
database: 0
代码
代码语言:javascript复制package com.sky.config;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.StringRedisSerializer;
@Configuration
@Slf4j
public class RedisConfiguration {
@Bean
public RedisTemplate redisTemplate(RedisConnectionFactory redisConnectionFactory){
log.info("开始创建redis模板对象...");
RedisTemplate redisTemplate = new RedisTemplate();
//设置redis的连接工厂对象
redisTemplate.setConnectionFactory(redisConnectionFactory);
//设置redis key的序列化器
redisTemplate.setKeySerializer(new StringRedisSerializer());
return redisTemplate;
}
}
Redis高级
持久化策略
分为RDB和AOF
RDB
代码语言:javascript复制概念:数据快照,默认开启持久化策略
将Redis内存中的数据定期或根据需要快照到磁盘上
优点: 数据持久化到硬盘,效率高
缺点:会出现数据丢失
AOF
代码语言:javascript复制概念:追加文件,每条命令都记录在AOF文件上
优点:数据完整性高
缺点:效率低
区别
RDB | AOF | |
---|---|---|
是否默认开启 | 默认 | 手动开启 |
备份文件大小 | 小 | 大 |
性能 | 好 | 差 |
资源占用 | 高 | 低 |
数据完整性 | 差 | 高 |
文件存储方式 | 数据快照 | 写命令 |
恢复速度 | 快 | 慢 |
redis.conf配置文件来开启AOF
代码语言:javascript复制# 是否开启AOF功能,默认是no
appendonly yes
# AOF文件的名称
appendfilename "appendonly.aof"
redis.conf配置文件来AOF的命令记录的频率
代码语言:javascript复制# 表示每执行一次写命令,立即记录到AOF文件
appendfsync always
# 写命令执行完先放入AOF缓冲区,然后表示每隔1秒将缓冲区数据写到AOF文件,是默认方案
appendfsync everysec
# 写命令执行完先放入AOF缓冲区,由操作系统决定何时将缓冲区内容写回磁盘
appendfsync no
redis.conf配置文件来配置阈值
代码语言:javascript复制# AOF文件比上次文件 增长超过多少百分比则触发重写
auto-aof-rewrite-percentage 100
# AOF文件体积最小多大以上才触发重写
auto-aof-rewrite-min-size 64mb
集群
代码语言:javascript复制集群就是使用网络将若干台计算机联通起来,并提供统一的服务
主从集群
代码语言:javascript复制概念:部署多个redis节点,一个master节点,跟随一个或多个slave节点
作用:主从第一次连接的时候,就会执行全量同步,用来备份数据和提高并发支撑
优点:可以备份数据、提高并发支撑
搭建流程
代码语言:javascript复制1.准备主从Redis实例:在不同的服务器上安装Redis并启动。其中,一个Redis实例作为主节点,其他Redis实例作为从节点。
2.配置主节点:在主节点的redis.conf配置文件中,设置bind绑定主节点的IP地址,设置port端口号,设置slaveof 选项为 no one,表示主节点不从其他节点同步数据。
3.配置从节点:在从节点的redis.conf配置文件中,设置bind绑定从节点的IP地址,设置port端口号,设置slaveof 选项为主节点的IP地址和端口号,表示从节点要从主节点同步数据。
4.启动Redis实例:分别启动主节点和从节点的Redis实例。
5.验证主从同步:使用命令info replication可以查看主从节点的同步状态,确保主节点与从节点已成功建立连接并同步数据。
6.测试主从切换:可以通过关闭主节点的Redis实例来模拟主节点故障,从而验证主从切换的可靠性。
需要注意的是,主从节点之间的网络延迟和带宽限制可能会影响数据同步的效率和准确性。为了优化主从同步效率,可以使用Redis提供的复制积压缓冲区和复制粘贴缓冲区等功能。同时,为了确保数据的安全性,可以在主节点上配置Redis的密码保护机制。
哨兵集群
代码语言:javascript复制概念:基于分布式系统,对Redis服务器进行监控、通知、故障转移一种模式
作用:实现主从集群的自动故障恢复
优点:可以备份数据、提高并发支撑、自动恢复
注意:哨兵要是单数,所以最少需要3台哨兵,不提供数据服务;搭建集群至少要有六台服务器其中三台用来备份 三台用来投票
流程
代码语言:javascript复制1.配置Redis实例:在不同的服务器上安装Redis,并分别配置不同的端口号和密码,以避免冲突和安全性问题。
2.启动Redis实例:分别启动多个Redis实例,其中一个为主节点,其余为从节点。
3.配置哨兵节点:在哨兵节点的redis.conf配置文件中,设置sentinel monitor选项,指定要监控的主节点的名称、IP地址和端口号等信息。
4.启动哨兵节点:分别启动多个哨兵节点的Redis实例,这些哨兵节点会自动发现并监控指定的主节点和从节点。
5.监控主节点状态:哨兵节点会定期向主节点发送PING命令,以检查主节点的状态是否正常,如果主节点没有响应,哨兵节点就会认为主节点已宕机。
6.选举新的主节点:当哨兵节点检测到主节点宕机时,会将一个从节点选举为新的主节点,并将其他从节点重新配置为新主节点的从节点。
7.客户端自动重定向:当主节点切换后,客户端需要重新连接新的主节点,这时哨兵节点会自动将客户端重定向到新的主节点。
需要注意的是,哨兵集群需要部署多个哨兵节点来保证高可用性,建议至少部署3个哨兵节点。此外,哨兵节点也需要配置密码保护机制,以确保系统的安全性。
分片集群
代码语言:javascript复制作用:在集群中会有多个Redis节点,每个节点存储部分数据,从而实现对大数据量的支持
优点:可以备份数据、提高并发支撑、扩容、自动恢复、扩容和收缩
流程
代码语言:javascript复制1.安装Redis:在不同的服务器上安装Redis,并设置不同的端口号和密码,以避免冲突和安全性问题。
2.分片策略:根据实际情况选择合适的分片策略,常见的有hash、range和mod等。
3.配置分片节点:将多个Redis节点配置为分片集群的节点,每个节点都有自己的IP地址和端口号。
4.启动Redis实例:分别启动多个Redis实例,并设置不同的端口号和密码,每个实例都只存储部分数据。
5.配置分片代理:使用分片代理软件(如Twemproxy、Codis、Redis Cluster等),将多个Redis实例组合成一个分片集群,提供统一的服务入口。
6.客户端访问:通过分片代理向分片集群发送请求,分片代理会根据分片策略将请求分发到不同的Redis实例。
7.数据迁移:在分片集群运行过程中,可能需要调整分片策略或增加/删除节点,此时需要进行数据迁移,确保数据的一致性。
需要注意的是,Redis分片集群需要对数据进行划分和分布,以避免数据倾斜和不一致的问题。同时,分片集群也需要配置密码保护机制和监控机制,以确保系统的安全性和可靠性
存在问题
缓存预热
代码语言:javascript复制1)redis初始化没有数据,初始化要进行大批量的数据同步,响应速度比较慢
2)大批量请求透过redis,直接访问数据,导致数据库服务器宕机
缓存雪崩
概念:短时间内大批key过期,导致大量请求都去请求了数据库
代码语言:javascript复制1)页面静态化(freemarker、Thymeleaf)
2)多级缓存(CDN、nginx、redis、ehcache)
3)错峰
大品类设置不同过期时间
同一品类,固定时间 随机时间
4)限流、降级
缓存击穿
概念:redis中单个高热key过期,导致大量请求都去请求了数据库
解决方案:
代码语言:javascript复制1)对预料到的高热的key提前设置,设置有效时间稍长一点或者永久
2)监控,发现高热key,提前处理
3)多级缓存
缓存穿透
概念:redis出现恶意的大面积访问未命中,并且数据在数据库中也不存在
解决方案:
代码语言:javascript复制1)缓存null值(解决单个key恶意访问;如果多个key恶意访问,会导致redis中存储大量无用的数据)
2)白名单(白名单地址请求都正常处理,非白名单地址请求都不处理直接返回友好错误提示)
3)黑名单(黑名单地址请求都不处理直接返回友好错误提示)
4)key加密(校验key,符合条件才会处理请求,不符合不处理直接返回友好错误提示)
5)页面添加唯一标识
监控指标
代码语言:javascript复制性能指标
内存指标
持久化指标
基础活动指标
错误指标
命中率
策略
删除策略
作用:
代码语言:javascript复制1.释放内存:当Redis中的数据量过大时,可能会导致内存占用过高,这时就需要采取一些删除策略来清理不必要的数据,释放内存空间。
2.保证性能:当Redis内存占用过高时,可能会导致系统性能下降,影响Redis的读写速度。因此,我们需要采取一些删除策略来确保Redis的性能稳定,避免系统因为内存占用过高而崩溃
分类:
代码语言:javascript复制1.DEL key:删除指定的key。
2.UNLINK key:与DEL类似,但是UNLINK命令是异步执行的,可以减少短暂的CPU阻塞。
3.FLUSHDB:删除当前数据库中所有的key。
4.FLUSHALL:删除所有数据库中的所有key。
淘汰策略
作用:
代码语言:javascript复制在内存不足的情况下,删除一些过期或不常用的数据,以释放一定的内存空间
分类:
代码语言:javascript复制1、noeviction:不进行淘汰数据。一旦缓存被写满,再有写请求进来,Redis就不再提供服务,而是直接返回错误。Redis 用作缓存时,实际的数据集通常都是大于缓存容量的,总会有新的数据要写入缓存,这个策略本身不淘汰数据,也就不会腾出新的缓存空间,我们不把它用在 Redis 缓存中。
2、volatile-ttl:在设置了过期时间的键值对中,移除即将过期的键值对。
3、volatile-random:在设置了过期时间的键值对中,随机移除某个键值对。
4、volatile-lru:在设置了过期时间的键值对中,移除最近最少使用的键值对。
5、volatile-lfu:在设置了过期时间的键值对中,移除最近最不频繁使用的键值对
6、allkeys-random:在所有键值对中,随机移除某个key。
7、allkeys-lru:在所有的键值对中,移除最近最少使用的键值对。
8、allkeys-lfu:在所有的键值对中,移除最近最不频繁使用的键值对
常见面试题
谈一下redis理解?
主要问的是概念、作用
key命名规范?
(业务名称)_唯一标识)唯一性和可读性
项目中使用的redis单机还是集群?
测试和开发环境使用单机版
生产环境使用集群
单机版存在哪些问题?
数据丢失、并发能力、无法自动故障恢复、存储能力有有上限
如何解决Redis单机版数据丢失问题?
使用redis持久化策略、搭建redis集群
Redis持久化策略有哪些,分别怎么工作的?
RDB、AOF
RDB、AOF区别?
见上边持久化策略区别中
你有没有搭建过redis集群?
主从、哨兵、分片
把哪些数据存在redis?
热点数据
Redis毕竟是内存性数据库,redis内容满了怎么办?
1.key设置有限期
2.通过删除策略(定性 惰性)、淘汰策略清理redis里的key
3.通过集群进行扩容
实际开发中还有哪些问题?
缓存预热、缓存雪崩、缓存击穿、缓存穿透