package main import ( "context" "fmt" "os" "strconv" "strings" "time" "github.com/redis/go-redis/v9" ) // 用法: go run . [password] // 例: go run . 10.1.1.100:6379 func main() { addr := "10.1.1.100:6379" pass := os.Getenv("REDIS_PASSWORD") if len(os.Args) >= 2 { addr = os.Args[1] } if len(os.Args) >= 3 { pass = os.Args[2] } ctx, cancel := context.WithTimeout(context.Background(), 8*time.Second) defer cancel() r := redis.NewClient(&redis.Options{Addr: addr, Password: pass}) defer r.Close() if err := r.Ping(ctx).Err(); err != nil { fmt.Fprintf(os.Stderr, "连接失败 %s: %v\n", addr, err) os.Exit(1) } s, err := r.Info(ctx, "keyspace").Result() if err != nil { fmt.Fprintf(os.Stderr, "INFO keyspace: %v\n", err) os.Exit(1) } used := make(map[int]int64) for _, line := range strings.Split(s, "\r\n") { line = strings.TrimSpace(line) if line == "" || strings.HasPrefix(line, "#") { continue } if !strings.HasPrefix(line, "db") { continue } colon := strings.IndexByte(line, ':') if colon <= 2 { continue } dbStr := line[2:colon] dbNum, err := strconv.Atoi(dbStr) if err != nil { continue } var keys int64 for _, part := range strings.Split(line[colon+1:], ",") { part = strings.TrimSpace(part) if strings.HasPrefix(part, "keys=") { keys, _ = strconv.ParseInt(strings.TrimPrefix(part, "keys="), 10, 64) break } } used[dbNum] = keys } fmt.Printf("Redis %s — 逻辑库 key 统计(INFO keyspace)\n\n", addr) for i := 0; i < 16; i++ { k, ok := used[i] if !ok { fmt.Printf(" db%-2d : 无记录(通常为 0 个 key / 未写入过)\n", i) } else if k == 0 { fmt.Printf(" db%-2d : 0 keys\n", i) } else { fmt.Printf(" db%-2d : %d keys (已占用)\n", i, k) } } fmt.Println() fmt.Println("说明: Redis 默认 16 个逻辑库(0-15);「无记录」一般可当空闲选用。") fmt.Println("若 redis.conf 里 databases=N,实际库数量可能更大,可用 redis-cli CONFIG GET databases 查看。") }