首页 > 数据库 >redis 缓存 singlefly 查询

redis 缓存 singlefly 查询

时间:2024-06-01 11:21:28浏览次数:26  
标签:缓存 return nil err redis value singlefly string

正常缓存没有数据时会先从DB取数据来回填缓存,而如果瞬间查询过多或者缓存利用率过低。

singlefly

当瞬间过多查询到缓存的空值时就会一起去查询数据库,带给数据库压力变大。这里不能直接用 mutex,如果用了拿不到资源的会自旋等待,拿到后继续查 DB,用 mutex 可能会出现整个逻辑处于一直查 DB 的状态。

// Cache 是一个简单的缓存结构
type Cache struct {
    mu    sync.RWMutex
    data  map[string]string
    group singleflight.Group
}

// NewCache 初始化一个新的 Cache 实例
func NewCache() *Cache {
    return &Cache{
        data: make(map[string]string),
    }
}

// Get 从缓存中获取值,如果值不存在则调用 fetcher 函数来更新缓存
func (c *Cache) Get(key string, fetcher func() (string, error)) (string, error) {
    c.mu.RLock()
    value, exists := c.data[key]
    c.mu.RUnlock()

    if exists {
        return value, nil
    }

    // 使用 singleflight 确保只有一个请求会触发 fetcher 调用
    result, err, _ := c.group.Do(key, func() (interface{}, error) {
     // 假设这个 fetcher 方法就是从数据库拿数据 value, err := fetcher() if err != nil { return nil, err }      // 假装这里在回填缓存 c.mu.Lock() c.data[key] = value c.mu.Unlock() return value, nil }) if err != nil { return "", err } return result.(string), nil }

空缓存设置

当数据库没有的数据的查询会反复查询数据库,这时可以在缓存中设置空值进行防护。

    // 使用 singleflight 确保只有一个请求会触发 fetcher 调用
    result, err, _ := c.group.Do(key, func() (interface{}, error) {
        value, err := fetcher()
        if err != nil {
            // 对于获取失败的情况,不缓存空值
            return nil, err
        }

        c.mu.Lock()
        // 如果数据库返回空结果,缓存一个特殊的空值
        if value == "" {
            c.data[key] = ""
            c.mu.Unlock()
            return "", errors.New("fetched but empty value")
        }

        c.data[key] = value
        c.mu.Unlock()
        return value, nil
    })

    if err != nil {
        return "", err
    }

 

标签:缓存,return,nil,err,redis,value,singlefly,string
From: https://www.cnblogs.com/caiawo/p/18225697

相关文章

  • Session+Redis,Token+Redis,JWT+Redis,用户身份认证,到底选择哪种更合适?
    1三中方案的比较在选择Session+Redis、Token+Redis、JWT+Redis这三种用户身份认证方案时,我们需要考虑各自的优势、劣势以及应用场景。以下是对这三种方案的详细分析和比较:1.Session+Redis优势:Session登录是一种在Web应用程序中用于跟踪用户状态的机制,通过在服务器端存储......
  • windows安装redis
    1、下载: Releases·microsoftarchive/redis(github.com)   2、解压Redis安装包 3、注册RedisWindows服务进入Redis安装包目录,执行如下的命令,安装服务redis-server.exe--service-installredis.windows.conf--service-nameredisserver1--loglevelverbose......
  • 【运维项目经历|026】Redis智能集群构建与性能优化工程
    ......
  • redis的command命令
    一.Redis命令详解SLOWLOG:用途:用于记录和查询执行时间超过设定阈值的慢查询。子命令:SLOWLOGGET[n]:获取最新的n条慢查询日志。如果未指定n,则返回所有日志。SLOWLOGLEN:返回慢查询日志的条数。SLOWLOGRESET:清空慢查询日志。示例:SLOWLOGGET5SLOWL......
  • redis 缓存一致性
    问题在使用缓存中一般都是先看看缓存是否有数据,没有查db,再回填到缓存。然后更新时候一般是更新db,更新完了再删除或者回填缓存。然而因为缓存与数据库是两个独立的系统,很难去保证原子性,所以就产生了一致性的问题。 比如说:一个查询请求查到了数据库数据,然后准备更新到缓存......
  • 两台windowserver服务器配置Redis哨兵集群
    十年河东,十年河西,莫欺少年穷学无止境,精益求精redis下载地址:https://github.com/tporadowski/redis/releases 这里选择压缩版,不选择安装版1、集群环境 主机master:局域网IP  172.27.40.27从机slave:局域网IP  172.27.40.29 2、修改主从相关配置-两台服务器均需修改......
  • Springcloud学习笔记68--springboot 整合Caffeine 本地缓存
    一、本地缓存介绍缓存在日常开发中启动至关重要的作用,由于是存储在内存中,数据的读取速度是非常快的,能大量减少对数据库的访问,减少数据库的压力。之前介绍过Redis这种NoSql作为缓存组件,它能够很好的作为分布式缓存组件提供多个服务间的缓存,但是Redis这种还是需要网络开销,增......
  • 防止浏览器缓存了静态的配置等文件(例如外部的config.js 等文件)
    防止浏览器缓存了静态的配置文件前言1、在script引入的时候添加随机数1.1、引入js文件1.2、引入css文件2、通过html文件的<meta>设置防止缓存3、使用HTTP响应头:前言在实际开发中浏览器的缓存问题一直是一个很让人头疼的问题,尤其是我们打包时候防止的静态配置文件con......
  • Redis-Redis为什么快
    参考文章:Redis常见面试题总结(上)redisIO多路复用模型详解JavaIO模型详解1.Redis是什么Redis(REmoteDIctionaryServer)是一个基于C语言开发的开源NoSQL数据库(BSD许可)。与传统数据库不同的是,Redis的数据是保存在内存中的(内存数据库,支持持久化),因此读写速度非常快,被广......
  • redis集群
    redis集群搭建注意:Redis5以上版本适用1、直接使用下面的步骤mkdir/redis-cluster/7000/redis-cluster/7001/redis-cluster/7002/redis-cluster/7003/redis-cluster/7004/redis-cluster/7005//创建六个文件夹代表六个redis服务存放目录touchredis.conf//每个目录创......