为什么我的redis缓存只返回部分数据
php小编香蕉在使用redis缓存时,可能会遇到一个常见问题:为什么我的redis缓存只返回部分数据?这个问题可能有多种原因,包括缓存设置不当、缓存键名冲突、缓存过期等。在解决这个问题之前,我们需要仔细检查代码和配置,确保缓存的正常运行。本文将为您分析可能的原因,并提供解决方案,帮助您解决这个问题,确保redis缓存返回完整的数据。
问题内容
该函数检查 postgres 与 redis 缓存的实现情况 当我发出 get 请求时,第一个结果返回所有数据,但是当我发出下一个结果时,数据的某些字段丢失
func (usr *UserImplementation) GetAllUsers(ctx context.Context) ([]models.User, error) {
cachedUsers, err := databaseapi.Redis_CacheDB_Api()
if err != nil {
return nil, fmt.Errorf("error connecting to Redis cache: %v", err)
}
// pipe := cachedUsers.TxPipeline()
cachedData, err := cachedUsers.Get(ctx, "users").Result()
if err != nil && err != redis.Nil {
return nil, fmt.Errorf("error retrieving cached data: %v", err)
}
if cachedData != "" {
// Data found in the cache, return the cached data
var cachedUsers []models.User
err := json.Unmarshal([]byte(cachedData), &cachedUsers)
if err != nil {
return nil, fmt.Errorf("error unmarshaling cached data: %v", err)
}
return cachedUsers, nil
}
users, err := usr.pg.Postgres_DB_Api().DB.GetAllUsers(ctx)
if err != nil {
return nil, fmt.Errorf("error: %v", err.Error())
}
cacheData, err := json.Marshal(users)
if err != nil {
return nil, fmt.Errorf("error marshaling data for caching: %v", err)
}
expiration := time.Hour
err = cachedUsers.Set(ctx, "users", string(cacheData), expiration).Err()
if err != nil {
return nil, fmt.Errorf("error caching data: %v", err)
}
return models.DatabaseUsersToUsers(users), nil
}
这是我的用户结构:type user struct {
id uuid.uuid json:"id"
名字字符串 json:"first_name"
姓氏字符串 json:"last_name"
其他名称字符串 json:"other_name"
用户名字符串 json:"user_name"
密码字符串 json:"密码"
电子邮件字符串 json:"email"
配置文件图像字符串 json:"profile_image"
状态字符串 json:"status"
isadmin bool json:"is_admin"
角色字符串 json:"角色"
性别字符串 json:"性别"
电话号码字符串 json:"phone_number"
createdat time.时间 json:"created_at"
updatedat time.时间 json:"updated_at"
}
解决方法
我整理了一个小例子来尝试帮助您。作为前提,我简化了您的示例,只是为了提供此处重要的内容。由于程序的某些部分尚未共享,我不得不做一些猜测。如果这个例子没有用,请让我知道缺少什么,我会更新我的答案。让我们从我使用 docker 在本地运行 postgres/redis 的命令开始。
设置
我使用的命令是:
docker run -d -p 54322:5432 -e postgres_password=postgres postgres
docker run -d --name redis-stack -p 6379:6379 -p 8001:8001 redis/redis-stack:latest
现在,让我们切换到代码。
程序
package main
import (
"context"
"encoding/json"
"fmt"
"time"
"github.com/redis/go-redis/v9"
"gorm.io/driver/postgres"
"gorm.io/gorm"
)
type user struct {
ID int `json:"id"`
FirstName string `json:"first_name"`
LastName string `json:"last_name"`
}
func main() {
// 1. instantiate clients
dsn := "host=localhost port=54322 user=postgres password=postgres"
db, err := gorm.Open(postgres.Open(dsn))
if err != nil {
panic(err)
}
redisClient := redis.NewClient(&redis.Options{
Addr: ":6379",
Password: "",
DB: 0,
})
// 2. automigrate objects & seed dummy data
db.AutoMigrate(&user{})
db.Create(&user{ID: 1, FirstName: "John", LastName: "Doe"})
db.Create(&user{ID: 2, FirstName: "Suzy", LastName: "White"})
// 3. attempt to retrieve from cache
var users []user
cachedUsers, err := redisClient.Get(context.Background(), "users").Result()
if err != nil && err != redis.Nil {
panic(fmt.Errorf("err retrieving cached data: %v", err))
}
if cachedUsers != "" {
if err := json.Unmarshal([]byte(cachedUsers), &users); err != nil {
panic(fmt.Errorf("err while unmarshaling data: %v", err))
}
fmt.Println("users taken from Redis")
for _, v := range users {
fmt.Println(v)
}
return
}
// 4. retrieve from the DB
if err := db.Model(&user{}).Find(&users).Error; err != nil {
panic(fmt.Errorf("err while retrieving from DB: %v", err))
}
// 5. set the key within the cache
rawUsers, err := json.Marshal(users)
if err != nil {
panic(fmt.Errorf("err while marshaling users: %v", err))
}
if err := redisClient.Set(context.Background(), "users", rawUsers, time.Minute*15).Err(); err != nil {
panic(fmt.Errorf("err while setting key in cache: %v", err))
}
fmt.Println("users taken from DB")
for _, v := range users {
fmt.Println(v)
}
}
让我们仔细看看每个部分(按编号评论划分):
- 在客户端初始化中没有太多可说的。我们初始化了指向本地实例的客户端
- 然后,我们使用一些虚拟数据设置数据库
- 我们尝试从 redis 实例获取数据。如果找到它们,我们将其打印出来并终止程序
- 如果在缓存中没有找到数据,那么我们从数据库中获取它们
- 最后,如果我们从数据库中获取数据,则可以安全地假设我们也应该将它们放入缓存中
在这两种情况下,我们都使用相同的字段获取相同数量的数据。因此,如果您坚持这个示例并将其调整为您的模型和项目类型(我的不是网络项目),您应该会很好。如果您仍然遇到问题,请告诉我。谢谢!
以上就是为什么我的redis缓存只返回部分数据的详细内容,更多请关注编程网其它相关文章!
免责声明:
① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。
② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341