golang类型安全可定制化的Redis客户端插件库xredis的使用

golang类型安全可定制化的Redis客户端插件库xredis的使用

xredis是一个基于github.com/garyburd/redigo构建的Redis客户端库,旨在简化Redis客户端的创建,提供类型安全的调用,并封装底层细节以便轻松集成Redis。

特性

  • 类型安全客户端
  • 易于设置:
    • 使用默认客户端
    • 通过设置选项自定义客户端
    • 使用redigo的redis.Pool
  • 自动提供连接池
  • 支持Redis哨兵:
    • 写入操作发送到主节点
    • 读取操作发送到从节点,如果没有可用从节点则回退到主节点
  • 支持多种Redis命令(ECHO、INFO、PING、SET、GET、HSET、HGET等)
  • 完全访问Redigo的API

依赖

示例

示例1:使用DefaultClient创建默认Redis客户端

package main

import (
	"fmt"
	"github.com/shomali11/xredis"
)

func main() {
	client := xredis.DefaultClient()
	defer client.Close()

	fmt.Println(client.Ping()) // PONG <nil>
}

默认选项:

defaultHost                  = "localhost"
defaultPort                  = 6379
defaultPassword              = ""
defaultDatabase              = 0
defaultNetwork               = "tcp"
defaultConnectTimeout        = time.Second
defaultWriteTimeout          = time.Second
defaultReadTimeout           = time.Second
defaultConnectionIdleTimeout = 240 * time.Second
defaultConnectionMaxIdle     = 100
defaultConnectionMaxActive   = 10000
defaultConnectionWait        = false
defaultTlsConfig             = nil
defaultTlsSkipVerify         = false
defaultTestOnBorrowTimeout   = time.Minute

示例2:使用SetupClient创建自定义Redis客户端

package main

import (
	"fmt"
	"github.com/shomali11/xredis"
)

func main() {
	options := &xredis.Options{
		Host: "localhost",
		Port: 6379,
	}

	client := xredis.SetupClient(options)
	defer client.Close()

	fmt.Println(client.Ping()) // PONG <nil>
}

可用选项:

type Options struct {
	Host                  string
	Port                  int
	Password              string
	Database              int
	Network               string
	ConnectTimeout        time.Duration
	WriteTimeout          time.Duration
	ReadTimeout           time.Duration
	ConnectionIdleTimeout time.Duration
	ConnectionMaxIdle     int
	ConnectionMaxActive   int
	ConnectionWait        bool
	TlsConfig             *tls.Config
	TlsSkipVerify         bool
	TestOnBorrowPeriod    time.Duration
}

示例3:使用SetupSentinelClient创建Redis哨兵客户端

package main

import (
	"fmt"
	"github.com/shomali11/xredis"
)

func main() {
	options := &xredis.SentinelOptions{
		Addresses:  []string{"localhost:26379"},
		MasterName: "master",
	}

	client := xredis.SetupSentinelClient(options)
	defer client.Close()

	fmt.Println(client.Ping()) // PONG <nil>
}

示例4:使用NewClient通过redis.Pool创建Redis客户端

package main

import (
	"fmt"
	"github.com/garyburd/redigo/redis"
	"github.com/shomali11/xredis"
)

func main() {
	pool := &redis.Pool{
		Dial: func() (redis.Conn, error) {
			return redis.Dial("tcp", "localhost:6379")
		},
	}

	client := xredis.NewClient(pool)
	defer client.Close()

	fmt.Println(client.Ping()) // PONG <nil>
}

示例5:使用Ping、Echo和Info命令

package main

import (
	"fmt"
	"github.com/shomali11/xredis"
)

func main() {
	client := xredis.DefaultClient()
	defer client.Close()

	fmt.Println(client.Ping())         // PONG <nil>
	fmt.Println(client.Echo("Hello"))  // Hello <nil>
	fmt.Println(client.FlushDb())      // <nil>
	fmt.Println(client.FlushAll())     // <nil>
	fmt.Println(client.Info())         
}

示例6:使用SET、GET、DEL等命令

package main

import (
	"fmt"
	"github.com/shomali11/xredis"
)

