方案一:springboot + 本地缓存 + redis分布式缓存
- 设计简单,可以支持普通并发现的大部分需求,但如果并发太高,该方案依然无法支撑。
- 瓶颈卡在tomcat的并发量低
方案二:nginx + lua + redis分布式缓存(结合双删策略)
- 通过lua直连redis
- nginx判断是否从nginx中直接获取缓存,如果需要获取,则通过lua直接去redis读取,并返回,整个过程不需要经历应用程序这层,所以性能很高,单节点qps大约10W+
- 由于双删策略,会导致如果数据库数据更新,会清空redis缓存,此时nginx直接查会查不到数据,依然会走应用程序查询,但如果此时并发量很高,依然会有大量请求冲击到应用程序,导致性能变慢,这是双删策略不可避免的
- 双删策略就是更新数据库时,先删除缓存,再更更新数据库,更新完再次删除缓存,目的就是避免数据不一致
方案三:nginx + lua + redis + canal体系
- canal可以监听mysql的binlog,如果DB数据又变动,canal会监听到,并发起更新redis的请求
- 由于canal的存在,redis不需要使用双删,因为DB只要数据变动,canal就会发送消息到kafka,应用程序只需要监听kafka,如果有消息,就进行更新redis即可,基本上缓存与DB数据是一致的,可能只有个几毫秒的延迟
- 此时如果需要从nginx中直接走redis获取数据,那基本上一定会查到数据(是基本,不是绝对), 因为不需要走双删流程,canal的存在会让缓存实时更新,并且更细速度很快
- 为什么说是基本会查到,而不是一定会查到呢?
答:因为如果redis用的是list,hash等结构,要想更新数据,必须要先删除,再更新才行(如果直接更新,则list,hash会直接向原数据插入,而并非覆盖,如果是string类型,那无所谓,直接覆盖,不会出现redis空档期), 所以从删除到再插入这两段代码中,依然有极短是时间是没数据的 - 双删也是有删除操作,canal也有删除操作,为什么canal的体系更完美?
答:双删操作的第二次删除后是不会向缓存写数据的,所以下一次请求必定会走到应用程序去DB查询,并且如果此时并发量很高,会有大量的请求进入应用程序,期间还要去DB查询,这个过程时间要远远大于canal更新,因为canal更新是删除旧数据后,紧接着就写入到了redis,没有中间查DB这个场景。
文章来源地址https://www.toymoban.com/news/detail-522567.html
文章来源:https://www.toymoban.com/news/detail-522567.html
到了这里,关于【HBZ分享】高并发下Redis+Nginx+Lua+Canal架构体系设计的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!