一、基础
1、什么是Redis
- C语言编写,基于key-value存储的nosql开源内存数据库
- 数据内存存储、数据结构优化,高性能
- 内置多种数据结构、支持持久化等
- 一般用于应用和数据库之间的分布式缓存中间件
- 提供主从复制+哨兵、集群的方式实现高可用,在redis集群中通过hash槽的方式实现数据分片,进一步提升性能和可扩展性
2、Redis的优缺点
- 优点
- 读写性能优异
- 支持数据持久化RDB、AOF
- 支持事务
- 数据结构丰富
- 支持主从复制,主机自动将数据同步至slave,可进行读写分离
- 高性能(直接操作内存快)、高并发:
- 缺点
- 数据库容量受到物理内存限制
- 在线扩容困难
- 内存成本太高且 Redis 提供的数据持久化仍然有数据丢失的风险
3、redis与其它缓存
- redis是分布式缓存
4、redis为什么快
- 完全基于内存,内存的访问速度比磁盘快很多
- 内置多种优化过的数据结构
- 采用单线程,避免不必要的上下文切换和竞争,也避免锁问题
- 采用多路IO复用模型,非阻塞IO
- Redis 通信协议实现简单且解析高效

5、缓存读写策略
- 旁路缓存
- 写:先更新DB,再删除缓存
- 读:从 cache 中读取数据,读取到就直接返回;cache 中读取不到的话,就从 db 中读取数据返回,再把数据放到 cache 中。
- 先删缓存后更新数据库:数据不一致
- 请求 1 先把 cache 中的 A 数据删除 -> 请求 2 从 db 中读取数据->请求 1 再把 db 中的 A 数据更新
- 更新 db,后删除 cache,可能存在数据不一致
- 概率非常小,因为缓存的写入速度是比数据库的写入速度快很多。
- 缺陷:
- 首次请求数据一定不在 cache 的问题(热点数据提前放缓存);
- 写操作比较频繁的话导致 cache 中的数据会被频繁被删除,这样会影响缓存命中率
- 1、数据库和缓存数据强一致场景:更新 db 的时候同样更新 cache,不过我们需要加一个锁/分布式锁来保证更新 cache 的时候不存在线程安全问题。
- 2、可以短暂地允许数据库和缓存数据不一致的场景:更新 db 的时候同样更新 cache,但是给缓存加一个比较短的过期时间,这样的话就可以保证即使数据不一致的话影响也比较小。
二、Redis应用
1、redis的应用场景
- 分布式锁
- 限流
- 消息队列
- 缓存
- 计数器
2、Redis分布式锁
三、数据类型
1、redis有哪些数据类型
- String、List、Set、Zset、Hash、Geospatial、Hyperloglog、Bitmap
四、持久化机制
1、RDB持久化
- 什么是RDB:一定时间内将内存数据以快照的形式保存到磁盘。也可以将快照复制到其他服务器从而创建具有相同数据的服务器副本(Redis 主从结构,主要用来提高 Redis 性能),还可以将快照保留以便重启服务器的时候使用。快照持久化是 Redis 默认采用的持久化方式。
- 创建快照会阻塞主线程吗:Redis 提供了两个命令来生成 RDB 快照文件:
save: 同步保存操作,会阻塞 Redis 主线程;bgsave: fork 出一个子进程,子进程执行,不会阻塞 Redis 主线程,默认选项。
2、AOF持久化
- 什么是AOF:与快照持久化相比,AOF 持久化的实时性更好。默认情况下 Redis 没有开启 AOF(append only file)方式的持久化(Redis 6.0 之后已经默认是开启了),可以通过
appendonly参数开启。开启 AOF 持久化后每执行一条会更改 Redis 中的数据的命令,Redis 就会将该命令写入到 AOF 缓冲区server.aof_buf中,然后再写入到 AOF 文件中(此时还在系统内核缓存区未同步到磁盘),最后再根据持久化方式(fsync策略)的配置来决定何时将系统内核缓存区的数据同步到硬盘中的。只有同步到磁盘中才算持久化保存了,否则依然存在数据丢失的风险,比如说:系统内核缓存区的数据还未同步,磁盘机器就宕机了,那这部分数据就算丢失了。 - 流程:

