gredis采用接口化设计,具有强大的灵活性和扩展性。

接口定义

https://pkg.go.dev/github.com/gogf/gf/v2/database/gredis#Adapter

相关方法

// SetAdapter sets custom adapter for current redis client.
func (r *Redis) SetAdapter(adapter Adapter) 

// GetAdapter returns the adapter that is set in current redis client.
func (r *Redis) GetAdapter() Adapter

自实现Redis Adapter

框架社区组件提供了Redis Adapter的默认实现,如果开发者需要自实现Redis Adapter或者想要覆盖其中的某一些方法,可以基于该实现来扩展。

我们来看一个例子,在该例子中,我们实现一个自定义的Redis Adapter,并且覆盖它的Do底层方法。为简化示例,我们这里在自实现的Do方法中打印一条日志即可,后续逻辑仍然走社区Redis Adapter的实现。

package main

import (
	"context"
	"fmt"

	"github.com/gogf/gf/contrib/nosql/redis/v2"

	"github.com/gogf/gf/v2/container/gvar"
	"github.com/gogf/gf/v2/database/gredis"
	"github.com/gogf/gf/v2/frame/g"
	"github.com/gogf/gf/v2/os/gctx"
)

var (
	ctx    = gctx.New()
	group  = "cache"
	config = gredis.Config{
		Address: "127.0.0.1:6379",
		Db:      1,
	}
)

// MyRedis description
type MyRedis struct {
	*redis.Redis
}

// Do implements and overwrites the underlying function Do from Adapter.
func (r *MyRedis) Do(ctx context.Context, command string, args ...interface{}) (*gvar.Var, error) {
	fmt.Println("MyRedis Do:", command, args)
	return r.Redis.Do(ctx, command, args...)
}

func main() {
	gredis.RegisterAdapterFunc(func(config *gredis.Config) gredis.Adapter {
		r := &MyRedis{redis.New(config)}
		r.AdapterOperation = r // This is necessary.
		return r
	})
	gredis.SetConfig(&config, group)

	_, err := g.Redis(group).Set(ctx, "key", "value")
	if err != nil {
		g.Log().Fatal(ctx, err)
	}
	value, err := g.Redis(group).Get(ctx, "key")
	if err != nil {
		g.Log().Fatal(ctx, err)
	}
	fmt.Println(value.String())
}

 执行后,终端输出:

MyRedis Do: Set [key value]
MyRedis Do: Get [key]
value




Content Menu

  • No labels

3 Comments

  1. 问题:现在我需要给Redis操作进行打点,切入日志、Prometheus业务指标采集。看完文档与源码,在gredis层面只能通过自定义Adapter,在创建redis client的时候添加Hook实现,除了这种还有其他方式吗?

    1. 可以参考数据库ORM的Driver实现,"继承"新版本的社区组件Adapter实现,自己覆盖底层的Do方法打点即可,不过可能需要改进下社区组件内部实现把接口对象传递进去(目前内部调用的Do没法覆盖)。

  2. 我应该如何获取底层的 go-redis 实例?我看了下源码似乎没找到获取的方式,请问如何能实现? 郭强