异常处理
学会了使用redis,也知道了穿透 雪崩 击穿 这一些面试比较火热的问题,
雪崩
雪崩就是在一定时间内,大量的缓存失效,解决办法主要有三种
数据预热
就是先让需要的缓存先存起来,还有就是设置不同的过期时间
限流降级
限制流量,通过加锁或者队列限制数据库写缓存的数量 降级就是降低其他低流量 业务的级别 例如在双十一的时候 先关闭评论 退款这些服务,以保证重要的进行
redis高可用
多设置几台redis服务器,以保证redis的高可用,也即是异地多活
击穿
击穿就是非常热频的点一直被访问,例如出现重大新闻,大量的人取搜索,导致大并发集中对这个点进行访问,当这个key在失效的瞬间,持续的大并发就穿破缓存,直接访问数据库
不设置过期时间
加互斥锁
只保证一个进程可以进去,其余的必须进行等待,就是当一个线程在访问的时候,就给他加锁,只有等当前线程释放锁,其他进程才可以访问
利用synchronized
通过synchronized+双重检查机制:某个key只让一个线程查询,阻塞其它线程
穿透
由于恶意频繁访问,访问一些缓存中不存在的key,并且数据库不存在,从而每次查询都会访问数据库,导致数据库崩溃
布隆过滤器
校验请求查询的参数 不符合就会直接丢弃
缓存空对象
在缓存里面加一个空对象 ,当数据库没有数据时候,就在缓存中设置一个空对象
拓展
降级
降级 就是退而求其次就是资源不足和访问量增加的矛盾 在有限资源的情况下,为了抵抗住大量的请求,就对系统做出一些牺牲,放弃一些功能,以保证系统能平稳运行。或者说就是简化业务流程。
限流
限流 限流就是对并发访问进行限速,以保证系统不会由于数据访问量剧增而瘫痪 限流的方式有很多种 例如特权请求,对用户进行分级 还有就是延时处理,利用队列把请求缓存住
熔断
熔断 熔断就是为了防止应用程序不断尝试可能超时或者失败的服务,能够让应用程序执行而不必等待下游服务修正错误服务 熔断主要是针对下游来的,是为了防止服务不断调用下游服务,但是调用一直失败而一直重复
主从复制
主从复制,主服务器负责写,从服务器负责读,设置主从关系有两种手动方式,一种是直接敲命令,另外一种就是在配置文件设置,但是这种手动方式有很大的弊端,一是不够灵活,二是比较繁琐。所以哨兵模式就很关键了,哨兵模式就是当主服务器不可用时侯,哨兵可以时候监听主机是否有故障,并且进行投票处理,选出一个从机作为主机,当原来的主机重启的时候,只能做现在主机的从机,而不是像原来的还是作为主机。
订阅发布
订阅发布 订阅发布有点类似与公众号,当用户订阅了频道的时候,发布者一但发布了信息在频道,用户就可以接收到消息用户可以取消订阅 这种主要应用于聊天系统,例如两个人聊天时候,两个人就进入了容易个频道
监控
锁有两种 一种是悲观锁,一种是乐观锁,
redis用的就是乐观锁,时刻监控,更新数据时候判断是否有用户修改数据,有的话就加锁
悲观锁就是无论做什么都加锁
事务
在redis中还是有事务的,
redis事务的本质是一组命令的集合,,一个事务中所有命令都被序列化,在事务执行过程中,会按顺序执行
redis事务没有隔离级别的概念
redis单条命令保证原子性,但是事务不保证原子性
拓展
事务有四个特征 ACID 原子性 一致性 隔离性 持久性
原子性 整个事务所有操作,要么全部完成,事务执行过程中发生错误,会被回滚到事务开始前的状态
一致性 在事务开始之前和执行之后,数据库的完整性约束没有被破坏 所谓数据库的完整性约束就是数据的精准可靠性,没有不合规范的数据
隔离性 事务之间没有侵扰,哪怕两个事务做相同的功能,也必须保证在同一时间内只有一个请求访问数据,事务之间没有侵扰
持久性 在事务完成以后,该事务对数据库的更改便持久的保存在数据库中,并不会被回滚
事务的隔离级别
脏读 不可重复读 幻读
脏读 脏读是指在一个事务处理过程里读取了另一个未提交的事务中的数据 当a进行存钱时候,a已经放入100元,但是没有提交,此时b去账号查看发现多了一百块钱。
不可重复读 不可重复读就是一个用户多次访问同一数据有不同的结果,这是由于在查询间隔,被另外一个事务修改并且提交了。和脏读不同的是,脏读读取的是没有被提交的数据,而不可重复读读取的是提交的数据
幻读 幻读就是a对所有数据的1都修改为了2,但是b此时插入了一条数据,数据任然是1,a提交,当a再次查看数据的时候,发现还有一条数据是1,其实这行数据是事务b添加的,就好像产生了幻觉一样。 幻读和不可重复读都是读取了另一条已经提交的事务(这点就脏读不同),所不同的是不可重复读查询的都是同一个数据项,而幻读针对的是一批数据整体(比如数据的个数)。
MySQL四种隔离级别
① Serializable (串行化):可避免脏读、不可重复读、幻读的发生。
② Repeatable read (可重复读):可避免脏读、不可重复读的发生。
③ Read committed (读已提交):可避免脏读的发生。
④ Read uncommitted (读未提交):最低级别,任何情况都无法保证
数据库索引B+Tree
索引是为了提高数据的查询数据,相当于给数据进行编号,在查找数据的时候可以通过编号快速找到查询的数据,主键自带索引,乱序插入数据,会自动按照id排序,数据存储内部结构类似于链表
,通过指针关联不同的数据。
数据123…就是id索引,abc…就是数据内容,p就是指针;
page
page,给数据进行分页,将一部分数据存入一个page中,如下如图所示:
每个page存储16KB数据,相当于给数据建立了上层数据,先找大目录,再找具体数据。MySQL给page也提供了快速查询的page目录;
将每个page中的第一条数据的id+指针存入page目录,查询数据时侯,先找到他的page,例如id=4,此时大于3小于5,所以在3开头的page。
如果数据还是比较大,可以再增加一层page目录;
这是数据库经常使用的索引,B代表平衡而不是二叉树。
这样可以提高数据库检索的速度,通过分页处理,现在一般是三层结构,第一层主要存储数据,第二层存储分页信息,第三层存储分页信息的信息,一层最多是16KB,三层结构容量很大,基本完全可以满足现在的需求。