Redis是什么?简述它的优缺点?
Redis是一个(关键字-数值)的内存数据库,数据库是在内存当中操作,并定期将数据库中的数据更新到硬盘上进行保存。
因为是纯内存操作,Redis的性能非常出色,每秒可以处理超过 10万次读写操作,是已知性能最快的(关键字-数值)数据库。
优点:
1.读写性能极高
2.数据持久化,支持AOF和RDB两种持久化方式
3.支持事务, Redis的所有操作都是原子性的,要么成功执行要么失败完全不执行
4.redis的数据结构丰富
5.支持主从复制,主机会自动将数据同步到从机,可以进行读写分离
缺点:
受物理内存的限制,不能用作海量数据的高性能读写,因此Redis适合的场景主要局限在较小数据量的高性能操作和运算上。
主机宕机
redis的高可用
Redis 支持主从同步,提供集群部署模式,通过哨兵来监控 Redis 主服务器的状态。当主挂掉时,在从节点中根据一定策略选出新主,并调整其他从 slaveof 到新主。
1.从redis的priority越低,优先级越高
2.从redis复制的数据越多,优先级越高
Redis为什么这么快
1.内存存储
2.单线程实现
3.非阻塞IO
4.优化了存储的数据结构
为什么要用 Redis 做缓存
高并发上:
缓存能够承受的请求是远远大于直接访问数据库
高性能上:
直接访问数据库速度慢,而访问缓存的速度和访问内存差不多
Redis的使用场景
缓存,排行榜,社交网络,消息系统,最新列表
Redis数据类型:
类型 | 简介 | 特性 | 场景 |
---|---|---|---|
String (字符串) | 二进制安全 | 可以包含任何数据,比如jpg图片或者序列化的对象,一个键最大能存储512M | 关键字-数值 |
Hash (字典) | 键值对集合 | 适合存储对象,并且可以更新修改某一项属性值 | 存储、读取、修改用户属性 |
List (列表) | 链表(双向链表) | 增删快,提供了操作某一段元素的API | 1、最新消息排行等功能(比如朋友圈的时间线) 2、消息队列 |
Set (集合) | 哈希表实现,元素不重复 | 1、添加、删除、查找的复杂度都是O(1) 2、为集合提供了求交集、并集、差集等操作 | 1、共同好友 2、利用唯一性,统计访问网站的所有独立ip 3、好友推荐时,根据tag求交集,大于某个阈值就可以推荐 |
Sorted Set (有序集合) | 将Set中的元素增加一个权重参数score,元素按score有序排列 | 数据插入集合时,已经进行天然排序 | 1、排行榜 2、带权重的消息队列 |
缓存击穿
缓存击穿是某个热点的key失效后,对其进行大量并发请求,造成大量请求读缓存没读到数据。导致高并发访问数据库,引起数据库压力剧增。
1.加互斥锁,控制访问数量(key只允许一个线程查询数据和写缓存,其他线程等待)
2.针对热点key不设置过期时间
缓存穿透
用户请求的数据在缓存中不存在,同时在数据库中也不存在,导致用户每次请求该数据都要去数据库中查询一遍。
如果有恶意攻击者不断请求系统中不存在的数据,会导致短时间大量请求落在数据库上,造成数据库压力过大,甚至导致数据库承受不住而宕机崩溃。
1.把请求的key保存到Redis中,设置为null,后面再出现查询这个key的请求的时候,直接返回null(存在key变化问题)
2.使用布隆过滤器。将数据库中的所有key都存储在布隆过滤器中,在查询Redis前先去布隆过滤器查询 key 是否存在,如果不存在就直接返回,不让其访问数据库,避免对存储系统的查询压力
缓存雪崩
缓存在某一个时刻出现大规模的key失效,导致大量的请求打在了数据库上面,导致数据库压力增大,可能瞬间就会导致数据库宕机。这时候如果运维马上又重启数据库,马上又会有新的流量把数据库打死。这就是缓存雪崩。
造成缓存雪崩的关键在于同一时间的大规模的key失效:1.Redis宕机,2.可能就是采用了相同的过期时间。
1可以使用 主从+ 哨兵,Redis集群来避免 Redis 宕机
2.加互斥锁,控制访问数量
3.开启Redis持久化机制
缓存预热
系统上线后,提前将相关的缓存数据加载到缓存系统。避免在用户请求的时候,先查询数据库,然后再将数据缓存的问题,用户直接查询事先被预热的缓存数据。
如果不进行预热,那么Redis初始状态数据为空,系统上线初期,对于高并发的流量,都会访问到数据库中, 对数据库造成流量的压力。
缓存预热解决方案:
数据量不大的时候,工程启动的时候进行加载缓存动作
数据量大的时候,设置一个定时任务脚本,进行缓存的刷新
数据量太大的时候,优先保证热点数据进行提前加载到缓存
缓存降级
缓存服务器挂掉后,不去访问数据库,直接返回默认数据或访问服务的内存数据。降级一般是有损的操作,所以尽量减少降级对于业务的影响程度
缓存穿透和缓存击穿的区别
缓存穿透的关键在于在Redis中查不到key值,它和缓存击穿的根本区别在于传进来的key在Redis中是不存在的
Redis持久化机制
将数据写入到磁盘空间中,使用:1.快照RDB,2.只追加文件AOF(类似Linux的">")
RDB | AOF | |
优势 | 适合大规模的数据恢复;对数据完整性和一致性要求不高 | 每次发生数据变更会被立即记录到磁盘,性能较差但数据完整性比较好 |
劣势 | 所以如果Redis意外down掉的话,就会丢失最后一次快照后的所有操作 | 追加的运行效率要慢于快照 追加文件要远大于快照文件,恢复速度慢于快照 |
如何保证缓存与数据库双写时的数据一致性
1.先更新数据库,后更新缓存
2.先更新缓存,后更新数据库
3.先删除缓存,后更新数据库
4.先更新数据库,后删除缓存
第一种问题:并发更新数据库场景下,会将脏数据刷到缓存
第二种问题:如果先更新缓存成功,但是数据库更新失败,则肯定会造成数据不一致
先删除缓存,后更新数据库
请求A进行写操作,删除缓存
请求B查询发现缓存不存在
请求B去数据库查询得到旧值
请求B将旧值写入缓存
请求A将新值写入数据库
① 延时双删
②更新与读取操作进行异步串行化
先更新数据库,后删除缓存
1.请求1先对数据库进行更新操作
2.再对Redis进行删除操作的时候发现报错,删除失败
3.此时将Redis的key作为消息体发送到消息队列中
4.系统接收到消息队列发送的消息后再次对Redis进行删除操作
Redis事务的概念
事务是ACID的,原子性,一致性,隔离性,持久性,但是redis的事务并不是原子的
redis事务可以理解为一个脚本包(ansible的playbook一样),中间某条指令的失败不会导致前面已做指令的回滚,也不会造成后续的指令不做(类似于ansible的ignore)
Redis事务的三个阶段
①开启事务
②大量指令入队
③执行事务块内命令(截止此处一个事务已经结束)
结束: ①取消事务
②监视一个或多个key,如果事务执行前key被改动,事务将打断
Redis常见使用方式有哪些
1.Redis单副本
单个Redis节点部署架构,没有备用节点实时同步数据
2.主从
主节点挂掉后,需要手动指定新的主节点,可用性不高,基本不用。
3.哨兵模式
主节点挂掉后,哨兵进程会主动选举新的主节点,可用性高,
但是每个节点存储的数据是一样的,浪费内存空间。
Redis高可用实施
使用哨兵模式就能实现,当主节点出现故障时,由哨兵自动完成故障发现和转移,并通知应用方,实现高可用性。它有四个主要功能:
集群监控:负责监控redis的主和从节点是否正常工作。
消息通知:如果某个Redis出现故障,那么哨兵负责发送消息给管理员
故障转移:如果主节点挂掉了,会自动转移到从节点上。
配置中心:如果故障转移发生了,通知client客户端新的主节点地址
Redis如何做内存优化
1.控制key的数量
2.缩减键值对象,降低Redis内存使用最直接的方式就是缩减关键字和值的长度
3.编码优化
Redis常见的性能问题和解决方案
1.主节点最好不要做持久化工作(快照RDB;只追加文件AOF)
2.如果数据比较重要,某个从节点开启只追加备份数据,策略设置为每秒同步一次
3.主从节点最好在同一个局域网内
4.尽量避免在压力很大的主库上增加从库