美文网首页
beego cache模块源码解析

beego cache模块源码解析

作者: 蒋植玉 | 来源:发表于2019-08-23 23:06 被阅读0次

缘起.什么是cache?

cache的中文名叫缓存,缓存在计算机的世界里无处不在,比如cpu的多级缓存,比如类似encache的本地缓存。举个现实中的例子,比如取钱,当然这样的场景被电子支付逐渐取代了,那就把时光倒退到10年前。假设你去饭店吃饭,发现兜里没钱了,去银行取了一顿饭的钱,等到下个饭点,又得去趟银行,不是银行忙死就是你累死,聪明的你,一定不会这么傻,你会取多些出来放在兜里,等下次用直接从兜里拿,你的布袋就是缓存。精明的你一定不会取出太多,取出一万块揣在 兜里,不知道的还以为你肿了呢?缓存不能为缓而缓,要缓的恰到好处。

缘生.为什么用cache?

根据我的经验,主要有两点:

a>提高性能,比如把热点数据放进memcache,redis。

b>减少对后端服务的冲击,给它们减压降温。比如有个服务b,需要被服务a调用。哪一天服务a喝醉昏了头,以超高qps向服务b发起冲击。十有八九,服务b会挂掉。那么,服务a服务b之间加个缓存,问题是不是就化解了。此时,我的耳边响起了那句宛如咒语一样的话:计算机里的问题都可以通过加一层来解决。

缘来.beego是怎么做的?

前面有些跑偏了,言归正传。

beego支持多个cache类型,内存、redis、file、memcache、ssdb。先看一下接口定义:

type Cache interface {

// get cached value by key.

      Get(key string)interface{}

// GetMulti is a batch version of Get.

      GetMulti(keys []string) []interface{}

// set cached value with key and expire time.

      Put(key string, valinterface{}, timeout time.Duration) error

// delete cached value by key.

      Delete(key string) error

// increase cached int value by key, as a counter.

      Incr(key string) error

// decrease cached int value by key, as a counter.

      Decr(key string) error

// check if cached value exists or not.

      IsExist(key string) bool

// clear all cache.

      ClearAll() error

// start gc routine based on config string settings.

      StartAndGC(config string) error

}

望文生义,其他函数功能不多解释。主要说说StartAndGC。这个函数主要用来初始连接与清除缓存,redis与memcache可以设置过期时间的缓存适配器是不需要做清除操作的,完全交由他们自己来做。内存缓存、文件缓存就需要自己费神了。简单看一下MemoryCache的实现。

// StartAndGC start memory cache. it will check expiration in every clock time.

func (bc *MemoryCache) StartAndGC(config string) error {

var cfmap[string]int

json.Unmarshal([]byte(config), &cf)

if _, ok := cf["interval"]; !ok {

cf = make(map[string]int)

cf["interval"] = DefaultEvery

}

dur := time.Duration(cf["interval"]) * time.Second

      bc.Every = cf["interval"]

bc.dur = dur

go bc.vacuum()

return nil

}

主要看go bc.vacuum()

这里起了个goroutine,来做过期检测,并清除过期值。

// check expiration.

func (bc *MemoryCache) vacuum() {

bc.RLock()

every := bc.Every

bc.RUnlock()

if every <1 {

return

      }

for {

<-time.After(bc.dur)

if bc.items == nil {

return

              }

if keys := bc.expiredKeys(); len(keys) !=0 {

bc.clearItems(keys)

}

}

}

清除其实就是从map里面删除掉:

// clearItems removes all the items which key in keys.

func (bc *MemoryCache) clearItems(keys []string) {

bc.Lock()

defer bc.Unlock()

for _, key :=range keys {

delete(bc.items, key)

}

}

其他缓存适配器大同小异,当然,你也可以自己实现一个cache,只要实现上面那个cache接口 即可。

有了这些适配器,怎么找到并使用他们呢?

// Instance is a function create a new Cache Instance

type Instancefunc() Cache

var adapters = make(map[string]Instance)

// Register makes a cache adapter available by the adapter name.

// If Register is called twice with the same name or if driver is nil,

// it panics.

func Register(name string, adapterInstance) {

if adapter == nil {

panic("cache: Register adapter is nil")

}

if _, ok := adapters[name]; ok {

panic("cache: Register called twice for adapter " + name)

}

adapters[name] = adapter

}

每个适配器文件里实现了init方法,

func init() {

Register("memory", NewMemoryCache)

}

原来是把适配器注册到了全局变量里。如果要使用适配器,只需传入适配器类型便可。服务很是到位:

func test(){

bm, err := cache.NewCache("redis",`{"conn": "127.0.0.1:6379"}`)

if err != nil {

t.Error("init err")

}

timeoutDuration :=10 * time.Second

if err = bm.Put("astaxie",1, timeoutDuration); err != nil {

t.Error("set Error", err)

}

}

缘终:技术没有终点

第一次写技术博客,很粗糙。看过不如写过,写过不如用过。

相关文章

  • beego cache模块源码解析

    缘起.什么是cache? cache的中文名叫缓存,缓存在计算机的世界里无处不在,比如cpu的多级缓存,比如类似e...

  • beego cache模块源码分析笔记四

    beego cache模块下的ssdb源码,这段源码是在gossdb包的基础上进行封装。 整个源码在230行左右,...

  • go gomemcache包源码分析

    因为beego中的cache模块中的子模块memcached引用了这个包,所以也对这包的源码进行分析了下。花了一定...

  • beego cache模块源码分析笔记一

    cache模块是beego中的一个独立模块,这个模块的设计方式是经典的工厂模式。 cache.go:抽象接口部分、...

  • beego源码cache

    一、缓存 cache模块是一个go缓存管理器,目前能够支持多种缓存方式: Memory、File、Redis、Me...

  • beego cache模块源码分析笔记三

    从代码库中可以看到有两个文件,其中有一个是测试文件。整个代码包括注释一共两百多行代码。 整个代码提供给开发者的内容...

  • beego cache模块源码分析笔记二

    之前已经分析了外面的那几个文件,现在分析下里面的这几个文件。 这个目录夹里有两个文件,一个是测试文件。里面有一个结...

  • Kubernetes Informer 源码解析与深度使用 [1

    原文地址:Kubernetes Informer 源码解析与深度使用 [1/4]: cache 包源码解析与 In...

  • SDWebImage

    1.SDWebImage源码解析(1)——总体架构,Cache读取2.SDWebImage源码解析(2)——ima...

  • MyBatis源码解析(四) Cache模块

    MyBatis的二级缓存 MyBatis的缓存分为一级缓存和二级缓存,一级缓存是 SqlSession 级别的缓存...

网友评论

      本文标题:beego cache模块源码解析

      本文链接:https://www.haomeiwen.com/subject/nahxectx.html