目 录CONTENT

文章目录

Redis-Go编程

Sakura
2023-09-16 / 0 评论 / 0 点赞 / 41 阅读 / 0 字 / 正在检测是否收录...
温馨提示:
本文最后更新于57天前,若内容或图片失效,请留言反馈。 部分素材来自网络,若不小心影响到您的利益,请联系我们删除。

Redis-Go编程

Go-Redis github 地址 :

redis/go-redis: Redis Go client (github.com)

官方中文教程:

Go Redis [快速入门] (uptrace.dev)

1. 安装Go-Redis

  • Redis 6 :

go get github.com/redis/go-redis/v8
  • Redis 7 :

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

查看 Redis 的版本

# 方式一
# docker exec -it docker-ID redis-server --version
Redis server v=7.0.5 sha=00000000:0 malloc=jemalloc-5.2.1 bits=64 build=a507a0b937977997

# 方式二
127.0.0.1:6379>info server
# Server
redis_version:7.0.5

2. 连接单点服务模式

单点模式服务指的是使用单一的redis服务器实现Redis服务,最简单的一种模式。

  • 通过地址建立连接

import "github.com/go-redis/redis/v9"

rdb := redis.NewClient(&redis.Options{
        Addr:        "192.168.157.135:6379",
        Username:    "default",       // default user
        Password:    "1234",     // no password set
        DB:          0,               // use default DB
        DialTimeout: 1 * time.Second, // 1 second
    })

注意,

NewClient()操作,不会立即对 Redis 服务器建立连接,仅用来配置连接选项。只有当对 Redis 服务器发出第一次操作时,才会建立连接。例如,rdb.Ping() 可用来测试服务器的连接情况:

下面这段代码用于测试 Redis 服务器是否建立连接

status := rdb.Ping(context.Background())
fmt.Println(status.Result())

  • 基于连接字符串建立连接:

import "github.com/go-redis/redis/v9"

opt, err := redis.ParseURL("redis://default:password@192.168.157.135:6379/0?dial_timeout=1")
    if err != nil {
        panic(err)
    }

rdb := redis.NewClient(opt)
  • 其他连接选项

Network string // 网络类型 Default is tcp
Addr string // 地址 host:port
Username string // ACL 用户名
Password string // ACL 密码
DB int // 所选数据库
DialTimeout time.Duration // 拨号连接超时时间,default 5 seconds
ReadTimeout time.Duration // 读操作超时时间
WriteTimeout time.Duration // 写操作超时时间
PoolTimeout time.Duration // 连接池等待超时时间
PoolSize int // 连接池大小
  • 将 Redis 连接封装为方法

func Link() *redis.Client {
	// Redis 客户单
	// 此时不会建立连接
	client := redis.NewClient(&redis.Options{
		Addr:        "8.130.86.133:6379",
		Username:    "default",
		Password:    "jhkdjhkjdhsIUTYURTU_JteHXp",
		DB:          0,
		DialTimeout: 5 * time.Second,
	})
	return client
}

3. String

3.1 set

注意:

SetEx , SetNx , SetXX的功能可以由Set , SetArgs完成,因此建议以使用Set、SetArgs为主

// 设置
func (c Client) Set(ctx context.Context, key string, value interface{}, expiration time.Duration) *StatusCmd
// 设置,使用参数配置。Mode(`NX` or `XX` or empty),TTL,ExpireAt,Get,KeepTTL
func (c Client) SetArgs(ctx context.Context, key string, value interface{}, a SetArgs) *StatusCmd

// 设置,同时设置有效期
func (c Client) SetEX(ctx context.Context, key string, value interface{}, expiration time.Duration) *StatusCmd
// 设置,前提是Key不存在
func (c Client) SetNX(ctx context.Context, key string, value interface{}, expiration time.Duration) *BoolCmd
// 设置,前提是Key存在
func (c Client) SetXX(ctx context.Context, key string, value interface{}, expiration time.Duration) *BoolCmd
// 注意:SetEx,SetNx,SetXX 的功能可以由 Set、SetArgs完成,因此建议以使用 Set、SetArgs 为主

// 设置多个
func (c Client) MSet(ctx context.Context, values ...interface{}) *StatusCmd
// 设置多个,前提是全部的key都要不存在
func (c Client) MSetNX(ctx context.Context, values ...interface{}) *BoolCmd
  • SetArgs()

// 设置条件
// NX, key 不存在时设置
// XX, key 存在时设置
status := client.SetArgs(ctx, "name", "Sakura", redis.SetArgs{
	// NX | XX | "" 空表示存在则更新,不存在则添加,是默认的模式
	Mode: "",
	// 有效期,时间周期, eg,10秒
	TTL: 0,
	// 有效期,时间点 eg,今晚23点(时间戳)
	ExpireAt: time.Time{},
	// 是否返回原有值
	Get: false,
	// 是否保持原有有效期
	KeepTTL: false,
})

3.2 get

// 获取
func (c Client) Get(ctx context.Context, key string) *StringCmd
// 获取并删除
func (c Client) GetDel(ctx context.Context, key string) *StringCmd
// 获取并设置有效期
func (c Client) GetEx(ctx context.Context, key string, expiration time.Duration) *StringCmd

// 获取多个
func (c Client) MGet(ctx context.Context, keys ...string) *SliceCmd

// 获取字符串长度
func (c Client) StrLen(ctx context.Context, key string) *IntCmd
  • Result() 返回执行的结果

