概述
1.Redis是什么,它的优缺点是?
Redis是一个单线程的内存级别的缓存非关系型数据库。
Redis的读取与存储速度是mysql的数量级倍。
优点是:
- 读写性能高
- 支持事务,Redis中所有操作都是原子性的。
- 数据结构丰富
- 支持主从复制,可以进行读写分离。
缺点是:
- 容易受到物理内存的限制,故不能用作海量数据库的高性能读写。
- 主机宕机,宕机前有部分数据未能及时同步到从机,切换IP后还会引入数据不一致的问题,降低了系统的可用性。
2.Redis为什么这么快?
原因:
- 内存存储:Redis是使用内存存储的,没有磁盘IO上的开销。
- 单线程实现(Redis6.0之前):Redis使用单线程来处理请求,避免了多个线程之间线程来回切换和锁资源争用的开销。
- Redis的底层是NIO(非阻塞性IO):使用多路复用IO 技术,不在网络I/O上浪费过多的时间。
- 使用底层模型不同:Redis直接自己构建了VN(虚拟内存)机制,不会浪费时间去移动与请求。
3.为什么要用Redis来做缓存?
从高并发上来说:
- 直接操作缓存能够承受的请求时远远大于直接访问数据库的,所以我们可以考虑把数据库中的部分数据转移到缓存中去,这样用户的一部分请求会直接到缓存这里而不用经过数据库。
从高性能上来说:
- 用户第一次访问数据库中的某些数据。因为是从硬盘上读取的所以过程会比较慢。将该用户访问的数据存在缓存中,下一次访问这些数据时就可以直接在缓存中获取了。操作缓存就是直接操作内存,所以速度相当快。
4.Redis的常用场景有哪些?
- 缓存:缓存现在几乎是所有中大型网站都在用的必杀技,合理的利用缓存不仅能够提升网站访问速度,还能大 大降低数据库的压力。Redis提供了键过期功能,也提供了灵活的键淘汰策略,所以,现在Redis用在缓存的场合非常多。
- 排行榜:很多网站都有排行榜应用的,如京东的月度销量榜单、商品按时间的上新排行榜等。Redis提供的有序集合数据类构能实现各种复杂的排行榜应用。
- 计数器:什么是计数器,如电商网站商品的浏览量、视频网站视频的播放数等。为了保证数据实时效,每次浏览 都得给+1,并发量高时如果每次都请求数据库操作无疑是种挑战和压力。Redis提供的incr命令来实现计 数器功能,内存操作,性能非常好,非常适用于这些计数场景
- 分布式会话:集群模式下,在应用不多的情况下一般使用容器自带的session复制功能就能满足,当应用增多相对复杂 的系统中,一般都会搭建以Redis等内存数据库为中心的session服务,session不再由容器管理,而是由 session服务及内存数据库管理。
- 分布式锁:在很多互联网公司中都使用了分布式技术,分布式技术带来的技术挑战是对同一个资源的并发访问,如 全局ID、减库存、秒杀等场景,并发量不大的场景可以使用数据库的悲观锁、乐观锁来实现,但在并发 量高的场合中,利用数据库锁来控制资源的并发访问是不太理想的,大大影响了数据库的性能。可以利 用Redis的setnx功能来编写分布式的锁,如果设置返回1说明获取锁成功,否则获取锁失败,实际应用 中要考虑的细节要更多。
- 社交网络:点赞、踩、关注/被关注、共同好友等是社交网站的基本功能,社交网站的访问量通常来说比较大,而且 传统的关系数据库类型不适合存储这种类型的数据,Redis提供的哈希、集合等数据结构能很方便的的实 现这些功能。如在微博中的共同好友,通过Redis的set能够很方便得出。
5.Redis的数据类型有哪些?
- String:String时最常用的一种数据结构,普通的<k,v>都可以归为此类。redis.cli操作:
- Hash:Hash是一个键值对集合。Redishash 是一个 string 类型的 field 和 value 的 映射表,hash 特别适合用于存储对象,并且可以像数据库中update一个属性一样只修改某一项属性 值。
- Set:Set是一个无序的天然去重的集合,即Key-Set。此外还提供了交集、并集等一系列直接操作集 合的方法,对于求共同好友、共同关注什么的功能实现特别方便。
- List:是一个有序可重复集合。 其遵循FIFO的原则,底层是依赖双向链表实现的,因此支持正 向、反向双重查找。通过List,我们可以很方面的获得类似于最新回复这类的功能实现。
- Zset:类似于java中的TreeSet,是Set的可排序版。此外还支持优先级排序,维护了一个score 的参数来实现。适用于排行榜和带权重的消息队列等场景。
持久化
1.Redis持久化机制?
为了能够重用Redis数据,或者防止系统故障,我们需要将Redis中的数据写入到磁盘文件中,即持久化。
Redis提供了两种不同的持久化方法可以将数据存储在磁盘中,一种叫做快照RDB,另一种叫做只追加文件AOF。
- RDB:在指定的时间间隔内将内存中的数据快照写入磁盘(Snapshot),它恢复是将快照文件直接读到内存里。适用于“通表备份”。
- 优势:适合大规模的数据恢复;对数据完整性和一致性要求不高。
- 劣势:在一定间隔时间做一次备份,所以如果Redis意外down掉的话,就会丢失最后依次快照后的所有修改。
- AOF:即“文件之后追加”。以日志形式来记录每个写操作,只许追加文件但不可以改写内容。
- 优势:数据完整性好。
- 劣势:运行速度慢。
2.Redis持久化数据和缓存怎么做扩容?
- 如果Redis被当做缓存使用,使用一致性哈希实现动态扩容缩容。
- 如果Redis被当做一个持久化存储使用,必须使用固定的keys-to-nodes映射关系,节点的数量一旦 确定不能变化。否则的话(即Redis节点需要动态变化的情况),必须使用可以在运行时进行数据再 平衡的一套系统,而当前只有Redis集群可以做到这样。
过期键的删除策略、淘汰策略
1.Redis的过期删除策略
- 定时删除:设置key的时候创建一个定时器,让定时器在该过期时间到时删除它。
- 惰性删除:不会去主动删除数据,在访问数据的时候,检查是否过期。
- 定期删除:Redis会定期检查已过期的key,并对其进行删除操作。
2.Redis key的过期时间与永久有效分别怎么设置?
通过expire或pexpire命令,客户端可以以秒或毫秒的精度为数据库中的某个键设置生存时间。 与expire和pexpire命令类似,客户端可以通过expireat和pexpireat命令,以秒或毫秒精度给数据库中 的某个键设置过期时间,可以理解为:让某个键在某个时间点过期。
3. Redis内存淘汰策略
-
volatile-lru: 利用LRU算法移除设置过过期时间的key (LRU:最近使用 Least Recently Used )
-
allkeys-lru: 删除最近最少使用的
-
volatile-ttl:删除将要过期的
-
volatile-random:删除任意的
-
allkeys-random:删除任意的
-
no-eviction:不删除,但是操作会报异常
缓存异常
1.缓存雪崩:在同一时刻出现大规模的key失效
- 解决方案:
- 事中:互斥锁(会阻塞其他的线程,系统吞吐量会下降)
- 事后:开启Redis持久化机制,尽快恢复缓存数据
2.缓存击穿:针对某个热点的key在一瞬间大规模失效
- 解决方案:
- 缓存失效之后:通过互斥锁或者队列来控制线程数量
- 热点数据缓存永远不过期
3.缓存穿透:关键在于在Redis中查不到key值
- 解决方案:
- 将无效的key存放至Redis中
- 布隆过滤器:“位图”,类似于HashMap
4.缓存与数据库数据不一致
- 解决方案:共有四种:
- 先更新数据库,后更新缓存(会将脏数据刷到缓存)
- 先更新缓存,后更新数据库(可能会造成数据不一致)
-
先删除缓存,后更新数据库:
延时双删(先淘汰缓存,再写数据库,休眠1秒再次淘汰缓存)
更新与读取操作进行异步串行化
-
先更新数据库,后删除缓存
柔性事务(C A P)
“三个不能同时满足,两两可以”
- C:一致性
- A:可用性
- P:分区容错性
- CA:单节点(可忽略)
- AP:没同步前数据不一致
- CP:数据进行同步时不可用
互联网保证的是最终一致性!(比如幂等性就是通过最终一致性来保证的)
由CAP得到2PC 3PC TCC:
-
2PC:先请求,再返回
-
3PC:比2PC多了一开始的安全检查
-
TCC:阿里巴巴的微服务seata实现了TCC