redis

package module
v0.0.0-...-02f0996 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: May 24, 2026 License: Apache-2.0 Imports: 9 Imported by: 0

README

Redis Store 扩展包

Redis 存储实现,位于扩展包中,独立管理依赖。

安装

go get github.com/rushteam/reckit/ext/store/redis

基础使用

import (
    "github.com/rushteam/reckit/core"
    redisstore "github.com/rushteam/reckit/ext/store/redis"
)

// 创建 Redis 存储
store, err := redisstore.NewRedisStore("localhost:6379", 0)
if err != nil {
    log.Fatal(err)
}
defer store.Close(ctx)

// 作为 core.Store 使用
var s core.Store = store

布隆过滤器支持

本扩展包提供了基于 Redis + bits-and-blooms/bloom 的布隆过滤器实现,用于曝光过滤器的较长周期数据检查。

使用布隆过滤器
import (
    "context"
    "github.com/rushteam/reckit/core"
    "github.com/rushteam/reckit/filter"
    redisstore "github.com/rushteam/reckit/ext/store/redis"
)

ctx := context.Background()

// 1. 创建 Redis 存储
store, err := redisstore.NewRedisStore("localhost:6379", 0)
if err != nil {
    log.Fatal(err)
}
defer store.Close(ctx)

// 2. 创建布隆过滤器检查器
// 参数说明:
//   - capacity: 1000000 表示预期存储 100 万个元素
//   - falsePositiveRate: 0.01 表示 1% 的误判率
bloomChecker := redisstore.NewRedisBloomFilterChecker(
    store,
    1000000, // 预期容量:100 万
    0.01,    // 误判率:1%
)

// 3. 创建 StoreAdapter(带布隆过滤器检查器)
storeAdapter := filter.NewStoreAdapterWithBloomFilter(store, bloomChecker)

// 4. 创建曝光过滤器
// 参数说明:
//   - storeAdapter: 存储适配器
//   - "user:exposed": key 前缀
//   - 7*24*3600: IDs 列表时间窗口(7天,秒)- 用于近期数据
//   - 30: 布隆过滤器时间窗口(30天)- 用于较长周期数据
exposedFilter := filter.NewExposedFilter(
    storeAdapter,
    "user:exposed",
    7*24*3600, // IDs 列表:7天(近期数据)
    30,        // 布隆过滤器:30天(较长周期数据)
)

// 5. 使用曝光过滤器
rctx := &core.RecommendContext{
    UserID: "user_123",
    Scene:  "feed",
}

item := core.NewItem("item_456")
shouldFilter, _ := exposedFilter.ShouldFilter(ctx, rctx, item)
添加曝光数据到布隆过滤器
import (
    "context"
    "fmt"
    "time"
    redisstore "github.com/rushteam/reckit/ext/store/redis"
)

ctx := context.Background()

// 创建 Redis 存储和布隆过滤器检查器
store, _ := redisstore.NewRedisStore("localhost:6379", 0)
defer store.Close(ctx)

bloomChecker := redisstore.NewRedisBloomFilterChecker(store, 1000000, 0.01)

// 获取当前日期(YYYYMMDD 格式)
now := time.Now()
dateStr := now.Format("20060102")

// key 格式:{keyPrefix}:bloom:{userID}:{date}
userID := "user_123"
itemID := "item_456"
key := fmt.Sprintf("user:exposed:bloom:%s:%s", userID, dateStr)

// 单个添加
err := bloomChecker.AddToBloomFilter(ctx, key, itemID, 0) // ttl=0 表示不过期

// 批量添加
itemIDs := []string{"item_789", "item_101", "item_202"}
err = bloomChecker.BatchAddToBloomFilter(ctx, key, itemIDs, 0)
布隆过滤器参数说明
  • capacity: 预期容量(元素数量)

    • 例如:1000000 表示预期存储 100 万个元素
    • 建议根据实际业务量设置,设置过小可能导致误判率上升
  • falsePositiveRate: 期望的误判率

    • 例如:0.01 表示 1% 的误判率
    • 误判率越低,所需内存越大
    • 常见值:0.01 (1%), 0.001 (0.1%)
布隆过滤器 Key 格式

