简单使用FreeCache作为本地缓存
概述
思路
Redis
请求。如果这下一级缓存还没有命中则请求Mysql
。当查询到Mysql
返回的数据时再设置本地缓存和Redis
缓存。当Mysql
数据库中修改了数据后,需要将之前设置的缓存给清理掉。freeCache
作为本地缓存。FreeCache是一个基于Go语言的本地缓存库。它可以在应用程序内存中存储键值对,用于加速访问频繁的数据,如数据库查询结果、计算结果等。特点是性能非常高,内存的使用效率也非常高。github
地址是github.com/coocood/freecache
。我们将对上一个项目处理获取用户资料的功能进行简单修改,使用freeCache
作为本地缓存。当Mysql
修改了用户资料时将对应的缓存清除掉。我的思路是在v3/user/profile
路由上把本地缓存设置成一个中间件,放在中Redis
之前。Redis
中间件作为二级缓存放在本地缓存后,如果一二级缓存都没有命中那么请求Mysql
。获得请求到的数据后设置本地和Redis
缓存。在v3/edit/profile
路由上,如果修改Mysql
数据完成后就将缓存清理掉。实现
初始化本地缓存&设置为中间件
var (
cacheSize = 100 * 1024 * 1024 // 定义缓存的大小 100MB
LocalCache = freecache.NewCache(cacheSize) //初始化freeCache,函数会返回一个*freecahe.Cahe类型的指针
)
// 本次缓存中间件
func LocalCacheMiddleware() gin.HandlerFunc {
return func(c *gin.Context) {
/*
1. 如果key存在,则直接返回
2. 如果key不存在,则下一步看看redis中有没有
*/
userid, _ := c.Get("userid")
key := fmt.Sprintf("%s", userid)
value, err := GetLocalCacheByUserId(key)
if err != nil {
log.Println("Miss Local Cache")
c.Next()
} else {
log.Println("Hit Local Cache")
c.JSON(http.StatusOK, gin.H{
"message": "success",
"userprofile": value,
})
c.Abort()
}
}
}
设置/获取/删除 freecache中的值
// 设置缓存,调用freecache.Set()方法
func SetCache(key, value string, expire int) (err error) {
err = LocalCache.Set([]byte(key), []byte(value), expire)
if err != nil {
return err
}
return nil
}
// 获取缓存,调用freecache.Get()方法
func GetCache(key string) (value []byte, err error) {
value, err = LocalCache.Get([]byte(key))
if err != nil {
return nil, err
}
return value, nil
}
// 清除缓存,调用freecache.Del()方法
func DelCache(key string) (affected bool) {
/*
freeCache如果使用Del()方法删除指定key,返回一个bool值
*/
affected = LocalCache.Del([]byte(key))
return affected
}
在路由上设置中间件
{
v3.POST("/user/profile", JWT.JWTAuth(), localcache.LocalCacheMiddleware(), cache.RedisCacheMiddleWare(), controller.HandleUserProfileV2)
v3.POST("/user/edit", JWT.JWTAuth(), controller.HandleEditProfileV2)
}
在Controller层设置&清理缓存
func HandleUserProfileV2(ctx *gin.Context) {
xxx
....
xxxx
userinfo, _ := logic.GetUserProfileById(userIdStr)
ctx.JSON(http.StatusOK, gin.H{
"message": "success",
"userprofile": userinfo,
})
// 设置userinfo到本地缓存
if err := localcache.SetLocalCacheByUserId(&userinfo, userinfo.Id); err != nil {
log.Println("Set User Profile Local Cache ERROR", err)
}
// 设置userinfo到redis中缓存
if err := cache.SetCacheByUserId(&userinfo, userinfo.Id); err != nil {
log.Println("Set User Profile Redis Cache ERROR", err)
}
}
// 处理用户编辑信息请求 V2
func HandleEditProfileV2(ctx *gin.Context) {
xxx
...
xxx
//修改完成后清除LocalCache
if err := localcache.DelLocalCacheByUserId(userStr); err != nil {
log.Println("Del Local Cache By UserId ERROR ", err)
}
//删除redis缓存
if err := cache.DelCacheByUserId(userStr); err != nil {
log.Println("Del Redis Cache By UserId ERROR ", err)
}
// 返回成功
ctx.JSON(http.StatusOK, gin.H{
"message": "success",
})
}
验证
v3/user/profile
,首次请求时本地缓存和redis
缓存都不会命中,会向Mysql
请求数据,完成之后会设置本地缓存。在第二次请求时会命中本地缓存,看到Hit local cache
的字符。写在最后
https://github.com/FengZeHe/LearnGolang/tree/main/project/BasicProject
原文始发于微信公众号(ProgrammerHe):简单使用freeCache作为本地缓存
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/207877.html