使用go-redisredis依赖 *** 作redis

使用go-redisredis依赖 *** 作redis,第1张

文章目录 使用go-redis/redis依赖 *** 作redis一、go-redis/redis(v6.15.9)1.redis依赖安装2.redid.Z结构体3.cmdable接口3.1接口3.2ZAdd方法3.3ZIncrBy方法3.4ZRevRangeWithScores方法3.5ZRangeByScoreWithScores方法3.6Incr方法 4.redsi.Pipeliner接口5.redis.Client结构体5.1结构体5.2TxPipeline方法 6.redis.baseClient结构体6.1结构体6.2Do方法 7.redis.IntCmd结构体7.1结构体7.2Result方法 8.redis.FloatCmd结构体8.1结构体8.2Result方法 9.redis.ZSliceCmd结构体9.1结构体9.2Result方法 10.baseCmd结构体11.redis.ZRangeBy结构体12.sortedset有序集合zadd *** 作13.事务示例114.事务示例2 二、go-redis/redis(v8)1.redis依赖安装2.redis.NewClient函数3.redis.Client结构体3.1结构体3.2Do方法3.3TxPipeline方法 4.redis.Pipeliner接口5.redis.Cmd结构体6.baseCmd结构体6.1结构体6.2Err()方法 7.redis.StringCmd结构体7.1结构体7.2Val方法7.3Result方法 8.redis.StatusCmd结构体8.1结构体8.2Result方法 9.redis.StringSliceCmd结构体9.1结构体9.2Result()方法 10.redis.ScanCmd结构体11.1结构体11.2Iterator方法 12.redis.ScanIterator结构体12.1结构体12.2Next方法 13.redis.IntCmd结构体13.1结构体 14.cmdable类型14.1类型14.2Set方法14.3Get方法14.4Ping方法14.5Keys方法14.6Scan方法14.7Del方法 15.NewClusterClient函数16.NewFailoverClient函数17.String类型Set、Get单 *** 作18.根据前缀获取Key19.执行自定义命令20.按通配符删除key21.连接redis集群22.连接Redis哨兵模式

使用go-redis/redis依赖 *** 作redis 一、go-redis/redis(v6.15.9) 1.redis依赖安装
go get -u github.com/go-redis/redis
// 声明一个全局的rdb变量
var rdb *redis.Client

// 初始化连接
func initClient() (err error) {
	rdb = redis.NewClient(&redis.Options{
		Addr:     "localhost:6379",
		Password: "", // no password set
		DB:       0,  // use default DB
	})

	_, err = rdb.Ping().Result()
	if err != nil {
		return err
	}
	return nil
}

2.redid.Z结构体
type Z struct {
	Score  float64
	Member interface{}
}
3.cmdable接口 3.1接口
//这个接口有很多方法
type Cmdable interface {
	Pipeline() Pipeliner
	Pipelined(fn func(Pipeliner) error) ([]Cmder, error)

	TxPipelined(fn func(Pipeliner) error) ([]Cmder, error)
	TxPipeline() Pipeliner

	Command() *CommandsInfoCmd
	ClientGetName() *StringCmd
	Echo(message interface{}) *StringCmd
	Ping() *StatusCmd
	.............
	}
