目录
3、分布式缓存常见的技术选型?Redis和Memcached区别?
Redis
1、什么是Redis?为什么使用Redis?
Redis是一个基于C语言的NoSQL型数据库,其数据保存在内存中,相对于MySQL数据保存在磁盘上来说,其访问速度快,这也是为什么使用Redis缓存热点数据。其数据以Key_value键值对形式存储。
2、Redis为啥快?
- 数据存于内存,读快。
- Redis中单线程循环和IO多路复用提高其数据处理能力。
- Redis内置许多优化后的数据结构。
3、分布式缓存常见的技术选型?Redis和Memcached区别?
分布式技术选型:Redis和Memcached.。
相同:
- 数据都存于内存。
- 都有过期策略。
- 两者性能都非常高。
不同:
- Redis支持更加丰富的数据类型,而memcache只支持k-v类型。
- Redis支持数据持久化,可以将内存中的数据保存在磁盘中,而M把所有的数据存于内存中。
- Redis有灾难恢复机制。
- Redis使用单线程多路IO模型,M使用多线程非阻塞IO模型。
- Redis过期删除策略有惰性删除和定期删除,而M只有惰性删除。
- Redis 在服务器内存使用完之后,可以将不用的数据放到磁盘上。但是,Memcached 在服务器内存使用完之后,就会直接报异常。
- Memcached 没有原生的集群模式,需要依靠客户端来实现往集群中分片写入数据;但是 Redis 目前是原生支持 cluster 模式的。
4、为啥用Redis做缓存
1高性能:存于缓存的数据读取快速。
2.高并发:MySQL的每秒查询速度在1W左右,而使用了Redis之后很容易达到10W+。
5、Redis除了做缓存,还能做什么?
分布式锁、限流、消息队列、延时队列、分布式Session、复杂业务场景。
6、如何基于Redis实现分布式锁?
weit;
7、REdis可以做消息队列吗?
可以,但不建议。和专业消息队列比,Redis做消息队列要通过List来实现,且会出现消息丢失和堆积问题。
8、Redis常用的数据类型。
- String字符串类型:是Redis中最常用最简单的一种数据及类型,是一种二进制安全的数据类型。可以用来存储任何类型的数据。应用场景有:常规数据的缓存、分布式锁、计数等。其底层实现依赖“简单动态数组”实现。
- List列表:其底层实现为双项链表。应用场景为:消息队列。
- Hash哈希:是一个String类型的键值对映射表,适合存储对象。应用场景:对象数据存储
- Set集合:无序且唯一。应用场景:存放数据不重复;需要获取多个数据集的交、并集时;
- Sorted Set有序集合:对比Set增加了一个权重参数Score,根据Score获取元素。经常用于排行榜。
9、 Redis有序集合底部为啥用跳表?
有点多。。
10、Redis持久化机制。
持久化就是Redis内存中的数据存入磁盘中,这样Redis重启后可以再次从磁盘中将数据读入内存。
3中持久化方式:RDB快照;AOF只追加文件;RDB和AOF混合机制;
RDB持久化:
- Redis通过创建快照的方式将存于内存中的数据复制到快照中,快照可以存于另外一台服务器中,可以存于本地机器,由于恢复Redis内存。
- Redis使用两种命令来生成RDB文件:save、bgsave;区别在于save使用主线程来生成RDB文件,如果写RDB文件时间过长对导致主线程阻塞;使用gbsave会创建一个子线程来写RDB问价,不会发生阻塞。
- RDB是一种全量快照,每次执行会把内存中的所有数据都写入RDB中,如果操作频繁会影响Redis的性能,如果操作频率过低,服务器故障时丢失的数据回更多。
- 在生成RDB时,Redis仍然可以更新数据,这是因为使用gbsave生成RDB时,会通过子线程进行,子线程共享父线程的内存数据,当父线程执行读操作时,不受影响,当父线程执行写操作时,被修改的数据会复制一份副本写入RDB文件中。
AOF持久化:
- Redis在执行完一条操作命令后就会把该命令写入一个文件中(AOF),Redis重启后会执行w文件中的命令,恢复内存数据。
- AOF有3中写回策略:
- Always:每次写操作命令执行后,同步将AOF日志写回硬盘。
- Everysec:每次写操作执行后,将命令写入AOF内核缓冲区,每隔一秒将缓冲区内容写入硬盘。
- No,意味着不由Redis控制写回硬盘,转交给操作系统控制。
- AOF文件过大会触发AOF重写机制 :读取当前数据库的所有键值对,将每一条键值对用一条命令记录到新的AOF文件中,然后用新的AOF文件替换旧的AOF文件。重写过程由后台子进程完成
混合持久化:
- 为什么会有混合持久化:因为RDB形式数据恢复快,但是频率不好把握;AOF丢失的数据少,但是恢复慢;
- 持久化方式:混合持久化工作在AOF重写过程,fork出来的子进程会先将与主进程共享的数据以RDB的方式写入AOF文件,然后主线程处理的操作命令会写入重写缓冲区中,重写缓冲区里的增量会以AOF的形式写入AOF中,这样AOF文件中前一半时RDB形式的数据,恢复快,同时也解决了数据丢失问题。
- 缺点:AOF文件中添加了RDB形式的数据,使得AOF文件的可读性变差。其次,兼容性差。
Redis单线程模型:
Redis单线程是指客户端一条请求的执行过程都由一个主线程完成。但是Redis程序不是单线程的,他还会开启一些后端线程。
单线程怎么监听大量用户端连接呢?使用IO多路复用程序来监听多个socket,然后通过文件时间分派器将socket关联到对应事件处理器,调用不同的事件处理函数处理事件。
优点:
使用IO多路复用程序,不用创建多个线程,节省资源的同时消除了线程切换浪费的时间。
不会发生阻塞;
Redis6.0之前为什么使用单线程?
在Redis官方解答中说:CPU不是制约Redis性能的瓶颈,内存大小和网络IO才是。另外,使用单线程可维护性高,不会发生线程切换,不会导致死锁。
Redis6.0之后为什么引入多线程?
这是因为随着网络硬件能力的提升,Redis的瓶颈可能会出现在网络IO处理上。为了提升IO速度,6.0后对于网络IO使用多线程处理,但是一条命令的执行还是由一条线程处理。
Redis后台线程了解吗?
Redis如何判断数据是否过期?
通过过期字典,里面存放的都是KEY过期时间。
过期数据删除策略
惰性删除:
只会在取出KEY的时候才对数据进行过期检查,对CPU好,但可能造成大量过期KEY未被删除。
定期删除:
每隔一段时间取出一批Key执行删除过期操作,并且Redis底层会通过限制删除操作执行的时长和频率来减小对CPU的影响。
Redis内存淘汰机制
volatile-lru:从已设置过期时间的数据集中挑选最近最少使用数据淘汰。
volatile-ttl:从已设置过期时间的数据集中挑选将要过期的数据淘汰。
volatile-random:从已设置过期时间的数据集中随机挑选数据淘汰。
allKeys-lru:当内存不足以容乃新数据时,从所有数据中挑选最近最少使用数据淘汰。
allKeys-random :从所有数据中任意挑选数据淘汰。
no-eviction:禁止数据驱逐。
volatile/allKeys-lfu:移除最不经常用的数据。
什么是Redis事务
Redis事务提供了一种将多个Redis命令请求打包的功能,然后再按顺序执行包中命令,并且不会被中途打断。
事务四大特性:原子性、隔离性、持久性、一致性
Redis大Key:
一个Key对应的value值太大,则被称为大key。String类型数据超过1M,其他类型超过5000个。
缓存穿透
大量请求的Key是不合理的,不存在与缓存中也不存在于数据库中。对数据库造成巨大压力,可能导致宕机。
解决方法
- 缓存无效Key:如果Redis和数据库中都查不到某个Key,就写一个到Redis中并设置过期时间
- 布隆过滤器:把所有可能存在的请求的值存放在布隆过滤器中,当用户请求过来,先看请求的值是否在布隆过滤器中,不存在的话直接返回请求参数错误信息。
- 接口限流。
缓存击穿
请求的热点数据不存在与Redis中,但存于数据库中。可能会导致大量请求直接打到数据库中,导致宕机。
解决:
- 设置热点数据永不过期或者过期时间过长。
- 针对热点数据提前预热。
- 请求数据库写数据到Redis之前,获取互斥锁,保证只有一个请求会落到数据库上,减少数据库压力。
缓存雪崩
缓存在同一时间大面积失效,导致大量请求直接落到数据库上,导致宕机。
解决:
限流
多级缓存。例如本地缓存+Redis缓存组合,当Redis缓存数据大量失效时,还有本地缓存。
采用Redis集群,避免单机出现问题整个缓存服务都没办法使用。
缓存雪崩和缓存击穿区别
缓存击穿是某个热点数据不在Redis中,但在数据库中。缓存雪崩是缓存中大量数据同时失效。
如何保证缓存和数据库数据一致性?
使用旁路缓存模式:1缓存失效变短;2增加cache更新重试机制。
哪些情况可能会导致Redis阻塞?
O(n)命令、save创建RDB快照、AOF日志阻塞。。。