Go 语言使用 Redis

Go 语言使用 Redis,第1张

目录 Go 语言使用 Redis连接到 Redis 客户端一般写 *** 作事务

Go 语言使用 Redis

Redis client for Go

连接到 Redis 客户端

安装

go get github.com/go-redis/redis/v8

连接

import "github.com/go-redis/redis/v8"
// 参数方式连接
rdb := redis.NewClient(&redis.Options{
	Addr:	  "localhost:6379",
	Password: "", // no password set
	DB:		  0,  // use default DB
})

// 连接字符串方式
opt, err := redis.ParseURL("redis://:@localhost:6379/")
if err != nil {
	panic(err)
}

rdb := redis.NewClient(opt)

// 连接 TLS redis
rdb := redis.NewClient(&redis.Options{
	TLSConfig: &tls.Config{
		MinVersion: tls.VersionTLS12,
		//Certificates: []tls.Certificate{cert}
	},
})

如果 TLS 报错模式 x509: cannot validate certificate for xxx.xxx.xxx.xxx because it doesn't contain any IP SANs,设置 ServerName 选项即可

rdb := redis.NewClient(&redis.Options{
	TLSConfig: &tls.Config{
		MinVersion: tls.VersionTLS12,
		ServerName: "your.domain.com",
	},
})

SSH 方式连接

sshConfig := &ssh.ClientConfig{
	User:			 "root",
	Auth:			 []ssh.AuthMethod{ssh.Password("password")},
	HostKeyCallback: ssh.InsecureIgnoreHostKey(),
	Timeout:		 15 * time.Second,
}

sshClient, err := ssh.Dial("tcp", "remoteIP:22", sshConfig)
if err != nil {
	panic(err)
}

rdb := redis.NewClient(&redis.Options{
	Addr: net.JoinHostPort("127.0.0.1", "6379"),
	Dialer: func(ctx context.Context, network, addr string) (net.Conn, error) {
		return sshClient.Dial(network, addr)
	},
	// Disable timeouts, because SSH does not support deadlines.
	ReadTimeout:  -1,
	WriteTimeout: -1,
}) 
一般写 *** 作

go-redis API

// String
err := rdb.Set(ctx, "key", "value", 0).Err()
if err != nil {
    panic(err)
}

// 列表 List
rdb.LPush(ctx, "list", 1, 2, 3)

// 集合
rdb.SAdd(ctx, "team", "kobe", "jordan")
rdb.SAdd(ctx, "team", "curry")
rdb.SAdd(ctx, "team", "kobe")

// hash
rdb.HSet(ctx, "user", "key1", "value1", "key2", "value2")
rdb.HSet(ctx, "user", []string{"key3", "value3", "key4", "value4"})
rdb.HSet(ctx, "user", map[string]interface{}{"key5": "value5", "key6": "value6"})

// 有序集合
rdb.ZAdd(ctx, "zSet", &redis.Z{
    Score:  0,
    Member: 1,
})
rdb.ZAdd(ctx, "zSet", &redis.Z{
    Score:  0,
    Member: 2,
})
rdb.ZAdd(ctx, "zSet", &redis.Z{
    Score:  0,
    Member: 3,
})

// 管道
pipe := rdb.Pipeline()

incr := pipe.Incr(ctx, "pipeline_counter")
pipe.Expire(ctx, "pipeline_counter", time.Hour)

cmds, err := pipe.Exec(ctx)
if err != nil {
	panic(err)
}

// The value is available only after Exec is called.
fmt.Println(incr.Val())

事务

除了通过 Pipeline 开启事务,还可以通过官方提供的 func (c *Client) TxPipelined(ctx context.Context, fn func(Pipeliner) error) ([]Cmder, error) 来开启事务

TxPipelined 是封装 MULTI 和 EXEC 命令的 TxPipeline 管道,看一下 TxPipelineTxPipelined 的例子

// TxPipeline
pipe := rdb.TxPipeline()
defer pipe.Close()

incr := pipe.Incr(ctx, "tx_pipeline_counter")
pipe.Expire(ctx, "tx_pipeline_counter", time.Hour)

// Execute
//
//     MULTI
//     INCR pipeline_counter
//     EXPIRE pipeline_counts 3600
//     EXEC
//
// using one rdb-server roundtrip.
_, err = pipe.Exec(ctx)
if err != nil {
    //取消提交
    pipe.Discard()
}
fmt.Println(incr.Val(), err)

// 事务 TxPipelined
cmds, err := rdb.TxPipelined(ctx, func(pipe redis.Pipeliner) error {
    for i := 0; i < 2; i++ {
        pipe.Get(ctx, fmt.Sprintf("key%d", i))
    }
    return nil
})
// MULTI
// GET key0
// GET key1
// ...
// GET key99
// EXEC

if err != nil {
    panic(err)
}

for _, cmd := range cmds {
    fmt.Println(cmd.(*redis.StringCmd).Val())
}

另外还可以通过 Watch 处理事务管道

// Redis transactions use optimistic locking.
const maxRetries = 1000

// Increment transactionally increments the key using GET and SET commands.
func increment(key string) error {
	// Transactional function.
	txf := func(tx *redis.Tx) error {
		// Get the current value or zero.
		n, err := tx.Get(ctx, key).Int()
		if err != nil && err != redis.Nil {
			return err
		}

		// Actual operation (local in optimistic lock).
		n++

		// Operation is commited only if the watched keys remain unchanged.
		_, err = tx.TxPipelined(ctx, func(pipe redis.Pipeliner) error {
			pipe.Set(ctx, key, n, 0)
			return nil
		})
		return err
	}

    // Retry if the key has been changed.
	for i := 0; i < maxRetries; i++ {
		err := rdb.Watch(ctx, txf, key)
		if err == nil {
			// Success.
			return nil
		}
		if err == redis.TxFailedErr {
			// Optimistic lock lost. Retry.
			continue
		}
		// Return any other error.
		return err
	}

	return errors.New("increment reached maximum number of retries")
}

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/995516.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-21
下一篇 2022-05-21

发表评论

登录后才能评论

评论列表(0条)

保存