func String() {
	// 获取连接
	client := Link()

	// context 上下文
	ctx := context.Background()

	// 一:设置string
	status := client.Set(ctx, "name", "Sakura", 5*time.Second)
	// 0 表示不过期
	//client.Set(ctx, "name", "Sakrua", 0)
	// redis.KeepTTL 表示保持原有的有效期 (仅仅需要修改值的时候)
	//status := client.Set(ctx, "name", "Sakura", redis.KeepTTL)
	// 输出 set 执行后的状态 ,返回string,err
	fmt.Println(status.Result())

	// 二:获取string
	result := client.Get(ctx, "name")
	// 获取结果以及命令的执行结果 (是否错误)
	value, err := result.Result()
	//fmt.Println(value, err)

	// 判定 key 是否存在
	if err == redis.Nil {
		fmt.Println("key not exists")
	} else if err != nil {
		fmt.Println(err)
	} else if value == "" {
		fmt.Println("value is empty")
	} else {
		fmt.Println("get value:", value)
	}
}

3.3 追加

func StringAppend() {
	// 建立连接
	client := Link()
	ctx := context.Background()

	client.Set(ctx, "name", "Sakura", 10*time.Second)
	// Append
	client.Append(ctx, "name", "sss")
	status := client.Append(ctx, "name", ".top")
	fmt.Println(status.Result())

	result := client.Get(ctx, "name")
	fmt.Println(result.Result())
}

Apend() 的返回值是追加后的字符串长度和err

3.4 递增递减

递增步长是有IncrByFloat()

递减步长没有指定浮点数递减

func StringIncr() {
	client := Link()
	ctx := context.Background()

	// 执行递增操作,会将value看做64位整数
	client.Set(ctx, "num", "0", 10*time.Second)
	// 递增3次
	client.Incr(ctx, "num")
	client.Incr(ctx, "num")
	client.Incr(ctx, "num") // 3
	// 指定步长递增
	client.IncrBy(ctx, "num", 2)
	client.IncrBy(ctx, "num", 2)
	client.IncrBy(ctx, "num", 2)

	// 递减和指定步长递减
	client.Decr(ctx, "num")
	client.DecrBy(ctx, "num", 3)
	
	
	fmt.Println(client.Get(ctx, "num").Result())
}

3.5 子串操作

  • GetRange()SetRange()

// 设置特定字符串的特定索引内容
func (c Client) SetRange(ctx context.Context, key string, offset int64, value string) *IntCmd
// 获取特定范围的字符串(substr)
func (c Client) GetRange(ctx context.Context, key string, start, end int64) *StringCmd
func StringSub() {
	client := Link()
	ctx := context.Background()

	client.Set(ctx, "name", "Sakuasss.top", 10*time.Second)
	// GetRange
	// 左闭右闭
	fmt.Println(client.GetRange(ctx, "name", 0, 4).Result())
	// 负数表示,从右边起第几个  -4右边第四个 -1右边第一个
	fmt.Println(client.GetRange(ctx, "name", -4, -1).Result())
	// 越界会自动处理到最大索引
	fmt.Println(client.GetRange(ctx, "name", -4, 16).Result())
	// 获取全部内容
	fmt.Println(client.GetRange(ctx, "name", 0, -1).Result())

	// SetRange
	// 从0开始修改为www.
	client.SetRange(ctx, "name", 0, "www.")
	fmt.Println(client.Get(ctx, "name").Result())
	// 超出原本字符串的长度会追加
	client.SetRange(ctx, "name", 8, "www.")
	fmt.Println(client.Get(ctx, "name").Result())
}

这两个操作的时间复杂度是 O(n)

4. BitMap

4.1 基本操作

func BitMapSetGet() {
	client := Link()
	ctx := context.Background()

	// 1.设置bit
	client.SetBit(ctx, "User", 0, 1)
	client.SetBit(ctx, "User", 1, 0)
	client.SetBit(ctx, "User", 2, 1)
	client.SetBit(ctx, "User", 3, 0)
	client.SetBit(ctx, "User", 4, 0)

	// 2.获取bit
	fmt.Println(client.GetBit(ctx, "User", 0).Result())

	// 3.未设置的位为0
	fmt.Println(client.GetBit(ctx, "User", 5).Result())

	// 4.越界会报错
	fmt.Println(client.SetBit(ctx,"Big", 1<<32, 1))
	// 可以使用 memory usage <key> 查看key的内存占用情况

	// 5.统计 1 的数量
	fmt.Println(client.BitCount(ctx, "User", &redis.BitCount{
		// 以字节为单位,而不是以位为单位
		// 统计第一个字节中1的个数
		Start: 0,
		End:   0,
	}))
}

4.2 位运算

// 位与
func (c Client) BitOpAnd(ctx context.Context, destKey string, keys ...string) *IntCmd
// 位非
func (c Client) BitOpNot(ctx context.Context, destKey string, key string) *IntCmd
// 位或
func (c Client) BitOpOr(ctx context.Context, destKey string, keys ...string) *IntCmd
// 位异或
func (c Client) BitOpXor(ctx context.Context, destKey string, keys ...string) *IntCmd

destKey 存储运算结果的 Key

5.3 字符串操作位图

设置的 bitmap 位图,可以通过 get 通过 ASCII 码转成对应字符

func BitMapSetGet() {
	client := Link()
	ctx := context.Background()

	// 1.设置bit
	client.SetBit(ctx, "BitString", 0, 0)
	client.SetBit(ctx, "BitString", 1, 1)

	fmt.Println(client.Get(ctx, "BitString").Result())
}

5. List

6. Set

7. SortSet

8. HyperLogLog

9. Geo

0

评论区