分布式缓存
单点redis的问题
- 数据丢失问题:Redis是内存存储,服务重启可能会丢失数据。解决:数据持久化
- 并发能力问题:单节点并发能力不足。解决:主从集群,读写分离。
- 故障恢复:需要自动的故障恢复手段。解决:Redis哨兵,实现健康检测和自动恢复。
- 存储能力问题:单节点Redis难以满足海量数据存储。解决:搭建分片集群,利用插槽机制动态扩容。
Redis持久化
RDB持久化
RDB全称Redis Database Backup file(Redis数据备份文件),也被叫做Redis数据快照。 简单来说就是把内存中的所有数据都记录到磁盘中。当Redis实例故障重启后,从磁盘读取快照文件,恢复数据。
快照文件称为RDB文件,默认是保存在当前运行目录。
RDB执行时机:
- Redis停机时会执行一次RDB。 (save命令由Redis主进程来执行RDB,会阻塞所有命令;bgsave命令则开启子进程执行RDB,是异步的,避免主进程受到影响)
- Redis内部有触发RDB的机制,可以在redis.conf文件中找到。
异步持久化bgsave原理
RDB方式bgsave的基本流程? 1. fork主进程得到一个子进程,共享内存空间 2. 子进程读取内存数据并写入新的RDB文件 3. 用新RDB文件替换旧的RDB文件。
fork采用的是copy-on-write技术:
当主进程执行读操作时,访问共享内存;
当主进程执行写操作时,则会拷贝一份数据,执行写操作。
RDB会在什么时候执行?save 60 1000代表什么含义? 默认是服务停止时执行。也可以配置config文件触发执行。 save 60 1000代表60秒内至少执行1000次修改则触发RDB
RDB的缺点?
RDB执行间隔时间长,两次RDB之间写入数据有丢失的风险
fork子进程、压缩、写出RDB文件都比较耗时
AOF持久化
AOF全称为Append Only File(追加文件)。Redis处理的每一个写命令都会记录在AOF文件,可以看做是命令日志文件。
RDB和AOF比较
Redis主从(解决并发问题)
搭建主从架构
单节点Redis的并发能力是有上限的,要进一步提高Redis的并发能力,就需要搭建主从集群,实现读写分离。
因为根据经验,对Redis的操作大部分都是读,写操作占少数,所以在集群中采用读写分离,同时以少量主节点和大量从节点搭配,大大提升Redis的读取性能。主节点需要注意的就是数据同步如何同步给从节点。
在同一台服务器上搭建集群的步骤: 1、安装Redis,默认安装在/www/server/redis目录下。 2、在同一台服务器上开启3个redis实例,模拟主从集群,端口为7001、7002、7003。 3、准备实例和配置。要在同一台虚拟机开启3个实例,必须准备三份不同的配置文件和目录,配置文件所在目录也就是工作目录。在/tmp/目录下分别创建了7001、7002、7003三个子目录。# 创建目录 mkdir 7001 7002 7003 4、检查原始/www/server/redis/redis.conf文件中,持久化模式保持为默认的RDB模式,AOF保持关闭状态。 5、然后将/www/server/redis/redis.conf文件拷贝到/tmp/7001、/tmp/7002、/tmp/7003三个目录中 6、修改每个文件夹内的配置文件,将端口分别修改为7001、7002、7003,将rdb文件保存位置都修改为自己所在目录 7、虚拟机本身有多个IP,为了避免将来混乱,需要在redis.conf文件中指定每一个实例的绑定ip信息(这里直接将ip全部设置为云服务器ip) 8、由于我的数据库设置了数据库,在后续开启主从关系会出现主节点使用info replication查到的connected_slaves是0的情况。因此需要在从节点的配置文件中添加一行masterauth 自己的密码
主从数据同步原理
全量同步
主从第一次同步是全量同步
增量同步
Redis哨兵
slave节点宕机恢复后可以找master节点同步数据,那master节点宕机怎么办?
哨兵
RedisTemplate的哨兵模式
引入依赖
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> </dependency>
在配置文件application.yml中指定sentinel相关信息
spring: redis: password: 1234 #如果Redis有密码市一定要配置密码 sentinel: master: mymaster #指定master名称 nodes: # 指定Redis集群信息 - ip地址:27001 - ip地址:27002 - ip地址:27003
配置主从读写分离(在启动类中)
@SpringBootApplication public class RedisDemoApplication { public static void main(String[] args) { SpringApplication.run(RedisDemoApplication.class, args); } @Bean public LettuceClientConfigurationBuilderCustomizer clientConfigurationBuilderCustomizer(){ return clientConfigurationBuilder -> clientConfigurationBuilder.readFrom(ReadFrom.REPLICA_PREFERRED); } }
Redis分片集群(增强存储能力)