基于Nginx+Lua优化多级缓存架构

本文涉及的产品
云数据库 Redis 版,社区版 2GB
推荐场景:
搭建游戏排行榜
云数据库 RDS MySQL Serverless,0.5-2RCU 50GB
简介: 基于Nginx+Lua优化多级缓存架构

1 多级缓存架构介绍

任何项目中我们都有一些频繁的查询,而那些频繁的查询数据基本都是相同的,比如项目中查看用户个人信息,购物狂欢查询活动信息,这些功能点使用频率非常高,我们一般需要对他们做特殊处理。

我们以狂欢活动信息为例,当双十一的时候,很多人会去查看今天优惠活动有哪些,对这些活动信息我们可以采用多

级缓存架构来抗住高并发。


2 Java常用缓存设计

617200f8dcc14647bad8a9365949e38c.png

基于Java版的缓存架构实现流程如下:


1、用户请求经过Nginx

2、Nginx检查是否有缓存,如果Nginx有缓存,直接响应用户数据

3、Nginx如果没有缓存,则将请求路由给后端Java服务

4、Java服务查询Redis缓存,如果有数据,则将数据直接响应给Nginx,并将数据存入缓存,Nginx将数据响应给用户

5、如果Redis没有缓存,则使用Java程序查询MySQL,并将数据存入到Reids,再将数据存入到Nginx中


优点:


1、采用了Nginx缓存,减少了数据加载的路径,从而提升站点数据加载效率

2、多级缓存有效防止了缓存击穿、缓存穿透问题


缺点:


Tomcat并发量偏低,导致缓存同步并发量失衡,缓存首次加载效率偏低,Tomcat 大规模集群占用资源高


3 Lua版多级缓存架构改进

30fce99353d84809b6079f91fd9dbded.png

优点:

1、采用了Nginx缓存,减少了数据加载的路径,从而提升站点数据加载效率

2、多级缓存有效防止了缓存击穿、缓存穿透问题

3、使用了Nginx+Lua集成,无论是哪次缓存加载,效率都高

4、Nginx并发量高,Nginx+Lua集成,大幅提升了并发能力


4 Nginx+Lua多级缓存实战

Lua预备知识


我们以双十一活动信息加载为例,通过多级缓存架构来加载双十一活动信息,双十一活动信息表结构如下:

CREATE TABLE `activitt_info` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(100) DEFAULT NULL COMMENT '活动名称',
`desc` varchar(3000) DEFAULT NULL COMMENT '活动介绍',
`starttime` datetime DEFAULT NULL,
`endtime` datetime DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8;

4.1 链接MySQL封装

创建一个lua脚本 mysql.lua ,用于提供根据SQL语句执行查询操作,代码如下:

--引入依赖库mysql
local mysql = require "resty.mysql"
--配置数据库链接信息
local props = {
host = "192.168.211.141",
port = 3306,
database = "redpackage",
user = "root",
password = "123456"
}
--创建一个对象
local mysqlobj = {}
--根据SQL语句查询
function mysqlobj.query(sql)
--创建链接、设置超时时间、编码格式
local db = mysql:new()
db:set_timeout(10000)
db:connect(props)
db:query("SET NAMES utf8")
--执行SQL语句
local result = db:query(sql)
--关闭链接
db:close()
--返回结果集
return result
end
return mysqlobj

4.2 链接Redis集群封装

我们需要安装 lua-resty-redis-cluster ,用该依赖库实现Redis集群的操作,这里提供github地址,大家下载后按操

作配置即可,下载地址: <https://github.com/cuiweixie/lua-resty-redis-cluster>,下载该文件配置后即可

实现Redis集群操作。

接下来我们实现Redis集群操作,创建一个脚本 redis.lua ,脚本中实现Redis中数据的查询和添加操作,代码如

下:


         

4.3 多级缓存操作

配置创建Nginx缓存共享空间

lua_shared_dict act_cache 128m;

创建多级缓存操作脚本 activity.lua ,代码如下:

--多级缓存流程操作
--1)Lua脚本查询Nginx缓存
--2)Nginx如果没有缓存
--2.1)Lua脚本查询Redis
--2.1.1)Redis如果有数据,则将数据存入到Nginx缓存,并响应用户
--2.1.2)Redis没有数据,Lua脚本查询MySQL
-- MySQL有数据,则将数据存入到Redis、Nginx缓存[需要额外定义],响应用户
--3)Nginx如果有缓存,则直接将缓存响应给用户
--响应数据为JSON类型
ngx.header.content_type="application/json;charset=utf8"
--引入依赖库
--cjson:对象转JSON或者JSON转对象
local cjson = require("cjson")
local mysql = require("mysql")
local lrredis = require("redis")
--获取请求参数ID http://192.168.211.141/act?id=1
local id = ngx.req.get_uri_args()["id"];
--加载本地缓存
local cache_ngx = ngx.shared.act_cache;
--组装本地缓存的key,并获取nginx本地缓存
local ngx_key = 'ngx_act_cache_'..id
local actCache = cache_ngx:get(ngx_key)
--如果nginx中没有缓存,则查询Redis集群缓存
if actCache == "" or actCache == nil then
--从Redis集群中加载数据
local redis_key = 'redis_act_'..id
local result = lrredis.get(redis_key)
--Redis中数据为空,查询数据库
if result[1]==nil or result[1]==ngx.null then
--组装SQL语句
local sql = "select * from activity_info where id ="..id
--执行查询
result = mysql.query(sql)
--数据不为空,则添加到Redis中
if result[1]==nil or result[1]==ngx.null then
ngx.say("no data")
else
--数据添加到Nginx缓存和Redis缓存
lrredis.set(redis_key,cjson.encode(result))
cache_ngx:set(ngx_key, cjson.encode(result), 2*60);
ngx.say(cjson.encode(result))
end
else
--将数据添加到Nginx缓存中
cache_ngx:set(ngx_key, result, 2*60);
--直接输出
ngx.say(result)
end
else
--输出缓存数据
ngx.say(actCache)
end