- 命令追加(append):所有的写命令会追加到 AOF 缓冲区中。
- 文件写入(write):将 AOF 缓冲区的数据写入到 AOF 文件中。这一步需要调用
write函数(系统调用),write将数据写入到了系统内核缓冲区之后直接返回了(延迟写)。并没有同步到磁盘。 - 文件同步(fsync):AOF 缓冲区根据对应的持久化方式(
fsync策略)向硬盘做同步操作。这一步需要调用fsync函数(系统调用),fsync针对单个文件操作,对其进行强制硬盘同步,fsync将阻塞直到写入磁盘完成后返回,保证了数据持久化。 - 文件重写(rewrite):随着 AOF 文件越来越大,需要定期对 AOF 文件进行重写,达到压缩的目的。
- 重启加载(load):当 Redis 重启时,可以加载 AOF 文件进行数据恢复。
- AOF持久化方式(
fsync策略)appendfsync always:主线程调用write执行写操作后,后台线程(aof_fsync线程)立即会调用fsync函数同步 AOF 文件(刷盘),fsync完成后线程返回,这样会严重降低 Redis 的性能(write+fsync)。appendfsync everysec:主线程调用write执行写操作后立即返回,由后台线程(aof_fsync线程)每秒钟调用fsync函数(系统调用)同步一次 AOF 文件(write+fsync,fsync间隔为 1 秒)appendfsync no:主线程调用write执行写操作后立即返回,让操作系统决定何时进行同步,Linux 下一般为 30 秒一次(write但不fsync,fsync的时机由操作系统决定)。- 这 3 种持久化方式的主要区别在于
fsync同步 AOF 文件的时机(刷盘)
- AOF重写:AOF采用指令追加的方式,近乎实时的去实现数据指令的持久化,会把每个数据更改的操作指令,追加存储到aof 文件里面。所以很容易导致AOF 文件出现过大,造成IO 性能问题。当 AOF 变得太大时,Redis 能够在后台自动重写 AOF 产生一个新的 AOF 文件,这个新的 AOF 文件和原有的 AOF 文件所保存的数据库状态一样,但体积更小。
- 过程:把AOF 文件里面相同的指令进行压缩,只保留最新的数据指令
- 首先,根据当前Redis 内存里面的数据,重新构建一个新的AOF 文件然后
- 然后,读取当前Redis 里面的数据,写入到新的AOF 文件里面
- 最后,重写完成以后,用新的AOF 文件覆盖现有的AOF 文件
- 另外,因为AOF 在重写的过程中需要读取当前内存里面所有的键值数据,再生成对应的一条指令进行保存。而这个过程是比较耗时的,对业务会产生影响。所以Redis 把重写的过程放在一个后台子进程里面来完成,这样一来,子进程在做重写的时候,主进程依然可以继续处理客户端请求。
- 最后,为了避免子进程在重写过程中,主进程的数据发生变化,导致AOF 文件和Redis 内存中的数据不一致的问题,Redis 还做了一层优化。就是子进程在重写的过程中,主进程的数据变更需要追加到AOF 重写缓冲区里面。等到AOF 文件重写完成以后,再把AOF 重写缓冲区里面的内容追加到新的AOF 文件里面。
- 最后,服务器用新的 AOF 文件替换旧的 AOF 文件,以此来完成 AOF 文件重写操作。
- 过程:把AOF 文件里面相同的指令进行压缩,只保留最新的数据指令
- AOF校验机制:

本文详细介绍了Redis的基础知识,包括Redis是什么、优缺点、与其他缓存的区别及为何快速。此外,讨论了Redis的数据类型、持久化机制、过期策略、淘汰策略和事务。还涉及主从复制、哨兵和集群的概念,以及如何处理哈希冲突。文章最后提到了缓存一致性问题及其解决方案,如设置过期时间、先更新DB再删除缓存等。
最低0.47元/天 解锁文章
1337

被折叠的 条评论
为什么被折叠?