3.2ZAdd方法
func (c *cmdable) ZAdd(key string, members ...Z) *IntCmd {}
3.3ZIncrBy方法
func (c *cmdable) ZIncrBy(key string, increment float64, member string) *FloatCmd {}
3.4ZRevRangeWithScores方法
func (c *cmdable) ZRevRangeWithScores(key string, start, stop int64) *ZSliceCmd {}
3.5ZRangeByScoreWithScores方法
func (c *cmdable) ZRangeByScoreWithScores(key string, opt ZRangeBy) *ZSliceCmd {
3.6Incr方法
func (c *cmdable) Incr(key string) *IntCmd {}
4.redsi.Pipeliner接口
type Pipeliner interface {
   StatefulCmdable
   Do(args ...interface{}) *Cmd
   Process(cmd Cmder) error
   Close() error
   Discard() error
   Exec() ([]Cmder, error)
}
5.redis.Client结构体 5.1结构体
type Client struct {
	baseClient
	cmdable

	ctx context.Context
}
5.2TxPipeline方法
func (c *Client) TxPipeline() Pipeliner {}
6.redis.baseClient结构体 6.1结构体

type baseClient struct {
	opt      *Options
	connPool pool.Pooler
	limiter  Limiter

	process           func(Cmder) error
	processPipeline   func([]Cmder) error
	processTxPipeline func([]Cmder) error

	onClose func() error // hook called when client is closed
}
6.2Do方法
func (c *baseClient) Do(args ...interface{}) *Cmd {
7.redis.IntCmd结构体 7.1结构体
type IntCmd struct {
	baseCmd
	val int64
}

7.2Result方法
func (cmd *IntCmd) Result() (int64, error) {
	return cmd.val, cmd.err
}
8.redis.FloatCmd结构体 8.1结构体
type FloatCmd struct {
	baseCmd

	val float64
}
8.2Result方法
func (cmd *FloatCmd) Result() (float64, error) {
	return cmd.Val(), cmd.Err()
}
9.redis.ZSliceCmd结构体 9.1结构体
type ZSliceCmd struct {
	baseCmd
	val []Z
}
9.2Result方法
func (cmd *ZSliceCmd) Result() ([]Z, error) {
	return cmd.val, cmd.err
}
10.baseCmd结构体
type baseCmd struct {
	_args []interface{}
	err   error
	_readTimeout *time.Duration
}
11.redis.ZRangeBy结构体
type ZRangeBy struct {
	Min, Max      string
	Offset, Count int64
}
12.sortedset有序集合zadd *** 作
package main

import (
	"fmt"
	"github.com/go-redis/redis"
)

// 声明一个全局的rdb变量
var rdb *redis.Client

// 初始化连接
func initClient() (err error) {
	rdb = redis.NewClient(&redis.Options{
		Addr:     "localhost:6379",
		Password: "", // no password set
		DB:       0,  // use default DB
	})
	//Ping返回的是:*StatusCmd ; Result方法是StatusCmd结构体的方法(StatusCmd的val, baseCmd的err)
	_, err = rdb.Ping().Result()
	if err != nil {
		return err
	}
	return nil
}
func redisExample2() {
	if err := initClient(); err != nil {
		return
	}
	zsetKey := "language_rank"
	languages := []redis.Z{
		redis.Z{Score: 90.0, Member: "Golang"},
		redis.Z{Score: 98.0, Member: "Java"},
		redis.Z{Score: 95.0, Member: "Python"},
		redis.Z{Score: 97.0, Member: "JavaScript"},
		redis.Z{Score: 99.0, Member: "C/C++"},
	}
	// ZADD
	num, err := rdb.ZAdd(zsetKey, languages...).Result()
	if err != nil {
		fmt.Printf("zadd failed, err:%v\n", err)
		return
	}
	fmt.Printf("zadd %d succ.\n", num)//输出:zadd 5 succ.

	// 把Golang的分数加10
	newScore, err := rdb.ZIncrBy(zsetKey, 10.0, "Golang").Result()
	if err != nil {
		fmt.Printf("zincrby failed, err:%v\n", err)
		return
	}
	fmt.Printf("Golang's score is %f now.\n", newScore)//输出:Golang's score is 100.000000 now.

	// 取分数最高的3个;
	ret, err := rdb.ZRevRangeWithScores(zsetKey, 0, 2).Result()
	if err != nil {
		fmt.Printf("zrevrange failed, err:%v\n", err)
		/*输出:Golang 100
			C/C++ 99
			Java 98*/
		return
	}
	for _, z := range ret {
		fmt.Println(z.Member, z.Score)
	}

	// 取95~100分的
	op := redis.ZRangeBy{
		Min: "95",
		Max: "100",
	}
	ret, err = rdb.ZRangeByScoreWithScores(zsetKey, op).Result()
	if err != nil {
		fmt.Printf("zrangebyscore failed, err:%v\n", err)
		
		return
	}
	for _, z := range ret {
		fmt.Println(z.Member, z.Score)
		/*输出:
		Python 95
		JavaScript 97
		Java 98
		C/C++ 99
		Golang 100*/
	}
}
func main() {
	redisExample2()
	/*输出:
	zadd 5 succ.
	Golang's score is 100.000000 now.
	Golang 100
	C/C++ 99
	Java 98
	Python 95
	JavaScript 97
	Java 98
	C/C++ 99
	Golang 100

	*/
}

13.事务示例1

Redis是单线程的,因此单个命令始终是原子的,但是来自不同客户端的两个给定命令可以依次执行,例如在它们之间交替执行。但是,Multi/exec能够确保在multi/exec两个语句之间的命令之间没有其他客户端正在执行命令。
在这种场景我们需要使用TxPipeline。TxPipeline总体上类似于上面的Pipeline,但是它内部会使用MULTI/EXEC包裹排队的命令

package main

import (
	"fmt"
	"github.com/go-redis/redis"
)

// 声明一个全局的rdb变量
var rdb *redis.Client

// 初始化连接
func initClient() (err error) {
	rdb = redis.NewClient(&redis.Options{
		Addr:     "localhost:6379",
		Password: "", // no password set
		DB:       0,  // use default DB
	})

	_, err = rdb.Ping().Result()
	if err != nil {
		return err
	}
	return nil
}
func V8Example() {
	initClient()
    //Do是baseClient结构体的方法
	rdb.Do("set", "key8", "value8")
    //Client结构体里面有cmdable结构体
    //Keys是cmable结构体的方法,返回*StringSliceCmd
    // Result是StringSliceCmd结构体的方法
	vals, _ := rdb.Keys("k*").Result()
	fmt.Println(vals) //输出:[key8]
     //返回的是Pipeliner接口
	pipe := rdb.TxPipeline() //相当于MULTI开启事务
    //Pipeliner接口里定义有Do这个方法
	pipe.Do("set", "key8", "value8")
	pipe.Do("set", "key9", "value9")
    
	vals1, _ := rdb.Keys("k*").Result()
	fmt.Println(vals1) //输出:[key8]
	vals2, _ := pipe.Keys("k*").Result()
	fmt.Println(vals2) //输出:[]
    //Pipeliner接口里定义有Exec这个方法
	pipe.Exec() ///相当于EXEC事务

	vals3, _ := rdb.Keys("k*").Result()
	fmt.Println(vals3) //输出[key8 key9]

}
func main() {
	V8Example()
}

14.事务示例2
package main

import (
	"fmt"
	"github.com/go-redis/redis"
	"time"
)

// 声明一个全局的rdb变量
var rdb *redis.Client

// 初始化连接
func initClient() (err error) {
	rdb = redis.NewClient(&redis.Options{
		Addr:     "localhost:6379",
		Password: "", // no password set
		DB:       0,  // use default DB
	})

	_, err = rdb.Ping().Result()
	if err != nil {
		return err
	}
	return nil
}
func V8Example() {
	initClient()
	rdb.Do("set", "tx_pipeline_counter", "1")
	val, _ := rdb.Get("tx_pipeline_counter").Result()
	fmt.Println(val) //输出:1

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

	pipe.Exec()
	fmt.Println(incr.Val())//输出:2
	val1, _ := rdb.Get("tx_pipeline_counter").Result()
	fmt.Println(val1) //输出:2

}
func main() {
	V8Example()
}

二、go-redis/redis(v8) 1.redis依赖安装
最新版本的go-redis库的相关命令都需要传递context.Context参数,例如:

2.redis.NewClient函数
func NewClient(opt *Options) *Client {}
//Options是一个结构体,里面有很多参数
3.redis.Client结构体 3.1结构体
type Client struct {
	*baseClient
	cmdable
	hooks
	ctx context.Context
}

3.2Do方法
func (c *Client) Do(ctx context.Context, args ...interface{}) *Cmd {}
3.3TxPipeline方法
func (c *Client) TxPipeline() Pipeliner {}
4.redis.Pipeliner接口
type Pipeliner interface {
	StatefulCmdable
	Do(ctx context.Context, args ...interface{}) *Cmd
	Process(ctx context.Context, cmd Cmder) error
	Close() error
	Discard() error
	Exec(ctx context.Context) ([]Cmder, error)
}
5.redis.Cmd结构体
type Cmd struct {
	baseCmd

	val interface{}
}

6.baseCmd结构体 6.1结构体
//注意:引用不到,因为是小写
type baseCmd struct {
	ctx    context.Context
	args   []interface{}
	err    error
	keyPos int8

	_readTimeout *time.Duration
}

6.2Err()方法
func (cmd *baseCmd) Err() error {
	return cmd.err
}
7.redis.StringCmd结构体 7.1结构体
type StringCmd struct {
	baseCmd
	val string
}
7.2Val方法
func (cmd *StringCmd) Val() string {
	return cmd.val
}
7.3Result方法
func (cmd *StringCmd) Result() (string, error) {
	return cmd.Val(), cmd.err
}
8.redis.StatusCmd结构体 8.1结构体
type StatusCmd struct {
	baseCmd

	val string
}
8.2Result方法
func (cmd *StatusCmd) Result() (string, error) {
	return cmd.val, cmd.err
}
9.redis.StringSliceCmd结构体 9.1结构体
type StringSliceCmd struct {
	baseCmd

	val []string
}
9.2Result()方法
func (cmd *StringSliceCmd) Result() ([]string, error) {
	return cmd.Val(), cmd.Err()
}
10.redis.ScanCmd结构体 11.1结构体
type ScanCmd struct {
	baseCmd

	page   []string
	cursor uint64

	process cmdable
}
11.2Iterator方法
func (cmd *ScanCmd) Iterator() *ScanIterator {
	return &ScanIterator{
		cmd: cmd,
	}
}
12.redis.ScanIterator结构体 12.1结构体
type ScanIterator struct {
	mu  sync.Mutex // protects Scanner and pos
	cmd *ScanCmd
	pos int
}
12.2Next方法
func (it *ScanIterator) Next(ctx context.Context) bool {}
13.redis.IntCmd结构体 13.1结构体
type IntCmd struct {
	baseCmd

	val int64
}
14.cmdable类型 14.1类型
type cmdable func(ctx context.Context, cmd Cmder) error
14.2Set方法
func (c cmdable) Set(ctx context.Context, key string, value interface{}, expiration time.Duration) *StatusCmd {}
14.3Get方法
func (c cmdable) Get(ctx context.Context, key string) *StringCmd {}
14.4Ping方法
func (c cmdable) Ping(ctx context.Context) *StatusCmd {}
14.5Keys方法
func (c cmdable) Keys(ctx context.Context, pattern string) *StringSliceCmd {}
14.6Scan方法
func (c cmdable) Scan(ctx context.Context, cursor uint64, match string, count int64) *ScanCmd {}
14.7Del方法
func (c cmdable) Del(ctx context.Context, keys ...string) *IntCmd {} 
15.NewClusterClient函数
func NewClusterClient(opt *ClusterOptions) *ClusterClient {}
16.NewFailoverClient函数
func NewFailoverClient(failoverOpt *FailoverOptions) *Client {}
17.String类型Set、Get单 *** 作
package main

import (
	"context"
	"fmt"
	"github.com/go-redis/redis/v8"
	"time"
)

var (
	rdb *redis.Client
)

// 初始化连接
func initClient() (err error) {
	rdb = redis.NewClient(&redis.Options{
		Addr:     "localhost:6379",
		Password: "",  // no password set
		DB:       0,   // use default DB
		PoolSize: 100, // 连接池大小
	})
	/*func WithTimeout(parent Context, timeout time.Duration) (Context, CancelFunc) {
	  return WithDeadline(parent, time.Now().Add(timeout))}*/
	ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
	defer cancel()
    //Ping返回的是:*StatusCmd ; Result方法是StatusCmd结构体的方法(StatusCmd的val, baseCmd的err)
	_, err = rdb.Ping(ctx).Result()
	return err
}

func V8Example() {
	/*func Background() Context {
		return background
	}
	*/
	ctx := context.Background()
	if err := initClient(); err != nil {
		//Set是cmdable的方法Set返回的是*StatusCmd;StatusCmd结构体里面有basecmd
        //Err()是baseCmd结构体的方法 (baseCmd.err)
        //rdb是client结构体,这个结构体里面有cmdable类型,
		err := rdb.Set(ctx, "key", "value", 0).Err()
		if err != nil {
			panic(err)
		}
		//Set返回的是*StringCmd; Result是StringCmd结构体的方法 (StringCmd.Val() [StringCmd.val]  )
		val, err := rdb.Get(ctx, "key").Result()
		if err != nil {
			panic(err)
		}
		fmt.Println("key", val)

		val2, err := rdb.Get(ctx, "key2").Result()
		if err == redis.Nil {
			fmt.Println("key2 does not exist")
		} else if err != nil {
			panic(err)
		} else {
			fmt.Println("key2", val2)
		}
		// Output: key value
		// key2 does not exist
	}
}
func main() {
	V8Example()
	/*输出:
	key value
	key2 does not exist
	*/
}

18.根据前缀获取Key
package main

import (
	"context"
	"fmt"
	"github.com/go-redis/redis/v8"
	"time"
)

var (
	rdb *redis.Client
)

// 初始化连接
func initClient() (err error) {
	rdb = redis.NewClient(&redis.Options{
		Addr:     "localhost:6379",
		Password: "",  // no password set
		DB:       0,   // use default DB
		PoolSize: 100, // 连接池大小
	})
	ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
	defer cancel()
	_, err = rdb.Ping(ctx).Result()
	return err
}

func V8Example() {
	ctx := context.Background()
	err := initClient()
	rdb.Set(ctx, "key", "value", 0).Err()
	rdb.Set(ctx, "keppp", "value", 0).Err()
	vals, _ := rdb.Keys(ctx, "k*").Result()
	if err != nil {
		panic(err)
	}
	fmt.Println(vals) //输出: [key keppp]

}
func main() {
	V8Example()
}

19.执行自定义命令
package main

import (
	"context"
	"fmt"
	"github.com/go-redis/redis/v8"
	"time"
)

var (
	rdb *redis.Client
)

// 初始化连接
func initClient() (err error) {
	rdb = redis.NewClient(&redis.Options{
		Addr:     "localhost:6379",
		Password: "",  // no password set
		DB:       0,   // use default DB
		PoolSize: 100, // 连接池大小
	})
	ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
	defer cancel()
	_, err = rdb.Ping(ctx).Result()
	return err
}

func V8Example() {
	ctx := context.Background()
	initClient()
    //Do是Client结构体的方法
	rdb.Do(ctx, "set", "key1", "value1").Result()
	val1, _ := rdb.Get(ctx, "key1").Result()
	val2, _ := rdb.Do(ctx, "get", "key1").Result()
	fmt.Println(val1) //输出:val1
	fmt.Println(val2) //输出:val1
}
func main() {
	V8Example()
}

20.按通配符删除key

当通配符匹配的key的数量不多时,可以使用Keys()得到所有的key在使用Del命令删除。 如果key的数量非常多的时候,我们可以搭配使用Scan命令和Del命令完成删除。

package main

import (
	"context"
	"fmt"
	"github.com/go-redis/redis/v8"
	"time"
)

var (
	rdb *redis.Client
)

// 初始化连接
func initClient() (err error) {
	rdb = redis.NewClient(&redis.Options{
		Addr:     "localhost:6379",
		Password: "",  // no password set
		DB:       0,   // use default DB
		PoolSize: 100, // 连接池大小
	})
	ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
	defer cancel()
	_, err = rdb.Ping(ctx).Result()
	return err
}

func V8Example() {
	initClient()
	ctx := context.Background()
	rdb.Do(ctx, "set", "key1", "value1").Result()
	rdb.Do(ctx, "set", "key2", "value2").Result()
	vals1, _ := rdb.Keys(ctx, "k*").Result()
	fmt.Println(vals1) //输出:[key2 key1]
	iter := rdb.Scan(ctx, 0, "k*", 0).Iterator()
	for iter.Next(ctx) {
		err := rdb.Del(ctx, iter.Val()).Err()
		if err != nil {
			panic(err)
		}
	}
	vals2, _ := rdb.Keys(ctx, "k*").Result()
	fmt.Println(vals2)//输出:[]
}
func main() {
	V8Example()
}

21.连接redis集群
func initClient() (err error) {

	rdb := redis.NewClusterClient(&redis.ClusterOptions{
		Addrs: []string{":7000", ":7001", ":7002", ":7003", ":7004", ":7005"},
	})
	ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
	defer cancel()
	//Ping返回的是:*StatusCmd ; Result方法是StatusCmd结构体的方法(StatusCmd的val, baseCmd的err)
	_, err = rdb.Ping(ctx).Result()
	return err
}

22.连接Redis哨兵模式
func initClient() (err error) {

	rdb := redis.NewFailoverClient(&redis.FailoverOptions{
		MasterName:    "master",
		SentinelAddrs: []string{"x.x.x.x:26379", "xx.xx.xx.xx:26379", "xxx.xxx.xxx.xxx:26379"},
	})
	ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
	defer cancel()
	_, err = rdb.Ping(ctx).Result()
	return err
}

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

原文地址: https://outofmemory.cn/langs/990906.html

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

发表评论

登录后才能评论

评论列表(0条)

保存