前情描述:
由于我们在实际开发过程中,有些数据需要被频繁读取,而且这些数据基本不会被改变,只会被频繁查询,但是问题在于,我们的数据库访问承受能力是有限的,在访问量非常高时,数据库负荷非常大,为了解决这个问题,我们就可以用到OpenResty+redis+mysql。
思路解析:
OpenResty已经内置了nginx,所以我们实际上是通过访问nginx来实现获取数据,nginx还可以起到其他的作用,这个以后在记录。回归正题,我们设想设计一个三级缓存来减轻数据库的负荷,第一级缓存就是我们nginx的缓存,第二级缓存就是redis的数据,第三级缓存就是数据库的数据。当我们发送请求获取数据时,首先从nginx中获取缓存数据,如果没有,则从redis获取,redis也没有,则从数据库获取,这里要注意一点,我们获取到数据后,要把数据存到上一级缓存,这样可以避免每次都要从下一级缓存获取数据。
举个例子:
如果我们的数据是从数据库获取的,那我们再把数据给到前端时,切记同时把数据存到redis和nginx缓存,不然我们的三级缓存就是去意义了。
具体实现:
我们使用lua脚本来实现对mysql数据库和redis的操作(lua的基本语法大家可以自己再网上找找,应该有很多)
1.修改/usr/local/openresty/nginx/conf/nginx.conf,将配置文件使用的根设置为root,目的就是将来要使用lua脚本的时候 ,直接可以加载在root下的lua脚本
命令:
cd /usr/local/openresty/nginx/conf
vi nginx.conf
2.定义lua缓存命名空间,修改nginx.conf,添加如下代码即可
添加lua_shared_dict dis_cache 128m
3.创建一个文件到 /root/lua/read.lua,编写lua代码
ngx.header.content_type="application/json;charset=utf8"local uri_args = ngx.req.get_uri_args();local id = uri_args["id"];
--获取本地缓存
local cache_ngx = ngx.shared.dis_cache;
--根据ID 获取本地缓存数据
local contentCache = cache_ngx:get('content_cache_'..id);
if contentCache == "" or contentCache == nil then
local redis = require("resty.redis");
local red = redis:new()
red:set_timeout(2000)
red:connect("192.168.211.132", 6379)
local rescontent=red:get("content_"..id)
--如果nginx没有数据,则从数据库查找
if ngx.null == rescontent then
local cjson = require("cjson");
local mysql = require("resty.mysql");
local db = mysql:new();
db:set_timeout(2000)
local props = {
host = "192.168.72.110",
port = 3306,
database = "data",
user = "root",
password = "root"
}
local res = db:connect(props);
local select_sql = "select * from user";
res = db:query(select_sql);
local responsejson = cjson.encode(res);
red:set("content_"..id,responsejson);
ngx.say(responsejson);
db:close()
else
--将数据存到nginx缓存
cache_ngx:set('content_cache_'..id, rescontent, 10*60);
ngx.say(rescontent);
end
red:close()
else
ngx.say(contentCache)
end
4.设置访问路径,修改nginx配置文件如下
5.访问:http://nginx的所在ip地址/read_content
拿到数据,测试成功