func main() {
	client := xredis.DefaultClient()
	defer client.Close()

	fmt.Println(client.Set("name", "Raed Shomali")) // true <nil>
	fmt.Println(client.SetNx("name", "Hello"))      // false <nil>
	fmt.Println(client.SetEx("id", "10", 1))        // true <nil>
	fmt.Println(client.Expire("name", 1))           // true <nil>
	fmt.Println(client.Expire("unknown", 1))        // false <nil>
	fmt.Println(client.Keys("*"))                   // [id name] <nil>
	fmt.Println(client.Get("name"))                 // "Raed Shomali" true <nil>
	fmt.Println(client.Exists("name"))              // true <nil>
	fmt.Println(client.Del("name"))                 // 1 <nil>
	fmt.Println(client.Exists("name"))              // false <nil>
	fmt.Println(client.Get("name"))                 // "" false <nil>
	fmt.Println(client.Del("name"))                 // 0 <nil>
	fmt.Println(client.Append("name", "a"))         // 1 <nil>
	fmt.Println(client.Append("name", "b"))         // 2 <nil>
	fmt.Println(client.Append("name", "c"))         // 3 <nil>
	fmt.Println(client.Get("name"))                 // "abc" true <nil>
	fmt.Println(client.GetRange("name", 0 , 1))     // "ab" <nil>
	fmt.Println(client.SetRange("name", 2, "xyz"))  // 5 <nil>
	fmt.Println(client.Get("name"))                 // "abxyz" <nil>
	fmt.Println(client.Scan(0, "*"))                // 0 [name id] <nil>
	fmt.Println(client.Del("id", "name"))           // 2 <nil>
}

示例7:使用INCR、DECR等命令

package main

import (
	"fmt"
	"github.com/shomali11/xredis"
)

func main() {
	client := xredis.DefaultClient()
	defer client.Close()

	fmt.Println(client.Set("integer", "10"))       // true <nil>
	fmt.Println(client.Set("float", "5.5"))        // true <nil>

	fmt.Println(client.Get("integer"))             // 10 true <nil>
	fmt.Println(client.Get("float"))               // 5.5 true <nil>

	fmt.Println(client.Incr("integer"))            // 11 <nil>
	fmt.Println(client.IncrBy("integer", 10))      // 21 <nil>
	fmt.Println(client.DecrBy("integer", 5))       // 16 <nil>
	fmt.Println(client.Decr("integer"))            // 15 <nil>

	fmt.Println(client.IncrByFloat("float", 3.3))  // 8.8 <nil>
	fmt.Println(client.DecrByFloat("float", 1.1))  // 7.7 <nil>

	fmt.Println(client.Get("integer"))             // 15 true <nil>
	fmt.Println(client.Get("float"))               // 7.7 true <nil>

	fmt.Println(client.Del("integer", "float"))    // 2 <nil>
}

示例8:使用HSET、HGET等哈希命令

package main

import (
	"fmt"
	"github.com/shomali11/xredis"
)

func main() {
	client := xredis.DefaultClient()
	defer client.Close()

	fmt.Println(client.HSet("hash", "name", "Raed Shomali")) // true <nil>
	fmt.Println(client.HSet("hash", "sport", "Football"))    // true <nil>
	fmt.Println(client.HKeys("hash"))                        // [name sport] <nil>
	fmt.Println(client.HScan("hash", 0, "*"))                // 0 [name Raed Shomali sport Football] <nil>
	fmt.Println(client.HGet("hash", "name"))                 // "Raed Shomali" true <nil>
	fmt.Println(client.HGetAll("hash"))                      // map[name:Raed Shomali sport:Football] <nil>
	fmt.Println(client.HExists("hash", "name"))              // true <nil>
	fmt.Println(client.HDel("hash", "name", "sport"))        // 2 <nil>
	fmt.Println(client.HGet("hash", "name"))                 // "" false <nil>
	fmt.Println(client.HExists("hash", "name"))              // false <nil>
	fmt.Println(client.HGetAll("hash"))                      // map[] nil
	fmt.Println(client.HDel("hash", "name"))                 // 0 <nil>
	fmt.Println(client.HKeys("hash"))                        // [] <nil>
}

示例9:使用HINCR、HDECR等哈希命令

package main

import (
	"fmt"
	"github.com/shomali11/xredis"
)

func main() {
	client := xredis.DefaultClient()
	defer client.Close()

	fmt.Println(client.HSet("hash", "integer", "10"))       // true <nil>
	fmt.Println(client.HSet("hash", "float", "5.5"))        // true <nil>

	fmt.Println(client.HIncr("hash", "integer"))            // 11 <nil>
	fmt.Println(client.HIncrBy("hash", "integer", 10))      // 21 <nil>
	fmt.Println(client.HDecrBy("hash", "integer", 5))       // 16 <nil>
	fmt.Println(client.HDecr("hash", "integer"))            // 15 <nil>

	fmt.Println(client.HIncrByFloat("hash", "float", 3.3))  // 8.8 <nil>
	fmt.Println(client.HDecrByFloat("hash", "float", 1.1))  // 7.7 <nil>

	fmt.Println(client.HDel("hash", "integer", "float"))    // 2 <nil>
}

示例10:直接访问Redigo API

package main

import (
	"fmt"
	"github.com/garyburd/redigo/redis"
	"github.com/shomali11/xredis"
)

