目录
- 缓存设计原则
- 多级缓存
- redis 缓存
- 单机模式
- 本地缓存
- sentinal哨兵模式
- 集群cluster模式
- 热点本地缓存
- nginx proxy chche 缓存
- 依靠文件系统存索引级的文件
- nginx lua 缓存
缓存设计原则
- 用内存
- 将缓存推到距离用户最近的地方
- 脏缓存的清理
多级缓存
redis 缓存
把它当作集中式缓存的中间件,K-V 数据库。是一个易丢失的存储设备
单机模式
本地缓存
public interface CacheService {
//存方法
void setCommonCache(String key, Object value);
//取方法
Object getFromCommonCache(String key);
}
@Service
public class CacheServiceImpl implements CacheService {
private Cache<String, Object> commonCache = null;
@PostConstruct
public void init(){
commonCache = CacheBuilder.newBuilder()
//设置初始容量为10
.initialCapacity(10)
//设置最大的KEY数量为100
.maximumSize(100)
//设置过期时间为60s 采用的是在写后开始算起,而不是访问后
.expireAfterWrite(60, TimeUnit.MINUTES)
.build();
}
@Override
public void setCommonCache(String key, Object value) {
commonCache.put(key, value);
}
@Override
public Object getFromCommonCache(String key) {
return commonCache.getIfPresent(key);
}
}
然后我们在itemController中用上本地缓存与redis缓存
//商品详情页浏览
@RequestMapping(value = "/get",method = {RequestMethod.GET})
@ResponseBody
public CommonReturnType getItem(@RequestParam(name = "id")Integer id){
ItemModel itemModel = null;
//先取本地缓存
itemModel = (ItemModel) cacheService.getFromCommonCache("item_"+id);
if(itemModel == null){
//根据商品的id到redis内获取
itemModel = (ItemModel) redisTemplate.opsForValue().get("item_"+id);
//若redis内不存在对应的itemModel,则访问下游service
if(itemModel == null){
itemModel = itemService.getItemById(id);
//设置itemModel到redis内
redisTemplate.opsForValue().set("item_"+id,itemModel);
redisTemplate.expire("item_"+id,10, TimeUnit.MINUTES);
}
cacheService.setCommonCache("item_"+id, itemModel);
}
ItemVO itemVO = convertVOFromModel(itemModel);
return CommonReturnType.create(itemVO);
}
sentinal哨兵模式
这里选择哪个master依靠的是Hash算法
集群cluster模式
如果redis3出现了问,因为miaosha.jar存储的是错误的,redis2就会给他一个reask请求。
热点本地缓存
- 热点数据
- 对于脏数据不敏感
- 内存可控
nginx proxy chche 缓存
依靠文件系统存索引级的文件
#声明一个cache缓存节点的内容
proxy_cache_path /usr/local/openresty/nginx/tmp_cache levels=1:2 keys_zone=tmp_cache:100m inactive=7d max_size=10g;
location / {
proxy_pass http://backend_server;
proxy_cache tmp_cache;
proxy_cache_key $uri;
proxy_cache_valid 200 206 304 302 7d;
}
这种方法因为是在磁盘中寻找,所以比较慢,我们不采用。
nginx lua 缓存
- lua 协程机制
- nginx协程机制
- nginx lua 插载点
比如说这里的staticitem.lua ,我们还需要在nginx.conf 的配置文件中写上下面的配置,然后我们在url 打出miaoshaserver/staticitem/get
location /staticitem/get{
default_type "text/html";
content_by_lua_file ../lua/staticitem.lua;
}
- OpenResty
- helloword级别
首先在Lua目录下新建一个helloword.lua 脚本文件 里面写上ngx.exec("/item/get?id=6");
然后在nginx.conf 配置文件下写
location /helloword{
content_by_lua_file ../lua/helloword.lua;
}
然后在浏览器中输入就可以看到:
- shared dic(共享内存字典)
编写lua 脚本
在nginx.conf 中配置:
lua_shared_dict my_cache 128m;
location /luaitem/get{
default_type "application/json";
content_by_lua_file ../lua/itemsharedic.lua;
}
在新建的itemsharedic.lua 脚本中写上:
function get_from_cache(key)
local cache_ngx = ngx.shared.my_cache
local value = cache_ngx:get(key)
return value
end
function set_to_cache(key, value, exptime)
if not exptime then
exptime = 0
end
local cache_ngx = ngx.shared.my_cache
local succ, err, forcible = cache_ngx:set(key, value, exptime)
return succ
end
local args = ngx.req.get_uri_args()
local id = args["id"]
local item_model = get_from_cache("item_"..id)
if item_model == nil then
local resp = ngx.location.capture("/item/get?id="..id)
item_model = resp.body
set_to_cache("item_"..id, item_model, 1*60)
end
ngx.say(item_model)
**如何看nginx 是否收到了请求呢?我们可以看logs 目录下的access.log 日志文件。如何看报错信息呢?我们可以看error.log 目录 好比 后端tomcat 的接受请求就是看我们自定义的 tomcat 目录 **
- openresty redis 支持
首先建立一个Luad脚本文件,里面写上需要编写的脚本代码:
local args = ngx.req.get_uri_args()
local id = args["id"]
local redis = require "resty.redis"
local cache = redis:new()
local ok, err = cache:connect("192.168.0.232", 6379)
local item_model = cache:get("item_"..id)
if item_model == ngx.null or item_model == nil then
local resp = ngx.location.capture("/item/get?id="..id)
item_model = resp.body
end
ngx.say(item_model)
然后在nginx.conf 文件中 配置上访问路径啥的。
location /luaitem/get{
default_type "application/json";
content_by_lua_file ../lua/itemredis.lua;
}
然后在url 上访问:http://miaoshaserver/luaitem/get?id=6
就会出现该缓存的结果