Go语言搬砖 操作redis

1,492 阅读4分钟

这是我参与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

image.png

客户端

目前在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)
   }
}