- SQL 方言层:agent updated_at、dashboard 小时分桶、清理任务跨 SQLite/MySQL - Cache Capabilities:redka 跳过 ZSet/PubSub,Agent 聚合改 DB 直读 - local 模式 redka 初始化失败 Fatal;/version 返回 features - SQLite WAL + 连接池限制;K8s data 改 PVC 持久化 - run.sh:旧参数迁移、升级后 /version 校验
104 lines
2.7 KiB
Go
104 lines
2.7 KiB
Go
// go-redis 外部 Redis 服务器实现
|
|
// 用于 Docker Compose / 生产环境部署 // Logan.Li
|
|
package redis
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"time"
|
|
|
|
goredis "github.com/redis/go-redis/v9"
|
|
)
|
|
|
|
// goRedisCache 基于 go-redis 的缓存实现 // Logan.Li
|
|
type goRedisCache struct {
|
|
client *goredis.Client
|
|
}
|
|
|
|
func newGoRedis(cfg Config) (Cache, error) {
|
|
client := goredis.NewClient(&goredis.Options{
|
|
Addr: fmt.Sprintf("%s:%d", cfg.Host, cfg.Port),
|
|
Password: cfg.Password,
|
|
DB: cfg.DB,
|
|
})
|
|
|
|
// 连接测试
|
|
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
|
|
defer cancel()
|
|
|
|
if err := client.Ping(ctx).Err(); err != nil {
|
|
return nil, fmt.Errorf("redis: 连接失败 %s:%d: %w", cfg.Host, cfg.Port, err)
|
|
}
|
|
|
|
return &goRedisCache{client: client}, nil
|
|
}
|
|
|
|
func (r *goRedisCache) Capabilities() Capabilities {
|
|
return Capabilities{SortedSet: true, PubSub: true}
|
|
}
|
|
|
|
func (r *goRedisCache) Get(ctx context.Context, key string) (string, error) {
|
|
val, err := r.client.Get(ctx, key).Result()
|
|
if err == goredis.Nil {
|
|
return "", nil
|
|
}
|
|
return val, err
|
|
}
|
|
|
|
func (r *goRedisCache) Set(ctx context.Context, key string, value string, expiration time.Duration) error {
|
|
return r.client.Set(ctx, key, value, expiration).Err()
|
|
}
|
|
|
|
func (r *goRedisCache) Del(ctx context.Context, keys ...string) error {
|
|
return r.client.Del(ctx, keys...).Err()
|
|
}
|
|
|
|
func (r *goRedisCache) Exists(ctx context.Context, keys ...string) (int64, error) {
|
|
return r.client.Exists(ctx, keys...).Result()
|
|
}
|
|
|
|
func (r *goRedisCache) Expire(ctx context.Context, key string, expiration time.Duration) error {
|
|
return r.client.Expire(ctx, key, expiration).Err()
|
|
}
|
|
|
|
func (r *goRedisCache) Ping(ctx context.Context) error {
|
|
return r.client.Ping(ctx).Err()
|
|
}
|
|
|
|
func (r *goRedisCache) Close() error {
|
|
return r.client.Close()
|
|
}
|
|
|
|
func (r *goRedisCache) ZAdd(ctx context.Context, key string, member SortedSetMember) error {
|
|
return r.client.ZAdd(ctx, key, goredis.Z{
|
|
Score: member.Score,
|
|
Member: member.Member,
|
|
}).Err()
|
|
}
|
|
|
|
func (r *goRedisCache) ZRangeByScore(ctx context.Context, key string, min, max string) ([]SortedSetMember, error) {
|
|
zs, err := r.client.ZRangeByScoreWithScores(ctx, key, &goredis.ZRangeBy{
|
|
Min: min,
|
|
Max: max,
|
|
}).Result()
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
members := make([]SortedSetMember, len(zs))
|
|
for i, z := range zs {
|
|
members[i] = SortedSetMember{
|
|
Score: z.Score,
|
|
Member: z.Member.(string),
|
|
}
|
|
}
|
|
return members, nil
|
|
}
|
|
|
|
func (r *goRedisCache) ZRemRangeByScore(ctx context.Context, key string, min, max string) error {
|
|
return r.client.ZRemRangeByScore(ctx, key, min, max).Err()
|
|
}
|
|
|
|
func (r *goRedisCache) Publish(ctx context.Context, channel string, message string) error {
|
|
return r.client.Publish(ctx, channel, message).Err()
|
|
}
|