4.4 Nginx配置

#活动查询

location /act {
content_by_lua_file /usr/local/openresty/nginx/lua/activity.lua;
}
相关实践学习
基于Redis实现在线游戏积分排行榜
本场景将介绍如何基于Redis数据库实现在线游戏中的游戏玩家积分排行榜功能。
云数据库 Redis 版使用教程
云数据库Redis版是兼容Redis协议标准的、提供持久化的内存数据库服务,基于高可靠双机热备架构及可无缝扩展的集群架构,满足高读写性能场景及容量需弹性变配的业务需求。 产品详情:https://www.aliyun.com/product/kvstore &nbsp; &nbsp; ------------------------------------------------------------------------- 阿里云数据库体验:数据库上云实战 开发者云会免费提供一台带自建MySQL的源数据库&nbsp;ECS 实例和一台目标数据库&nbsp;RDS实例。跟着指引,您可以一步步实现将ECS自建数据库迁移到目标数据库RDS。 点击下方链接,领取免费ECS&amp;RDS资源,30分钟完成数据库上云实战!https://developer.aliyun.com/adc/scenario/51eefbd1894e42f6bb9acacadd3f9121?spm=a2c6h.13788135.J_3257954370.9.4ba85f24utseFl
目录
相关文章
|
2月前
|
缓存 负载均衡 算法
后端架构设计中的优化技巧
【2月更文挑战第9天】 后端架构设计是一个复杂而关键的工作,不仅需要考虑系统的可靠性和扩展性,还需要保证系统的高性能。本文将介绍一些后端架构设计中的优化技巧,包括数据库设计、缓存优化、负载均衡等方面的内容,帮助开发者在设计后端架构时更好地提升系统性能。
39 1
|
2月前
|
供应链 Java
云HIS技术架构:Angular+Nginx+Java+Spring,SpringBoot
标准数据维护 用户信息:维护用户的基本信息,所在科室以及各个系统所具体的权限。 科室信息:维护医院的科室信息。 数据字典:标准字典信息的维护。 药品/诊疗目录维护:维护药品和诊疗目录的基本信息。
33 2
|
2天前
|
缓存 NoSQL Java
Springboot 多级缓存设计与实现
Springboot 多级缓存设计与实现
|
2天前
|
JSON API 数据库
后端架构设计与优化:打造高性能应用后端
后端架构设计与优化:打造高性能应用后端
10 2
|
15天前
|
存储 数据库 Android开发
构建高效安卓应用:采用Jetpack架构组件优化用户体验
【4月更文挑战第12天】 在当今快速发展的数字时代,Android 应用程序的流畅性与响应速度对用户满意度至关重要。为提高应用性能并降低维护成本,开发者需寻求先进的技术解决方案。本文将探讨如何利用 Android Jetpack 中的架构组件 — 如 LiveData、ViewModel 和 Room — 来构建高质量的安卓应用。通过具体实施案例分析,我们将展示这些组件如何协同工作以实现数据持久化、界面与逻辑分离,以及确保数据的即时更新,从而优化用户体验并提升应用的可维护性和可测试性。
|
29天前
|
缓存 应用服务中间件 数据库
【分布式技术专题】「缓存解决方案」一文带领你好好认识一下企业级别的缓存技术解决方案的运作原理和开发实战(多级缓存设计分析)
【分布式技术专题】「缓存解决方案」一文带领你好好认识一下企业级别的缓存技术解决方案的运作原理和开发实战(多级缓存设计分析)
33 1
|
1月前
|
运维 Linux Apache
LAMP架构调优(十)——Apache禁止指定目录PHP解析与错误页面优化
LAMP架构调优(十)——Apache禁止指定目录PHP解析与错误页面优化
199 2
|
1月前
|
存储 缓存 运维
LAMP架构调优(五)——网页缓存设置
LAMP架构调优(五)——网页缓存设置
10 1
|
1月前
|
存储 NoSQL Redis
陌陌技术分享:陌陌IM在后端KV缓存架构上的技术实践
在本文中,陌陌数据库负责人冀浩东将聚焦探讨陌陌的 KV 系统架构选型思路,深入解析如何进行此类系统的甄选决策,同时进一步分享陌陌团队在采用 OceanBase(OBKV)过程中所经历的探索与实践经验。
33 0
|
1月前
|
存储 缓存 算法
说说什么是本地缓存、分布式缓存以及多级缓存,它们各自的优缺点?
说说什么是本地缓存、分布式缓存以及多级缓存,它们各自的优缺点?