千家信息网

如何提高进程内缓存的并发

发表于:2026-11-03 作者:千家信息网编辑
千家信息网最后更新 2026年11月03日,本篇文章给大家分享的是有关如何提高进程内缓存的并发,小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话不多说,跟着小编一起来看看吧。缓存,设计的初衷是为了减少繁重的IO操作
千家信息网最后更新 2026年11月03日如何提高进程内缓存的并发

本篇文章给大家分享的是有关如何提高进程内缓存的并发,小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话不多说,跟着小编一起来看看吧。

缓存,设计的初衷是为了减少繁重的IO操作,增加系统并发能力。不管是 CPU多级缓存,page cache,还是我们业务中熟悉的 redis 缓存,本质都是将有限的热点数据存储在一个存取更快的存储介质中。

计算机本身的缓存设计就是 CPU 采取多级缓存。那对我们服务来说,我们是不是也可以采用这种多级缓存的方式来组织我们的缓存数据。同时 redis 的存取都会经过网络IO,那我们能不能把热点数据直接存在本进程内,由进程自己缓存一份最近最热的这批数据呢?

这就引出了我们今天探讨的:local cache,本地缓存,也叫进程缓存。

快速入门

作为一个进程存储设计,当然是 crud 都有的:

  1. 我们先初始化 local cache

// 先初始化 local cachecache, err = collection.NewCache(time.Minute, collection.WithLimit(10))if err != nil {  log.Fatal(err)}

其中参数的含义:

  • expire:key统一的过期时间

  • CacheOption:cache设置。比如key的上限设置等

  1. 基础操作缓存

// 1. add/update 增加/修改都是该APIcache.Set("first", "first element")// 2. get 获取key下的valuevalue, ok := cache.Get("first")// 3. del 删除一个keycache.Del("first")
  • Set(key, value) 设置缓存

  • value, ok := Get(key) 读取缓存

  • Del(key) 删除缓存

  1. 高级操作

cache.Take("first", func() (interface{}, error) {  // 模拟逻辑写入local cache  time.Sleep(time.Millisecond * 100)  return "first element", nil})

前面的 Set(key, value) 是单纯将 加入缓存;Take(key, setFunc) 则是在 key 对于的 value 不存在时,执行传入的 fetch 方法,将具体读取逻辑交给开发者实现,并自动将结果放到缓存里。

到这里核心使用代码基本就讲完了,其实看起来还是挺简单的。也可以到 https://github.com/tal-tech/go-zero/blob/master/core/collection/cache_test.go 去看 test 中的使用。

解决方案

首先缓存实质是一个存储有限热点数据的介质,面临以下的这些问题:

  1. 有限容量

  2. 热点数据统计

  3. 多线程存取

下面来说说这3个方面我们的设计实践。

有限容量

有限就意味着满了要淘汰,这个就涉及到淘汰策略。cache 中使用的是:LRU(最近最少使用)。

那淘汰怎么发生呢? 有几个选择:

  1. 开一个定时器,不断循环所有key,等到了预设过期时间,执行回调函数(这里是删除map中过的key)

  2. 惰性删除。访问时判断该键是否被删除。缺点是:如果未访问的话,会加重空间浪费。

而 cache 中采取的是第一种 主动删除。但是,主动删除中遇到最大的问题是:

不断循环,空消耗CPU资源,即使在额外的协程中这么做,也是没有必要的。

cache 中采取的是时间轮记录额外过期通知,等过期 channel 中有通知时,然后触发删除回调。

> 有关 时间轮 更多的设计文章:https://go-zero.dev/cn/timing-wheel.html

热点数据统计

对于缓存来说,我们需要知道这个缓存在使用额外空间和代码的情况下是否有价值,以及我们想知道需不需要进一步优化过期时间或者缓存大小,所有这些我们就很依赖统计能力了, go-zero 中 sqlc 和 mongoc 也同样提供了统计能力。所以我们在 cache 中也加入的缓存,为开发者提供本地缓存监控的特性,在接入 ELK 时开发者可以更直观的监测到缓存的分布情况。

而设计其实也很简单,就是:Get() 命中,就在统计 count 上加1即可。

func (c *Cache) Get(key string) (interface{}, bool) {  value, ok := c.doGet(key)  if ok {    // 命中hit+1    c.stats.IncrementHit()  } else {    // 未命中miss+1    c.stats.IncrementMiss()  }  return value, ok}

多线程存取

当多个协程并发存取的时候,对于缓存来说,涉及的问题以下几个:

  • 写-写冲突

  • LRU 中元素的移动过程冲突

  • 并发执行写入缓存时,造成流量冲击或者无效流量

这种情况下,写冲突好解决,最简单的方法就是 加锁 :

// Set(key, value)func (c *Cache) Set(key string, value interface{}) {  // 加锁,然后将  作为键值对写入 cache 中的 map  c.lock.Lock()  _, ok := c.data[key]  c.data[key] = value  // lru add key  c.lruCache.add(key)  c.lock.Unlock()  ...}// 还有一个在操作 LRU 的地方时:Get()func (c *Cache) doGet(key string) (interface{}, bool) {  c.lock.Lock()  defer c.lock.Unlock()  // 当key存在时,则调整 LRU item 中的位置,这个过程也是加锁的  value, ok := c.data[key]  if ok {    c.lruCache.add(key)  }  return value, ok}

而并发执行写入逻辑,这个逻辑主要是开发者自己传入的。而这个过程:

func (c *Cache) Take(key string, fetch func() (interface{}, error)) (interface{}, error) {  // 1. 先获取 doGet() 中的值  if val, ok := c.doGet(key); ok {    c.stats.IncrementHit()    return val, nil  }  var fresh bool  // 2. 多协程中通过 sharedCalls 去获取,一个协程获取多个协程共享结果  val, err := c.barrier.Do(key, func() (interface{}, error) {    // double check,防止多次读取    if val, ok := c.doGet(key); ok {      return val, nil    }    ...    // 重点是执行了传入的缓存设置函数    val, err := fetch()    ...    c.Set(key, val)  })  if err != nil {    return nil, err  }  ...  return val, nil}

而 sharedCalls 通过共享返回结果,节省了多次执行函数,减少了协程竞争。

以上就是如何提高进程内缓存的并发,小编相信有部分知识点可能是我们日常工作会见到或用到的。希望你能通过这篇文章学到更多知识。更多详情敬请关注行业资讯频道。

缓存 数据 进程 设计 时间 有限 热点 存取 统计 就是 开发者 逻辑 存储 开发 函数 情况 更多 结果 能力 过程 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 江苏根荣互联网科技 科技平台互联网 北京互联网科技有限公司 互联网 科技创业 互联网科技股票 互联网金融科技平台 互联网科技logo 成都玖崟互联网科技有限公司乐商圈怎么样 云创客互联网科技公司 阿里巴巴算科技企业还是互联网 随着互联网科技发展 北京华百购互联网科技有限公司 宜昌元轩互联网科技有限公司 广州市恰铎互联网科技有限公司 互联网在线教育科技创业 上海同邻互联网科技有限公司规模 江苏互联网智能科技产品出厂价 广州智享互联网科技 保山互联网科技靠谱吗 科技互联网企业在行动 喔噻互联网科技有限公司 互联网科技论文 湖南洣水互联网科技有限公司扣款 互联网科技有哪些公司 河南住房之家互联网科技 互联网时代的科技公司 银行科技岗属于互联网吗 中国新注册互联网科技 福仕德教育科技互联网 米泉互联网科技专业怎么样
0