这是我参与8月更文挑战的第24天,活动详情查看:8月更文挑战
简介
Redis是一种开源,使用内存来缓存数据的key/value数据库
Redis提供了如字符串,列表,集合,散列等等数据结构
Redis的优势在于性能极高,每秒读取高达11万次,每秒写入高达8万次,还有丰富的数据类型,以及非富的特性,如订阅发布,通知,key过期等
应用场景
- 缓存系统 减轻关系型数据的压力
- 计数 关注数,粉丝数
- 排行榜 各种排名榜单
安装
安装docker
为了节省时间,直接写代码,这里基于docker来快速安装redis,传送门: juejin.cn/post/684490…
docker run --name redis -p 6379:6379 -d redis:5.0.7
安装UI工具
如果在本地没有安装RedisDesktopManager这类工具,也可以安装web ui工具,如下
mkdir -p ./p3x-redis-ui-settings
docker run -v $PWD/p3x-redis-ui-settings:/settings -h docker-p3x-redis-ui -p 7843:7843 -t -i -d patrikx3/p3x-redis-ui
客户端
目前在github有两个比较热门的客户端,都有8k以上的星星,但它们有特色描述说明有功能不一样的地方
github.com/go-redis/re… 表现如下:
- Redis 3 commands except QUIT, MONITOR, and SYNC.
- Automatic connection pooling with circuit breaker support.
- Pub/Sub.
- Transactions.
- Pipeline and TxPipeline.
- Scripting.
- Timeouts.
- Redis Sentinel.
- Redis Cluster.
- Cluster of Redis Servers without using cluster mode and Redis Sentinel.
- Ring.
- Instrumentation.
github.com/gomodule/re… 表现如下:
- A Print-like API with support for all Redis commands.
- Pipelining, including pipelined transactions.
- Publish/Subscribe.
- Connection pooling.
- Script helper type with optimistic use of EVALSHA.
- Helper functions for working with command replies.
可以看出go-redis实现的功能比较多一些,而gomodule在命令功能实现多一些,如果是写业务的curd建议使用go-redis,如果是想命令行工具,建议使用gomodule
api例子
这边使用go-redis客户端,以一台单机的redis实例来测试相关的api功能
初始化
将client,ctx,err定义全局变量,函数会经常用的,在项目启动检查连接状态,后续专注业务代码既可
var (
ctx = context.Background()
rdb *redis.Client
err error
)
func init() {
//连接redis
rdb = redis.NewClient(&redis.Options{Addr: "ip:6379", Password: "", DB: 0})
//健康检测
_, err = rdb.Ping(ctx).Result()
if err != nil {
log.Fatalln("redis状态错误: ",err)
}
}
字符串类型
string数据类型,一个key对应一个value..操作简单。还有过期时间设置,0代表不过期
func stringKV() {
//新增k/v
_ = rdb.Set(ctx, "hello", "world", 0).Err()
//获取k/v
result, _ := rdb.Get(ctx, "hello").Result()
fmt.Println(result)
//删除
_, _ = rdb.Del(ctx, "hello").Result()
}
列表类型
列表是简单的字符串列表,按照插入顺序排序。你可以添加一个元素到列表的头部(左边)或者尾部(右边)
以下代码展示了CURD等常规操作
func listKV() {
//新增
_ = rdb.RPush(ctx, "list", "message").Err()
_ = rdb.RPush(ctx, "list", "message2").Err()
//查询
result, _ := rdb.LLen(ctx, "list").Result()
fmt.Println(result)
//更新
_ = rdb.LSet(ctx, "list", 2, "message set").Err()
//遍历
lRange,_ := rdb.LRange(ctx, "list", 0, result).Result()
for _,v := range lRange {
log.Println(v)
}
//删除
_, _ = rdb.LRem(ctx, "list", 3, "message2").Result()
}
哈希类型
hash 是一个 string 类型的 field(字段) 和 value(值) 的映射表,hash 特别适合用于存储对象
func hashKV() {
data := map[string]interface{}{
"name":"张三",
"age": 66,
}
//新增
_ = rdb.HMSet(ctx, "hash", data).Err()
//查询
result, _ := rdb.HMGet(ctx, "hash","name").Result()
fmt.Println(result)
//全部
m, _ := rdb.HGetAll(ctx, "hash").Result()
fmt.Println("m: ",m)
//判断值是否存在
b, _ := rdb.HExists(ctx, "hash", "age").Result()
fmt.Println("b: ",b)
//删除
_, _ = rdb.HDel(ctx, "hash").Result()
}
集合类型
Set 是 String 类型的无序集合。集合成员是唯一的,这就意味着集合中不能出现重复的数据。
集合对象的编码可以是 intset 或者 hashtable。
Redis 中集合是通过哈希表实现的,所以添加,删除,查找的复杂度都是 O(1)。
func setKV() {
//新增
result, _ := rdb.SAdd(ctx, "set", "aa", "bb", "cc", "dd", "ee").Result()
fmt.Println(result)
//数量统计
i, _ := rdb.SCard(ctx, "set").Result()
fmt.Println(i)
//成员信息
i2, _ := rdb.SMembers(ctx, "set").Result()
fmt.Println(i2)
//删除
_, _ = rdb.SRem(ctx, "set", "cc").Result()
}
有序集合类型
有序集合和集合一样也是 string 类型元素的集合,且不允许重复的成员。
不同的是每个元素都会关联一个 double 类型的分数。redis 正是通过分数来为集合中的成员进行从小到大的排序。 有序集合的成员是唯一的,但分数(score)却可以重复
func sortSetKV() {
//新增
for i:=1;i<100 ;i++ {
data := redis.Z{
Score: float64(i),
Member: i,
}
_, _ = rdb.ZAdd(ctx, "sortSet", &data).Result()
}
//统计
result, _ := rdb.ZCard(ctx, "sortSet").Result()
fmt.Println(result)
//查询
result2, _ := rdb.ZRange(ctx, "sortSet", 0, result).Result()
fmt.Println(result2)
}
发布订阅
发布订阅 (pub/sub) 是一种消息通信模式:发送者 (pub) 发送消息,订阅者 (sub) 接收消息。 Redis客户端可以订阅任意数量的频道
func pubsub() {
subscribe := rdb.Subscribe(ctx,"sub1")
_, _ = subscribe.Receive(ctx)
channel := subscribe.Channel()
_ = rdb.Publish(ctx, "sub1", "message1").Err()
_ = rdb.Publish(ctx, "sub1", "message2").Err()
for msg := range channel {
log.Println(msg.Channel,msg.Payload)
}
}