多级缓存(亿级流量(并发)的缓存方案)
传统缓存的问题
传统缓存是请求到达tomcat后,先查询redis,如果未命中则查询数据库,问题如下:
(1)请求要经过tomcat处理,tomcat成为整个系统的瓶颈。
(2)redis缓存失效时,会对数据库产生冲击。(缓存雪崩等各个问题)
tomcat本身的缓存(并发)能力是不如redis的。
多级缓存
(1)多级缓存就是充分利用请求处理的每个环节,分别添加缓存,减轻tomcat压力,提升服务性能。
静态资源请求存入到浏览器客户端缓存,非静态数据进入到nginx服务器(此时的nginx为nginx的本地缓存,可编程将查询数据去访问redis中,不去请求tomcat),可将数据存入到业务nginx中。redis缓存未命中时,到达tomcat中可读取进程缓存来获得数据。tomcat进程缓存未命中,就到达
数据库。
(2)redis缓存失效时,(发生缓存雪崩等)可以使用tomcat进程(也称jvm进程缓存)缓存做缓冲,从而避免了全部访问数据库。
(3)业务nginx内部需要编写对redis的访问和对tomcat进程缓存的访问。
(4)业务nginx通常作为集群的形式
jvm进程缓存
使用lua语言编写业务nginx的逻辑
缓存同步策略
缓存数据同步的常见方式
(1)设置有效期:给缓存设置有效期,到期后自动删除。再次查询时更新。
缺点:时效性差,缓存过期前可能不一致
优点:简单、方便 ,适用于更新频率低,时效性要求低的业务
(2)同步双写:在修改数据库的同时,直接修改缓存
优势:时效性强,强一致性
缺点:业务代码中有侵入代码(更新缓存操作),耦合度高;适用于对一致性和时效性较高的缓存数据。
(3)异步通知:修改数据库时发送事件通知,相关服务监听到通知后修改缓存数据
优点:低耦合,可以同时通知多个缓存服务
缺点:时效性一般(其实也就够了,mq收到消息之间只是ms级别);适用于有多个服务需要同步。
<1> 基于mq的异步通知(仍需要在代码中进行操作mq)
<2> 基于Canal的异步通知(通过监听数据库的变化)
canal监听原理
canal把自己伪装成mysql的一个slave节点,从而监听master的binary log变化,再把得到的变化信息通知给Canal的客户端,从而完成对其他数据库的同步。
项目(在默认tomcat容器中)编写监听Canal客户端
引入依赖
编写配置:
canal:
destination:test # canal实例名称,要跟canal-server运行时设置的destination一致。
server:安装ip:端口号 # canal地址
编写监听器
实现EntryiHandler接口,重写方法(监听到数据库的新增、修改、删除会执行对应的方法)
编写指定的实体类Item(表和实体类之间的映射关系)
@Id : 声明表的逐渐
@Transient: 表示不是当前表的字段
@Column:当数据库和实体类字段名称不一致时编写