在本节中,我们将通过一个实际的项目案例,演示如何在 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缓存内容请搜索代码网以前的文章或继续浏览下面的相关文章希望大家以后多多支持代码网!
发表评论