Redis简介
Redis是Remote Dictionary Server的简称,是一个开源的内存数据存储系统,常用于缓存、消息队列、分布式锁等场景。
Redis数据类型
Redis支持多种类型的数据结构,包括字符串(String)、哈希(Hash)、列表(List)、集合(Set)、有序集合(Sorted Set)等。
如下图所示:
- 字符串(String):
- 存储单个值。
- 可以包含任意二进制数据,如文本、序列化对象等。
- 支持各种操作,如设置值、获取值、增加/减少数值等。
- 常用于缓存、计数器、存储序列化对象等场景。
- 哈希(Hash):
- 存储键值对的散列表。
- 每个键值对称为一个字段(field)和值(value)的组合。
- 支持单个字段的读写操作,也支持一次操作多个字段。
- 常用于存储对象的属性、配置信息等场景。
- 列表(List):
- 有序、可重复的字符串列表。
- 可以在列表的头部或尾部添加、删除元素。
- 支持按索引获取元素,支持范围操作,如获取子列表等。
- 常用于消息队列、任务队列、最新消息列表等场景。
- 集合(Set):
- 无序、不可重复的字符串集合。
- 支持添加、删除元素,以及对多个集合进行交集、并集、差集等操作。
- 支持判断元素是否存在于集合中,以及计算集合的大小等操作。
- 常用于标签系统、好友列表、唯一值的存储等场景。
- 有序集合(Sorted Set):
- 类似于集合,但每个元素都关联一个分数(score)。
- 元素按照分数进行排序,支持根据分数范围获取元素,以及按照分数排序返回元素等操作。
- 支持添加、删除元素,以及对多个有序集合进行交集、并集、差集等操作。
- 常用于排行榜、按权重排序的数据存储等场景。
Redis持久化
Redis提供了持久化机制,主要就是:RDB(Redis Database)和AOF(Append-Only File),可以将Redis的数据持久化到磁盘,以防止数据丢失并在重启后恢复数据。
1.RDB(Redis Data Base) 内存快照
RDB 快照是一次全量备份,RDB快照是内存数据的二进制序列化形式,在存储上非常紧凑。
如下图所示:
下面是Redis RDB持久化的主要步骤:
- Fork子进程:Redis使用fork系统调用创建一个子进程,子进程将负责执行实际的RDB持久化操作,而父进程则继续处理客户端请求。
- 快照生成:子进程会将当前数据库的状态快照写入一个临时文件中。快照包含了当前数据库中所有键值对的数据,以及一些额外的元数据信息。
- 原子性替换:当子进程完成快照的生成后,它会使用原子操作替换掉之前的RDB文件,确保在替换过程中不会发生数据损坏或数据丢失。
- 完成持久化:子进程完成RDB文件的替换后,将关闭临时文件,并通知父进程持久化操作已经完成。
2.AOF(Append Only File) 增量日志
AOF 则是将每次执行的写命令保存到硬盘,类似于 MySQL 的 Binlog,AOF 持久化的实时性更好,即当进程意外退出时丢失的数据更少。
如下图所示:
- 文件较大:相对于RDB持久化而言,AOF文件通常会更大,因为AOF文件记录了每个写命令的详细信息。
- 恢复时间较长:当AOF文件较大时,在Redis重启后,需要将AOF文件中的命令逐个执行以还原数据库的状态,这会导致恢复的时间相对较长,尤其是在AOF文件很大的情况下。
3.RDB AOF混合持久化
Redis4.0 后大部分的使用场景都不会单独使用 RDB 或者 AOF 来做持久化机制,而是兼顾二者的优势混合使用。
Redis集群方式
Redis提供了三种集群方式:
1.Redis主从复制模式
Redis主从复制是指通过将一个Redis服务器的数据复制到多个从Redis服务器上,实现多个Redis服务器之间的数据同步。
Redis主从复制前者称为主节点(master),后者称为从节点(slave)。
如下图所示:
2.Redis哨兵模式
Redis哨兵模式是Redis官方提供的高可用解决方案,主要负责监控Redis实例的状态、自动进行故障切换等。
如下图所示:
3.Redis集群模式
Redis 集群模式是Redis官方提供的分布式集群方案,支持水平扩展,适合大规模应用场景。
在Redis的每一个节点上,都有这么两个东西,一个是插槽(slot),它的的取值范围是:0-16383,还有一个就是cluster。
如下图所示:
Redis集群模式应用
主要是针对海量数据+高并发+高可用的海量数据场景,Redis集群模式的性能和高可用性均优于哨兵模式。
Redis常见问题
1.缓存雪崩
数据未加载到缓存中,或者缓存同一时间大面积的失效,从而导致所有请求都去查数据库,导致数据库CPU和内存负载过高,甚至宕机。
比如一个雪崩的简单过程:
1、redis集群大面积故障
2、缓存失效,但依然大量请求访问缓存服务redis
3、redis大量失效后,大量请求转向到mysql数据库
4、mysql的调用量暴增,很快就扛不住了,甚至直接宕机
5、由于大量的应用服务依赖mysql和redis的服务,这个时候很快会演变成各服务器集群的雪崩,最后网站彻底崩溃。

2.缓存穿透
缓存穿透是指查询一个一不存在的数据。例如:从缓存redis没有命中,需要从mysql数据库查询,查不到数据则不写入缓存,这将导致这个不存在的数据每次请求都要到数据库去查询,造成缓存穿透。
解决思路:
如果查询数据库也为空,直接设置一个默认值存放到缓存,这样第二次到缓冲中获取就有值了,而不会继续访问数据库。设置一个过期时间或者当有值的时候将缓存中的值替换掉即可。
可以给key设置一些格式规则,然后查询之前先过滤掉不符合规则的Key。
3.缓存并发
这里的并发指的是多个redis的client同时set key引起的并发问题。其实redis自身就是单线程操作,多个client并发操作,按照先到先执行的原则,先到的先执行,其余的阻塞。当然,另外的解决方案是把redis.set操作放在队列中使其串行化,必须的一个一个执行。
4.缓存预热
缓存预热就是系统上线后,将相关的缓存数据直接加载到缓存系统。
这样就可以避免在用户请求的时候,先查询数据库,然后再将数据缓存的问题!用户直接查询事先被预热的缓存数据!
解决思路:
1、直接写个缓存刷新页面,上线时手工操作下;
2、数据量不大,可以在项目启动的时候自动进行加载;
目的就是在系统上线前,将数据加载到缓存中。
以上就是Redis原理详解,更多Redis内容请查看:Redis教程(万字图文全面详解)
mikechen
mikechen睿哥,10年+大厂架构经验,资深技术专家,就职于阿里巴巴、淘宝、百度等一线互联网大厂。
关注「mikechen」公众号,获知最新一线技术干货!