布隆过滤器的 Redis key 格式为:{keyPrefix}:bloom:{userID}:{date}

  • keyPrefix: 在创建 ExposedFilter 时指定的前缀(例如:"user:exposed"
  • userID: 用户 ID
  • date: 日期,格式为 YYYYMMDD(例如:20260127
性能优化

RedisBloomFilterChecker 内置了本地缓存机制,避免频繁从 Redis 读取和反序列化布隆过滤器数据。如果需要强制刷新缓存,可以调用:

// 清除所有缓存
bloomChecker.ClearCache()

// 清除指定 key 的缓存
bloomChecker.ClearCacheKey(key)

依赖

  • github.com/rushteam/reckit - 核心包(仅接口定义)
  • github.com/redis/go-redis/v9 - Redis 客户端
  • github.com/bits-and-blooms/bloom/v3 - 布隆过滤器实现

自行实现

你也可以参考此实现,自行实现 core.Storecore.KeyValueStorefilter.BloomFilterChecker 接口,满足你的特定需求。

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func ExampleAddToBloomFilter

func ExampleAddToBloomFilter()

ExampleAddToBloomFilter 展示如何将曝光数据添加到布隆过滤器

func ExampleRedisBloomFilter

func ExampleRedisBloomFilter()

ExampleRedisBloomFilter 展示如何使用 Redis + bits-and-blooms/bloom 实现布隆过滤器

Types

type LegacyBloomBatchChecker

type LegacyBloomBatchChecker struct {
	Client            *redis.Client
	Capacity          uint
	FalsePositiveRate float64
}

LegacyBloomBatchChecker 适配 legacy STRING bloom 方案。 读取 rolling slot + :all 到内存后,对整批 item 做纯内存判定。

func NewLegacyBloomBatchChecker

func NewLegacyBloomBatchChecker(client *redis.Client, capacity uint, falsePositiveRate float64) *LegacyBloomBatchChecker

func (*LegacyBloomBatchChecker) CheckExposedBatch

func (c *LegacyBloomBatchChecker) CheckExposedBatch(
	ctx context.Context,
	userID string,
	itemIDs []string,
	keyPrefix string,
	_ int64,
	dayWindow int,
) (map[string]bool, error)

type RedisBloomFilterChecker

type RedisBloomFilterChecker struct {
	// contains filtered or unexported fields
}

func NewRedisBloomFilterChecker

func NewRedisBloomFilterChecker(store *RedisStore, capacity uint, falsePositiveRate float64) *RedisBloomFilterChecker

NewRedisBloomFilterChecker 创建一个新的 Redis 布隆过滤器检查器。

参数:

  • store: RedisStore 实例
  • capacity: 预期容量(元素数量),例如 1000000 表示预期存储 100 万个元素
  • falsePositiveRate: 期望的误判率,例如 0.01 表示 1% 的误判率

示例:

store, _ := NewRedisStore("localhost:6379", 0)
checker := NewRedisBloomFilterChecker(store, 1000000, 0.01)

func NewRedisBloomFilterCheckerWithClient

func NewRedisBloomFilterCheckerWithClient(client *redis.Client, capacity uint, falsePositiveRate float64) *RedisBloomFilterChecker

NewRedisBloomFilterCheckerWithClient 使用 *redis.Client 创建布隆过滤器检查器(高级用法)。 如果已有 *redis.Client 实例,可以使用此方法。

func (*RedisBloomFilterChecker) AddToBloomFilter

func (r *RedisBloomFilterChecker) AddToBloomFilter(ctx context.Context, key string, itemID string, ttl int) error

AddToBloomFilter 将 itemID 添加到指定 key 的布隆过滤器中。 这是一个辅助方法,用于数据写入场景(例如曝光数据收集)。

参数:

  • ctx: 上下文
  • key: 布隆过滤器的 Redis key
  • itemID: 要添加的物品 ID
  • ttl: 过期时间(秒),0 表示不过期

返回:

  • error: 错误信息

func (*RedisBloomFilterChecker) BatchAddToBloomFilter

func (r *RedisBloomFilterChecker) BatchAddToBloomFilter(ctx context.Context, key string, itemIDs []string, ttl int) error

BatchAddToBloomFilter 批量将 itemIDs 添加到指定 key 的布隆过滤器中。 这是一个辅助方法,用于批量数据写入场景。

参数:

  • ctx: 上下文
  • key: 布隆过滤器的 Redis key
  • itemIDs: 要添加的物品 ID 列表
  • ttl: 过期时间(秒),0 表示不过期

返回:

  • error: 错误信息

func (*RedisBloomFilterChecker) CheckInBloomFilter

func (r *RedisBloomFilterChecker) CheckInBloomFilter(ctx context.Context, key string, itemID string) (bool, error)

CheckInBloomFilter 检查 itemID 是否在指定 key 的布隆过滤器中。 实现了 filter.BloomFilterChecker 接口。

参数:

  • ctx: 上下文
  • key: 布隆过滤器的 Redis key,格式为 {keyPrefix}:bloom:{userID}:{date}
  • itemID: 要检查的物品 ID

返回:

  • bool: true 表示可能在布隆过滤器中(存在误判可能),false 表示一定不在
  • error: 错误信息

func (*RedisBloomFilterChecker) ClearCache

func (r *RedisBloomFilterChecker) ClearCache()

ClearCache 清除本地缓存。 当需要强制从 Redis 重新加载布隆过滤器时使用。

func (*RedisBloomFilterChecker) ClearCacheKey

func (r *RedisBloomFilterChecker) ClearCacheKey(key string)

ClearCacheKey 清除指定 key 的本地缓存。

type RedisStore

type RedisStore struct {
	// contains filtered or unexported fields
}

RedisStore 是 Redis 实现的 KeyValueStore,支持所有 Redis 数据结构操作。 生产环境常用,支持持久化、集群、哨兵等。

注意:此实现位于扩展包中,需要单独引入:

go get github.com/rushteam/reckit/ext/store/redis

func NewRedisStore

func NewRedisStore(addr string, db int) (*RedisStore, error)

NewRedisStore 创建一个新的 Redis 存储实例。

func (*RedisStore) BatchGet

func (r *RedisStore) BatchGet(ctx context.Context, keys []string) (map[string][]byte, error)

func (*RedisStore) BatchSet

func (r *RedisStore) BatchSet(ctx context.Context, kvs map[string][]byte, ttl ...int) error

func (*RedisStore) Close

func (r *RedisStore) Close(ctx context.Context) error

func (*RedisStore) Delete

func (r *RedisStore) Delete(ctx context.Context, key string) error

func (*RedisStore) Get

func (r *RedisStore) Get(ctx context.Context, key string) ([]byte, error)

func (*RedisStore) GetClient

func (r *RedisStore) GetClient() *redis.Client

GetClient 返回内部的 Redis 客户端(用于高级用法,如布隆过滤器)。 注意:此方法仅用于需要直接访问 Redis 客户端的场景。

func (*RedisStore) HGet

func (r *RedisStore) HGet(ctx context.Context, key, field string) ([]byte, error)

func (*RedisStore) HGetAll

func (r *RedisStore) HGetAll(ctx context.Context, key string) (map[string][]byte, error)

func (*RedisStore) HSet

func (r *RedisStore) HSet(ctx context.Context, key, field string, value []byte) error

func (*RedisStore) Name

func (r *RedisStore) Name() string

func (*RedisStore) Set

func (r *RedisStore) Set(ctx context.Context, key string, value []byte, ttl ...int) error

func (*RedisStore) ZAdd

func (r *RedisStore) ZAdd(ctx context.Context, key string, score float64, member string) error

func (*RedisStore) ZRange

func (r *RedisStore) ZRange(ctx context.Context, key string, start, stop int64) ([]string, error)

func (*RedisStore) ZRangeWithScores

func (r *RedisStore) ZRangeWithScores(ctx context.Context, key string, start, stop int64) ([]core.ScoredMember, error)

func (*RedisStore) ZRevRangeWithScores

func (r *RedisStore) ZRevRangeWithScores(ctx context.Context, key string, start, stop int64) ([]core.ScoredMember, error)

func (*RedisStore) ZScore

func (r *RedisStore) ZScore(ctx context.Context, key string, member string) (float64, error)

type TairBloomBatchChecker

type TairBloomBatchChecker struct {
	Client *redis.Client
}

TairBloomBatchChecker 适配 TairBloom BF.MEXISTS 方案。 通过 pipeline 一次 round-trip 完成多 slot 检查。

func NewTairBloomBatchChecker

func NewTairBloomBatchChecker(client *redis.Client) *TairBloomBatchChecker

func (*TairBloomBatchChecker) CheckExposedBatch

func (c *TairBloomBatchChecker) CheckExposedBatch(
	ctx context.Context,
	userID string,
	itemIDs []string,
	keyPrefix string,
	_ int64,
	dayWindow int,
) (map[string]bool, error)

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL