简单使用freeCache作为本地缓存

简单使用FreeCache作为本地缓存

概述

这个笔记要记录的是Gin框架下简单使用本地缓存,以及使用本地缓存的简单思路。
本地缓存是将数据存储在本地内存中,以便在需要时快速访问。当请求命中缓存时可以提高访问速度,同时也能降低数据库的压力。一般来说一级缓存通常指的是本地缓存,而二级缓存指的是远程缓存(如Redis、Memcached)。使用本地缓存能够减少与远程缓存间的数据交互,降低网络I/O开销,提高程序的响应速度和减少压力。

思路

在用户发起请求时,首先在本地缓存中查询是否有数据。如果命中了本地缓存则直接返回数据,否则继续向下一级缓存Redis请求。如果这下一级缓存还没有命中则请求Mysql。当查询到Mysql返回的数据时再设置本地缓存和Redis缓存。当Mysql数据库中修改了数据后,需要将之前设置的缓存给清理掉。
在Gin框架中我们使用freeCache作为本地缓存。FreeCache是一个基于Go语言的本地缓存库。它可以在应用程序内存中存储键值对,用于加速访问频繁的数据,如数据库查询结果、计算结果等。特点是性能非常高,内存的使用效率也非常高。github地址是github.com/coocood/freecache。我们将对上一个项目处理获取用户资料的功能进行简单修改,使用freeCache作为本地缓存。当Mysql修改了用户资料时将对应的缓存清除掉。我的思路是在v3/user/profile路由上把本地缓存设置成一个中间件,放在中Redis之前。Redis中间件作为二级缓存放在本地缓存后,如果一二级缓存都没有命中那么请求Mysql。获得请求到的数据后设置本地和Redis缓存。在v3/edit/profile路由上,如果修改Mysql数据完成后就将缓存清理掉。

简单使用freeCache作为本地缓存

简单使用freeCache作为本地缓存

实现

初始化本地缓存&设置为中间件

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的字符。

简单使用freeCache作为本地缓存

简单使用freeCache作为本地缓存

写在最后

本人是新手小白,如果这篇笔记中有任何错误或不准确之处,真诚地希望各位读者能够给予批评和指正。谢谢!练习的代码放在这里–↓
https://github.com/FengZeHe/LearnGolang/tree/main/project/BasicProject

原文始发于微信公众号(ProgrammerHe):简单使用freeCache作为本地缓存

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/207877.html

(0)
小半的头像小半

相关推荐

发表回复

登录后才能评论
极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!