Redis
大约 14 分钟
Redis
Redis 是一个开源的使用 ANSI C 语言编写、遵守 BSD 协议、支持网络、可基于内存、分布式、可选持久性的键值对(Key-Value)存储数据库,并提供多种语言的 API,Redis即可以当作一个NoSQL数据库,又可以是当作高速缓存存储,还支持简单的消息队列。
本文仅仅讲解如何使用Go语言驱动来操作Redis数据库,不会对Redis本身做任何讲解。
官方文档:Golang Redis client (uptrace.dev)
官方仓库:go-redis/redis: Type-safe Redis client for Golang (github.com)
安装
关于Redis的驱动有很多,本文使用的是github.com/go-redis/redis
。
如果你使用的Redis版本号为6
go get github.com/go-redis/redis/v8
如果你使用的Redis版本号为7
go get github.com/go-redis/redis/v9
快速开始
import (
"fmt"
"log"
"testing"
"github.com/go-redis/redis"
)
func TestQuickStart(t *testing.T) {
// 创建Redis连接客户端
redisClient := redis.NewClient(&redis.Options{
Addr: "192.168.48.134:6379",
Password: "123456",
DB: 0, // 使用默认DB
})
// 设置键值对,0就是永不过期
redisClient.Set("hello", "world", 0)
// 读取值
result, err := redisClient.Get("hello").Result()
if err == redis.Nil {
fmt.Println("ket not exist")
} else if err != nil {
log.Panic(err)
}
fmt.Println(result)
}
连接配置
type Options struct {
// 网络类型 tcp 或者 unix.
// 默认是 tcp.
Network string
// redis地址,格式 host:port
Addr string
// Dialer 创建一个新的网络连接且比Network和Addr有着更高的优先级
// Network and Addr options.
Dialer func() (net.Conn, error)
// 新建一个redis连接的时候,会回调这个函数
OnConnect func(*Conn) error
// redis密码,redis server没有设置可以为空。
Password string
// redis数据库,序号从0开始,默认是0,可以不用设置
DB int
// redis操作失败最大重试次数,默认0。
MaxRetries int
// 最小重试时间间隔.
// 默认是 8ms ; -1 表示关闭.
MinRetryBackoff time.Duration
// 最大重试时间间隔
// 默认是 512ms; -1 表示关闭.
MaxRetryBackoff time.Duration
// redis新连接超时时间.
// 默认是 5 秒.
DialTimeout time.Duration
// socket读取超时时间
// 默认 3 秒.
ReadTimeout time.Duration
// socket写超时时间
WriteTimeout time.Duration
// redis连接池的最大连接数.
// 默认连接池大小等于 cpu个数 * 10
PoolSize int
// redis连接池最小空闲连接数.
MinIdleConns int
// redis连接最大的存活时间,默认不会关闭过时的连接.
MaxConnAge time.Duration
// 当你从redis连接池获取一个连接之后,连接池最多等待这个拿出去的连接多长时间。
// 默认是等待 ReadTimeout + 1 秒.
PoolTimeout time.Duration
// redis连接池多久会关闭一个空闲连接.
// 默认是 5 分钟. -1 则表示关闭这个配置项
IdleTimeout time.Duration
// 多长时间检测一下,空闲连接
// 默认是 1 分钟. -1 表示关闭空闲连接检测
IdleCheckFrequency time.Duration
// 只读设置,如果设置为true, 在当前节点实例上,redis只能查询缓存不能更新。
readOnly bool
// TLS配置
TLSConfig *tls.Config
}
建立连接
// 创建Redis连接客户端
redisClient := redis.NewClient(&redis.Options{
Addr: "192.168.48.134:6379",
Password: "123456",
DB: 0, // 使用默认DB
})
关闭连接
驱动内部维护着一个连接池,不需要操作一次就关闭一次连接。
defer redisClient.Close()
这个Redis驱动几乎将所有的操作封装好了,Redis命令和方法名一一对应,基本上只要知道Redis命令怎么用,驱动对应的方法都也差不多会了。
Redis命令:redis 命令手册
基本操作
删除键
redisClient.Set("name", "jack", 0)
fmt.Println(redisClient.Del("name").Result())
过期时间
redisClient.Set("name", "jack", 0)
// 设置过期时间
redisClient.Expire("name", time.Second*2)
fmt.Println(redisClient.Get("name").Val())
time.Sleep(time.Second * 3)
fmt.Println(redisClient.Get("name").Val())
取消过期时间
redisClient.Set("name", "jack", 2)
// 取消过期时间
redisClient.Persist("name")
time.Sleep(time.Second * 2)
fmt.Println(redisClient.Get("name"))
查询过期时间
fmt.Println(redisClient.TTL("name"))
fmt.Println(redisClient.PTTL("name"))
重命名
redisClient.Rename("name", "newName")
查询类型
redisClient.Type("name")
扫描
fmt.Println(redisClient.Scan(0, "", 4))
字符串
简单存取
redisClient.Set("token", "abcefghijklmn", 0)
fmt.Println(redisClient.Get("token").Val())
批量存取
redisClient.MSet("cookie", "12345", "token", "abcefg")
fmt.Println(redisClient.MGet("cookie", "token").Val())
数字增减
redisClient.Set("age", "1", 0)
// 自增
redisClient.Incr("age")
fmt.Println(redisClient.Get("age").Val())
// 自减
redisClient.Decr("age")
fmt.Println(redisClient.Get("age").Val())
哈希表
读写操作
// 单个设置
redisClient.HSet("map", "name", "jack")
// 批量设置
redisClient.HMSet("map", map[string]interface{}{"a": "b", "c": "d", "e": "f"})
// 单个访问
fmt.Println(redisClient.HGet("map", "a").Val())
// 批量访问
fmt.Println(redisClient.HMGet("map", "a", "b").Val())
// 获取整个map
fmt.Println(redisClient.HGetAll("map").Val())
输出
b
[b <nil>]
map[a:b c:d e:f name:jack]
删除键
// 删除map的一个字段
redisClient.HDel("map", "a")
判断键是否存在
// 判断字段是否存在
redisClient.HExists("map", "a")
获取所有的键
// 获取所有的map的键
redisClient.HKeys("map")
获取哈希表键长度
// 获取map长度
redisClient.HLen("map")
遍历哈希表的键值对
// 遍历map中的键值对
redisClient.HScan("map", 0, "", 1)
列表
修改元素
// 左边添加
redisClient.LPush("list", "a", "b", "c", "d", "e")
// 右边添加
redisClient.RPush("list", "g", "i", "a")
// 在参考值前面插入值
redisClient.LInsertBefore("list", "a", "aa")
// 在参考值后面插入值
redisClient.LInsertAfter("list", "a", "gg")
// 设置指定下标的元素的值
redisClient.LSet("list", 0, "head")
访问长度
// 访问列表长度
redisClient.LLen("list")
访问元素
// 左边弹出元素
redisClient.LPop("list")
// 右边弹出元素
redisClient.RPop("list")
// 访问指定下标的元素
redisClient.LIndex("list", 1)
// 访问指定范围内的元素
redisClient.LRange("list", 0, 1)
删除元素
// 删除指定元素
redisClient.LRem("list", 0, "a")
// 删除指定范围的元素
redisClient.LTrim("list", 0, 1)
// 保留指定范围的元素
redisClient.LTrim("list", 0, 1)
集合
新增元素
// 往一个集合里面添加元素
redisClient.SAdd("set", "a", "b", "c")
redisClient.SAdd("set2", "c", "d", "e")
访问集合元素
// 获取集合中的所有成员
redisClient.SMembers("set")
// 判断一个元素是否属于这个集合
redisClient.SIsMember("set", "a")
// 随机返回count个元素
redisClient.SRandMemberN("set", 1)
// 获取一个集合的元素个数
redisClient.SCard("set")
集合操作
// 返回给定集合的差集
redisClient.SDiff("set", "set2")
// 将给定集合的差集保存在结果集里,返回结果集的长度
redisClient.SDiffStore("store", "set", "se2")
// 返回给定集合的交集
redisClient.SInter("set", "set2")
// 将给定集合的交集保存在结果集里,返回结果集的长度
redisClient.SInterStore("store", "set", "set2")
// 返回给定集合的并集
redisClient.SUnion("set", "set2")
// 将给定集合的并集保存在结果集里,返回结果集的长度
redisClient.SUnionStore("store", "set", "store")
删除元素
// 弹出并删除该元素
redisClient.SPop("set")
// 弹出并删除N给元素
redisClient.SPopN("set", 2)
移动元素
// 从源集合移动指定元素刀目标集合
redisClient.SMove("set", "set2", "a")
删除元素
// 删除指定元素
redisClient.SRem("set", "a", "b")
遍历
// 遍历集合
redisClient.SScan("set", 0, "", 2)
有序集合
加入元素
// 往有序集合中加入元素
redisClient.ZAdd("ss", redis.Z{
Score: 1,
Member: "a",
}, redis.Z{
Score: 2,
Member: "b",
})
元素排名
// 返回有序集合中该元素的排名,从低到高排列
redisClient.ZRank("ss", "1")
// 返回有序集合中该元素的排名,从高到低排列
redisClient.ZRevRank("ss", "1")
访问元素
// 返回介于min和max之间的成员数量
redisClient.ZCount("ss", "1", "2")
// 返回对元素的权值
redisClient.ZScore("ss", "a")
// 返回指定区间的元素
redisClient.ZRange("ss", 1, 2)
// 返回介于min和max之间的所有成员列表
redisClient.ZRangeByScore("ss", redis.ZRangeBy{
Min: "1",
Max: "2",
Offset: 0,
Count: 1,
})
修改权值
// 给一个对应的元素增加相应的权值
redisClient.ZIncr("ss", redis.Z{
Score: 2,
Member: "b",
})
删除元素
// 删除指定元素
redisClient.ZRem("ss", "a")
// 删除指定排名区间的元素
redisClient.ZRemRangeByRank("ss", 1, 2)
// 删除权值在min和max区间的元素
redisClient.ZRemRangeByScore("ss", "1", "2")
脚本
// 加载脚本,返回sha值
redisClient.ScriptLoad("return 0")
// 根据sha值执行脚本
redisClient.EvalSha("sha", []string{}, "")
// 直接执行脚本
redisClient.Eval("return 0", []string{}, "")
// 清除脚本缓存
redisClient.ScriptFlush()
// 杀死当前正在运行的脚本
redisClient.ScriptKill()
// 验证对应哈希值的脚本是否存在
redisClient.ScriptExists("")
发布订阅
// 发送消息到指定频道
redisClient.Publish("channel", "message")
// 订阅指定频道
redisClient.Subscribe("channel")
// 查看订阅状态
redisClient.PubSubNumSub("channel")