Go+Redis缓存设计与优化实现

 更新时间:2025年02月11日 08:27:38   作者:程序员林北北  
本文主要介绍了Go+Redis缓存设计与优化实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

在本节中,我们将通过一个实际的项目案例,演示如何在 Go 中使用 Redis 实现高效的缓存设计与优化。

业务需求

假设我们正在开发一个电商平台,需要缓存商品信息以提高页面加载速度。商品信息经常被查询,但修改频率较低,因此使用 Redis 作为缓存会大大减少数据库的查询压力。

1. 缓存设计

  • 缓存粒度 :我们将每个商品的信息作为一个缓存项进行存储,缓存的键为商品的 ID,值为商品的 JSON 数据。
  • 缓存失效策略:设置缓存的过期时间为 10 分钟,这样商品信息会在 10 分钟后自动失效,防止过期数据的出现。
  • 缓存预热:在系统启动时,我们通过预加载常见商品的数据到缓存中,减少首次访问时的缓存未命中的情况。

2. Go+Redis代码实现

package main

import (
	"context"
	"encoding/json"
	"fmt"
	"log"
	"time"

	"github.com/go-redis/redis/v8"
)

var ctx = context.Background()

// 商品结构体
type Product struct {
	ID    string `json:"id"`
	Name  string `json:"name"`
	Price float64 `json:"price"`
}

func getProductFromDB(productID string) (*Product, error) {
	// 模拟从数据库获取商品数据
	return &Product{
		ID:    productID,
		Name:  "Example Product",
		Price: 99.99,
	}, nil
}

func getProductFromCache(rdb *redis.Client, productID string) (*Product, error) {
	// 从缓存中获取商品数据
	val, err := rdb.Get(ctx, productID).Result()
	if err == redis.Nil {
		// 缓存未命中,查询数据库
		return nil, nil
	} else if err != nil {
		return nil, err
	}

	var product Product
	err = json.Unmarshal([]byte(val), &product)
	if err != nil {
		return nil, err
	}
	return &product, nil
}

func setProductToCache(rdb *redis.Client, product *Product) error {
	// 将商品数据缓存到 Redis
	productData, err := json.Marshal(product)
	if err != nil {
		return err
	}

	return rdb.Set(ctx, product.ID, productData, 10*time.Minute).Err()
}

func getProduct(rdb *redis.Client, productID string) (*Product, error) {
	// 尝试从缓存中获取商品
	product, err := getProductFromCache(rdb, productID)
	if err != nil {
		return nil, err
	}

	if product == nil {
		// 缓存未命中,查询数据库并将结果缓存
		product, err = getProductFromDB(productID)
		if err != nil {
			return nil, err
		}

		err = setProductToCache(rdb, product)
		if err != nil {
			return nil, err
		}
	}

	return product, nil
}

func main() {
	rdb := redis.NewClient(&redis.Options{
		Addr:     "localhost:6379", // Redis 地址
		Password: "",               // 密码
		DB:       0,                // 默认数据库
	})

	// 获取商品
	productID := "12345"
	product, err := getProduct(rdb, productID)
	if err != nil {
		log.Fatalf("获取商品失败: %v", err)
	}

	fmt.Printf("商品信息: %+v\n", product)
}

3. 代码解析

  • 获取商品信息:首先,我们尝试从 Redis 缓存中获取商品信息。如果缓存未命中,我们会从数据库中查询商品数据,并将查询结果存入缓存。
  • 缓存设置过期时间:商品信息被存入缓存时,我们设置了 10 分钟的过期时间,这样缓存会自动失效。
  • 缓存穿透与击穿防范:通过合理的缓存失效时间和商品信息的缓存设计,避免了缓存穿透和缓存击穿的问题。

4. 性能优化

通过上述设计,我们显著减少了数据库查询次数,降低了数据库的负载,提高了系统的响应速度和吞吐量。

到此这篇关于Go+Redis缓存设计与优化的文章就介绍到这了,更多相关Go Redis缓存内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • 解读rand.Seed(time.Now().UnixNano())的作用及说明

    解读rand.Seed(time.Now().UnixNano())的作用及说明

    这篇文章主要介绍了关于rand.Seed(time.Now().UnixNano())的作用及说明,具有很好的参考价值,希望对大家有所帮助。
    2023-03-03
  • golang默认Logger日志库在项目中使用Zap日志库

    golang默认Logger日志库在项目中使用Zap日志库

    这篇文章主要为大家介绍了golang默认Logger日志库在项目中使用Zap日志库,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步早日升职加薪
    2022-04-04
  • Go秒爬博客园100页新闻

    Go秒爬博客园100页新闻

    利用go语言的协程并发优势爬取网页速度相当之快,博客园100页新闻标题只需一秒即可全部爬取,跟着小编一起去看看如何实现的,希望大家可以从中受益
    2018-09-09
  • golang实现unicode转换为字符串string的方法

    golang实现unicode转换为字符串string的方法

    这篇文章主要介绍了golang实现unicode转换为字符串string的方法,实例分析了Go语言编码转换的相关技巧,具有一定参考借鉴价值,需要的朋友可以参考下
    2016-07-07
  • 解决Golang并发工具Singleflight的问题

    解决Golang并发工具Singleflight的问题

    前段时间在一个项目里使用到了分布式锁进行共享资源的访问限制,后来了解到Golang里还能够使用singleflight对共享资源的访问做限制,于是利用空余时间了解,将知识沉淀下来,并做分享
    2022-05-05
  • Go并发编程sync.Cond的具体使用

    Go并发编程sync.Cond的具体使用

    Go 标准库提供 Cond 原语的目的是,为等待 / 通知场景下的并发问题提供支持,本文主要介绍了Go并发编程sync.Cond的具体使用,具有一定的参考价值,感兴趣的可以了解一下
    2022-05-05
  • golang中获取变量类型的方法总结

    golang中获取变量类型的方法总结

    golang中是没有提供内置函数来获取变量的类型的,但是通过一定的方式也可以获取,下面主要给大家介绍了几个golang获取变量类型的几种方式,需要的朋友可以参考下
    2025-03-03
  • 从生成CRD到编写自定义控制器教程示例

    从生成CRD到编写自定义控制器教程示例

    这篇文章主要为大家介绍了从生成CRD到编写自定义控制器的教程示例,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-05-05
  • 一文带你吃透Golang中net/http标准库服务端

    一文带你吃透Golang中net/http标准库服务端

    这篇文章将从服务端(Server)作为切入点和大家分享一下Go语言net/http标准库的实现逻辑,进而一步步分析http标准库内部是如何运作的,感兴趣的可以了解下
    2024-03-03
  • golang 实现对Map进行键值自定义排序

    golang 实现对Map进行键值自定义排序

    这篇文章主要介绍了golang 实现对Map进行键值自定义排序,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2021-04-04

最新评论