一、基础
1、Redis的概念
Redis是一个基于C语言开发的开源NoSQL数据库。Redis的数据是保存在内存中的(内存数据库,支持持久化),因此读写速度非常快,被广泛应用在分布式缓存方向。并且,Redis存储的是KV键值对数据。
为了满足不同的业务场景,Redis内置了多种数据类型实现(比如 String、Hash、Sorted Set、Bitmap、HyperLogLog、GEO)。并且,Redis还支持事务、持久化、Lua脚本、发布订阅模型、多种开箱即用的集群方案。
2、Redis为什么这么快
- 纯内存操作:Redis数据读写操作都发生在内存中,访问数据是纳秒级别的。
- 高效的I/O模型:Redis使用单线程事件循环配合I/O多路复用技术,让单个线程可以同时处理多个网络连接上的I/O操作,避免了多线程模型的上下文切换和锁竞争的问题。
- 优化的内部数据结构:Redis 提供多种数据类型(如 String, List, Hash, Set, Sorted Set 等),其内部实现采用高度优化的编码方式(如 ziplist, quicklist, skiplist, hashtable 等)。Redis 会根据数据大小和类型动态选择最合适的内部编码,以在性能和空间效率之间取得最佳平衡。
- 简洁高效的通信协议:Redis 使用的是自己设计的 RESP (REdis Serialization Protocol) 协议。这个协议实现简单、解析性能好,并且是二进制安全的。客户端和服务端之间通信的序列化/反序列化开销很小,有助于提升整体的交互速度。
3、除了Redis还有哪些分布式缓存方案
包括Memcached、Dragonfly、KeyDB等
redis是分布式缓存的首选,生态优秀,资料全面。
4、Redis和Memcached的区别和共同点
共同点:
- 都是基于内存的数据库,一般都用来当做缓存使用。
- 都有过期策略
- 性能都非常高
区别:
- 数据类型:Redis数据类型丰富。Memcached只支持最简单的KV数据类型。
- 数据持久化:Redis支持数据持久化,可以将内存中的数据保存到磁盘中,重启时重新加载进行使用。而Memcached不支持数据持久化。
- 集线程型:Redis是单线程循环配合多路IO复用模型。Memcached是多线程、非注射IO复用的网络模型。
- 集群模型支持:Redis(3.0版本起)原生支持集群模式。Memcached没有原生集群模式。
- 特性支持:Redis支持发布订阅模型、Lua脚本、事务等功能,并且支持更多的编程语言。Memcached不支持。
- 过期数据删除:Reids有惰性删除和定期删除。Memcached只有惰性删除。
5、为什么要用Redis
- 访问速度快
- 高并发
- 功能全面
6、为什么用Redis而不用本地缓存
特性 | 本地缓存 | Redis |
数据一致性 | 多服务器部署时存在数据不一致问题 | 数据一致 |
内存限制 | 受限于单台服务器内存 | 独立部署,内存空间更大 |
数据丢失风险 | 服务器宕机数据丢失 | 可持久化,数据不易丢失 |
管理维护 | 分散,管理不便 | 集中管理,提供丰富的管理工具 |
功能丰富性 | 功能有限,通常只提供简单的键值对存储 | 功能丰富,支持多种数据结构和功能 |
7、常见的缓存读写策略
(1)Cache Aside Pattern(旁路缓存模式)
Cache Aside Pattern中服务端需要同时维系db和cache,并且是以db的结果为准,适合读请求比较多的场景。
写的操作步骤:
- 先更新db(数据)到数据库
- 再直接删除cache(缓存)
读的操作步骤
- 重cache中读数据,如读取到则直接返回。
- 如果没读到就会从数据库中读取数据返回
- 然后将数据放到缓存中。
在写的操作过程中,如果先删除cache再更新db,在并发读的过程中可能会产生脏数据,造成数据库和缓存不一致的问题。
Cache Aside Pattern的缺陷:
- 首次读,数据一定不在cache的问题(解决方法:提前将热点数据放入cache)。
- 写比较频繁的话导致cache的数据别频繁删除,影响缓存命中率。
(2)Read/Write Through Pattern(读写穿透)
服务端把cache视为主要数据存储,重中读取数据并将数据写入其中。cache服务负责将此数据读取和写入db,从而减轻应用程序的职责。
写的操作流程:
- 先查cache,cache中不存在,直接更新db。
- cache中存在,则先更新cache,然后cache服务自己更新db(同步更新cache和db)。
读的操作流程:
- 重cache中读取数据,读取到就直接返回。
- 没有读取到,先从db加载,写入到cache后返回响应。
Read-Through Pattern 实际只是在 Cache-Aside Pattern 之上进行了封装。在 Cache-Aside Pattern 下,发生读请求的时候,如果 cache 中不存在对应的数据,是由客户端自己负责把数据写入 cache,而 Read Through Pattern 则是 cache 服务自己来写入缓存的,这对客户端是透明的。
和 Cache Aside Pattern 一样, Read-Through Pattern 也有首次请求数据一定不再 cache 的问题,对于热点数据可以提前放入缓存中。
(3)Write Behind Pattern(异步缓存写入)
和读写穿透相似,都是由cache服务来负责cache和db的读写。但是两个又有很大的不同:Read/Write Through 是同步更新 cache 和 db,而 Write Behind 则是只更新缓存,不直接更新 db,而是改为异步批量的方式来更新 db。适用于对数据一致性要求不高的场景。
二、Redis应用
1.Reids可以用作:
- 分布式锁:通常情况下是基于Redisson来实现分布式锁
- 限流:通过Redis+Lua脚本
- 消息队列:自带的List数据结构可以当做一个简单的消息队列使用。Reids5。0以后新增Stream数据结构来做消息队列,有主题和消费组的概念,支持消息持久化以及ACK机制。
- 延迟对鞋:Reids内置了延时队列
- 分布式Session:利用String和Hash数据结构来保存Session数据
- 等等