【多级缓存】多级缓存OpenResty,Canal,nginx本地缓存

多级缓存

安装OpenResty

OpenResty是一个基于 Nginx的高性能 Web 平台,用于方便地搭建能够处理超高并发、扩展性极高的动态 Web 应用Web 服务和动态网关。具备下列特点:

  1. 具备Nginx的完整功能
  2. 基于Lua语言进行扩展,集成了大量精良的Lua库,第三方模块
  3. 允许使用Lua自定义业务逻辑,自定义库

官方地址:https://openresty.org/cn/

  • 在linux下安装
  1. 安装OpenResty的依赖开发库
    yum install -y pcre-devel openssl-devel gcc --skip-broken
  2. 在centos中添加openresty仓库
    yum-config-manager --add-repo https://openresty.org/package/centos/openresty.repo
  3. 安装openResty
    yum install -y yum-utils
  4. 安装opm工具,是一个openresty的管理工具,可以帮助我们安装一个第三方的lua模块
    yum instally openrest -y -opm

默认情况下 openResty的安装目录是/usr/local/openresty

配置nginx环境变量

  1. 打开配置文件vim /etc/profile

  2. 在最下面添加
    export NGINX_HOME=/usr/local/openresty/nginx
    export PATH=${NGINX_HOME}/sbin:$PATH

  3. 让配置生效
    source /etc/profile

  4. 启动nginx

java 复制代码
# 启动nginx
nginx
# 重新加载配置
nginx -s reload
# 停止
nginx -s stop

OpenResty入门

这里由代理一个访问路径为例子:

在windows端的nginx中进行

  1. 在nginx.conf的http下面,添加对OpenResty的Lua模块的加载:

  2. 在nginx.conf的server下面,添加对/api/item这个路径的监听:

  3. Linux中niginx目录下创建lua文件夹,新建item.lua文件

    创建内容:

  4. 重新加载配置
    nginx -s reload

OpenResty获取请求参数

OpenResty提供了各种API用来获取不同类型的参数:

OpenResty向tomcat服务器发送请求

nginx提供了内部API请求用以发送http请求:

返回的响应内容包括:

resp.status:响应状态码

resp.header:响应头,是一个table

resp.body:响应体,就是响应数据

注意:这里的path是路径,并不包含IP和端口,这个请求会被nginx内部的server监听并处理,可以使用反向代理

我们可以把http查询的请求封装到一个函数中,放到OpenResty函数库中,方便以后使用

  1. 创建文件/usr/local/openresty/lualib/common.lua
  2. 在文件中封装请求http查询的函数

    如何使用这个封装函数,返回向tomcat请求的数据,在item.lua文件中

注意:Openresty提供了一个cjson的模块用来处理JSON的序列化和反序列化

地址:https://github.com/openresty/lua-cjson/

如何使用:

  1. 引入json模块
    local cjson=require "cjson"
  2. 序列化:

    反序列化:

在nginx与tomcat端之间添加redis缓存

  • 冷启动和缓存预热

冷启动:服务刚刚启动时,Redis中并没有缓存,如果所有商品数据都在第一次查询时添加缓存,可能会给数据库带来较大压力。

缓存预热:在实际开发中,我们可以利用大数据统计用户访问的热点数据,在项目启动时将这些热点数据提前查询并保存到Redis中。

OpenResty提供了操作Redis的模块,只需要引入就能够使用

封装函数,用来释放Redis连接,放入连接池

封装函数,从Redis中读取数据并返回

Redis本地缓存

OpenResty为nginx提供了shard dict的功能,可以在nginx的多个worker之间共享数据,实现缓存功能

  1. 开启共享词典,在nginx.conf的http下添加配置:
  1. 操作共享词典

缓存同步

缓存同步策略

设置有效期:给缓存设置有效期,到期后自动删除。再次查询时更新

优势:简单、方便

缺点:时效性差,缓存过期之前可能不一致

场景:更新频率较低,时效性要求低的业务
同步双写:在修改数据库的同时,直接修改缓存

