package mainimport ("context""github.com/redis/go-redis/v9""log""time" )var (redisAddr = "addr"redisPassword = "pwd"redisDB = 0// ⚠️ 只清这些前缀(非常重要)patterns = []string{//"PLAT:USER:*","PLAT:USER:NEW:CHANNEL:INFO:*",//"PLAT:AD:*", }// 给历史 Key 补的 TTLexpireSeconds = int64(7 * 24) // 7 天// SCAN 每批数量(别太大)scanCount = int64(500)// 每处理一批 sleep,防止打爆 RedisbatchSleep = 50 * time.Millisecond )func main() {ctx := context.Background()rdb := redis.NewClient(&redis.Options{Addr: redisAddr,Password: redisPassword,DB: redisDB,})defer rdb.Close()for _, pattern := range patterns {log.Printf("🚀 start cleaning pattern: %s\n", pattern)if err := cleanByPattern(ctx, rdb, pattern); err != nil {log.Fatalf("❌ clean failed: %v", err)}}log.Println("✅ all patterns finished") }func cleanByPattern(ctx context.Context, rdb *redis.Client, pattern string) error {var cursor uint64var total int64for {keys, nextCursor, err := rdb.Scan(ctx, cursor, pattern, scanCount).Result()if err != nil {return err}for _, key := range keys {ttl, err := rdb.TTL(ctx, key).Result()if err != nil {log.Printf("⚠️ TTL error key=%s err=%v\n", key, err)continue}// 只处理「无过期时间」的 keyif ttl == -1 {ok, err := rdb.Expire(ctx, key, time.Duration(expireSeconds)*time.Hour).Result()if err != nil || !ok {log.Printf("⚠️ expire failed key=%s err=%v\n", key, err)continue}total++}}log.Printf("pattern=%s cursor=%d processed=%d\n", pattern, nextCursor, total)cursor = nextCursorif cursor == 0 {break}time.Sleep(batchSleep)}log.Printf("🎯 pattern=%s done, total expired=%d\n", pattern, total)return nil }