func main() {
	client := xredis.DefaultClient()
	defer client.Close()

	connection := client.GetConnection()
	defer connection.Close()

	fmt.Println(redis.String(connection.Do("INFO")))
}

更多关于golang类型安全可定制化的Redis客户端插件库xredis的使用的实战教程也可以访问 https://www.itying.com/category-94-b0.html

1 回复

更多关于golang类型安全可定制化的Redis客户端插件库xredis的使用的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


xredis - Golang类型安全可定制化的Redis客户端插件库

xredis是一个为Golang设计的类型安全且高度可定制的Redis客户端库,它在标准Redis客户端基础上提供了更严格的类型检查和灵活的扩展能力。

主要特性

  1. 类型安全:所有Redis操作都带有类型检查
  2. 可定制化:可以轻松扩展和修改命令行为
  3. 链式调用:提供流畅的API设计
  4. 上下文支持:支持context.Context传递
  5. 连接池管理:内置高效的连接池

安装

go get github.com/xxx/xredis

基本使用示例

package main

import (
	"context"
	"fmt"
	"github.com/xxx/xredis"
)

func main() {
	// 创建xredis客户端
	client := xredis.NewClient(&xredis.Options{
		Addr:     "localhost:6379",
		Password: "", // 无密码
		DB:       0,  // 默认DB
	})

	ctx := context.Background()

	// 设置字符串值
	err := client.Set(ctx, "key", "value", 0).Err()
	if err != nil {
		panic(err)
	}

	// 获取字符串值
	val, err := client.Get(ctx, "key").Result()
	if err != nil {
		panic(err)
	}
	fmt.Println("key", val)

	// 设置带过期时间的键
	err = client.SetEX(ctx, "temp_key", "temp_value", 10*time.Second).Err()
	
	// 哈希表操作
	err = client.HSet(ctx, "user:1", map[string]interface{}{
		"name":  "John",
		"age":   30,
		"email": "john@example.com",
	}).Err()
	
	// 获取哈希表字段
	name, err := client.HGet(ctx, "user:1", "name").String()
	age, err := client.HGet(ctx, "user:1", "age").Int()
	
	// 管道操作
	pipe := client.Pipeline()
	pipe.Set(ctx, "pipe1", "value1", 0)
	pipe.Set(ctx, "pipe2", "value2", 0)
	_, err = pipe.Exec(ctx)
}

高级特性

1. 自定义命令

// 定义自定义命令
func (c *Client) MyCustomCommand(ctx context.Context, key string, value interface{}) *xredis.StringCmd {
	cmd := xredis.NewStringCmd(ctx, "MYCUSTOM", key, value)
	c.Process(ctx, cmd)
	return cmd
}

// 使用自定义命令
result, err := client.MyCustomCommand(ctx, "mykey", "myvalue").Result()

2. 中间件支持

// 定义中间件
func loggingMiddleware(next xredis.HandlerFunc) xredis.HandlerFunc {
	return func(ctx context.Context, cmd xredis.Cmder) error {
		start := time.Now()
		err := next(ctx, cmd)
		duration := time.Since(start)
		
		fmt.Printf("cmd=%s, args=%v, duration=%s, err=%v\n",
			cmd.Name(), cmd.Args(), duration, err)
		return err
	}
}

// 应用中间件
client.WrapProcess(loggingMiddleware)

3. 类型安全操作

// 获取整数
count, err := client.Get(ctx, "counter").Int64()

// 获取布尔值
enabled, err := client.Get(ctx, "feature_enabled").Bool()

// 获取浮点数
price, err := client.Get(ctx, "product_price").Float64()

// 获取时间
expireAt, err := client.Get(ctx, "expire_at").Time()

4. 连接池配置

client := xredis.NewClient(&xredis.Options{
	Addr:     "localhost:6379",
	Password: "",
	DB:       0,
	PoolSize:     100,           // 连接池大小
	MinIdleConns: 10,            // 最小空闲连接数
	MaxConnAge:   30 * time.Minute, // 连接最大存活时间
})

最佳实践

  1. 重用客户端:xredis客户端是线程安全的,应该重用而不是频繁创建销毁
  2. 使用上下文:传递context以便实现超时和取消
  3. 合理配置连接池:根据应用负载调整连接池大小
  4. 错误处理:始终检查命令执行错误
  5. 使用管道:批量操作时使用管道减少网络往返

性能考虑

xredis在标准Redis客户端基础上增加的类型安全层带来的开销极小,几乎可以忽略不计。主要的性能影响来自于:

  1. 连接池配置
  2. 网络延迟
  3. Redis服务器性能

通过合理配置连接池和使用管道,可以最大化性能。

xredis为Golang开发者提供了一个既安全又灵活的Redis客户端解决方案,特别适合需要严格类型检查和自定义扩展的中大型项目。

回到顶部