优势:时效性强,缓存与数据库强一致

缺点:有代码侵入,耦合度高;

场景:对一致性、时效性要求较高的缓存数据
异步通知:修改数据库时发送事件通知,相关服务监听到通知后修改缓存数据

优势:低耦合,可以同时通知多个缓存服务

缺点:时效性一般,可能存在中间不一致状态

场景:时效性要求一般,有多个服务需要同步

基于Canal的异步通知

安装Canal

Canal是阿里巴巴旗下的开源项目,基于java开发,基于数据库增量日志解析,提供增量数据订阅&消费

地址:https://github.com/alibaba/canal

Canal是基于MySQL的主从同步来实现的,MySQL主从同步的原理如下:

MySOL master将数据变更写入二进制日志( binarylog)其中记录的数据叫binary log events

MySQLslave 将master的 binary log events拷贝到它的中继日志(relay log)

MySQL slave 重放 relay log 中事件,将数据变更反映它自己的数据

Canal就是把自己伪装成MVSOL的一个slave节点,从而监听master的binarylog变化。再把得到的变化信息通知给Canal的客户端,进而完成对其它数据库的同步。

安装:

  1. 首先创建一个网络,将MySQL,Canal,MQ放在同一个Docker网络中:
    docker network create hhh

    让mysql加入这个网络
    docker network connect hhh mysql

  2. 将Canal镜像上传到虚拟机中,通过命令导入;
    docker load -i canal.tar

  3. 运行创建Canal容器

    docker run p 11111:11111 --name canal

    -e canal.destinations=hhh

    -e canal.instance.master.address=mysql:3306

    -e canal.instance.dbUsername=canal

    -e canal.instance.dbPassword=canal

    -e canal.instance.connectionCharset=UTF-8

    -e canal.instance.tsdb.enable=true

    -e canal.instance.gtidon=false

    -e canal.instance.filter.regex=hhh\...*

    --network hhh

    -d canal/canal-server:v1.1.5

Canal客户端

Canal提供了各种语言的客户端,当Canal监听到binlog变化时,会通知Canal的客户端。

第三方开源的canal-starter:地址:https://github.com/NormanGyllenhaal/canal-client

  1. 引入依赖
  1. 编写配置
yml 复制代码
canal:
    destination: hhh #要跟canal运行时设置的destination一致
    server: 192.168.75.135:11111 #canal地址
  1. 编写监听器,监听canal消息
java 复制代码
//Item是指定表的实体类
@CanalTable("表名")
@Component
public class ItemHandler implements EntryHandler<Item>{
   @Override
   public void insert(Item item){
   //新增数据到redis中
   //新增数据到JVM缓存
   }
   @Override
   public void update(Item before,Item after){
   //更新redis数据
   //更新本地缓存
   //更新数据到JVM缓存
   }
   @Override
   public void delete(Item item){
   //删除redis数据
   //清除本地缓存
   //从JVM中删除缓存
   }
}
相关推荐
ajsbxi2 小时前
苍穹外卖学习记录
java·笔记·后端·学习·nginx·spring·servlet
想要打 Acm 的小周同学呀6 小时前
LRU缓存算法
java·算法·缓存
hlsd#6 小时前
go 集成go-redis 缓存操作
redis·缓存·golang
镰刀出海6 小时前
Recyclerview缓存原理
java·开发语言·缓存·recyclerview·android面试
奶糖趣多多8 小时前
Redis知识点
数据库·redis·缓存
CoderIsArt9 小时前
Redis的三种模式:主从模式,哨兵与集群模式
数据库·redis·缓存
ketil2713 小时前
Redis - String 字符串
数据库·redis·缓存
生命几十年3万天15 小时前
redis时间优化
数据库·redis·缓存
java知路18 小时前
springboot 基于google 缓存,实现防重复提交
spring boot·后端·缓存
_.Switch19 小时前
Serverless架构与自动化运维
运维·python·缓存·自动化·运维开发