Lors de l'utilisation du cache Redis, vous pouvez rencontrer un problème courant : Pourquoi mon cache Redis ne renvoie-t-il qu'une partie des données ? Ce problème peut avoir plusieurs causes, notamment des paramètres de cache incorrects, des conflits de noms de clé de cache, l'expiration du cache, etc. Avant de résoudre ce problème, nous devons vérifier soigneusement le code et la configuration pour nous assurer que le cache fonctionne correctement. Cet article analysera pour vous les causes possibles et fournira des solutions pour vous aider à résoudre ce problème et garantir que le cache Redis renvoie des données complètes.
Cette fonction vérifie l'implémentation du cache postgres et redis Lorsque je fais une requête get, le premier résultat renvoie toutes les données, mais lorsque je fais le résultat suivant, certains champs de données manquent
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 }
Voici ma structure utilisateur : tapez user struct {
identifiant uuid.uuid json:"id"
Chaîne de nom json:"first_name"
Chaîne de nom de famille json:"last_name"
Autres chaînes de noms json:"other_name"
Chaîne de nom d'utilisateur json:"user_name"
Chaîne de mot de passe json:"密码"
Chaîne d'e-mail json:"email"
Chaîne d'image de profil json:"profile_image"
chaîne de statut json:"status"
isadmin booléen json:"is_admin"
chaîne de rôle json:"角色"
Chaîne de genre json:"性别"
Chaîne de numéro de téléphone json:"phone_number"
créé à l'heure json:"created_at"
mis à jour à l'heure json:"updated_at"
}
J'ai rassemblé un petit exemple pour essayer de vous aider. En principe, j'ai simplifié votre exemple juste pour fournir ce qui est important ici. Étant donné que certaines parties du programme n'ont pas encore été partagées, je dois faire quelques suppositions. Si cet exemple ne fonctionne pas, faites-moi savoir ce qui manque et je mettrai à jour ma réponse. Commençons par ma commande pour exécuter postgres/redis localement à l'aide de Docker.
La commande que j'ai utilisée est :
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
Maintenant, passons au code.
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) } }
Regardons de plus près chaque section (divisée par des commentaires numérotés) :
Dans les deux cas, nous utilisons les mêmes champs pour obtenir la même quantité de données. Donc, si vous vous en tenez à cet exemple et l'adaptez à votre modèle et à votre type de projet (le mien n'était pas un projet Web), tout devrait bien se passer. Si vous rencontrez toujours des problèmes, faites-le-moi savoir. Merci!
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!