Golang扫描并删除Redis中没有设置过期时间的Key

在使用 Redis 做缓存时,会遇到一些没有设置过期时间的 Key,这些 Key 会一直存在于 Redis 中,导致 Redis 的内存占用越来越高,影响 Redis 的性能。

问题描述

在使用 Redis 做缓存时,会遇到一些没有设置过期时间的 Key,这些 Key 会一直存在于 Redis 中,导致 Redis 的内存占用越来越高,影响 Redis 的性能。

解决方案

使用 Golang 扫描 Redis 中的 Key,判断 Key 是否有过期时间,如果没有过期时间,则删除 Key。

代码实现

使用 Golang 的 Redis 客户端库,扫描 Redis 中的 Key,判断 Key 是否有过期时间,如果没有过期时间,则删除 Key。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
package main

import (
	"context"
	"fmt"
	"strings"
	"time"

	redisV8 "github.com/go-redis/redis/v8"
)

type RedisConfig struct {
	Host           string `json:"host"`
	Port           string `json:"port"`
	Password       string `json:"password"`
	DB             int    `json:"db"`
	ConnectTimeout int    `json:"connect_timeout"`
	ReadTimeout    int    `json:"read_timeout"`
	WriteTimeout   int    `json:"write_timeout"`
}

func InitRedis() *redisV8.Client {
	redisConfig := &RedisConfig{}
	return redisV8.NewClient(&redisV8.Options{
		DB:           redisConfig.DB,
		Addr:         fmt.Sprintf("%s:%s", redisConfig.Host, redisConfig.Port),
		DialTimeout:  time.Duration(redisConfig.ConnectTimeout*1000) * time.Millisecond,
		ReadTimeout:  time.Duration(redisConfig.ReadTimeout*1000) * time.Millisecond,
		WriteTimeout: time.Duration(redisConfig.WriteTimeout*1000) * time.Millisecond,
		Password:     redisConfig.Password,
	})
}

func main() {

	redisClient := InitRedis()

	var cursor uint64

	for {
		time.Sleep(time.Second * 1)

		var keys []string
		var err error

		keys, cursor, err = redisClient.Scan(context.TODO(), cursor, "", 1000).Result()
		if err != nil {
			fmt.Println("encounter err when checking scan with " + err.Error())
			continue
		}

		for _, key := range keys {
			handleKey(redisClient, key)
		}
		if cursor == 0 {
			break
		}
	}
}

func handleKey(client *redisV8.Client, key string) string {
	if ttl, err := client.TTL(context.TODO(), key).Result(); err == nil {
		if ttl.Seconds() < 0 && ttl.Seconds() == -1 {
			deleteResult, _ := client.Del(context.TODO(), key).Result()
			return 
		}
	}
}
使用 Hugo 构建
主题 StackJimmy 设计