在Golang中使用Redis的方法示例

 更新时间:2018年06月19日 13:49:23   作者:zzayne  
这篇文章主要介绍了在Golang中使用Redis的方法示例,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧

周五上班的主要任务是在公司老平台上用redis处理一个队列问题,顺便复习了一下redis操作的基础知识,回来后就想着在自己的博客demo里,用redis来优化一些使用场景,学习一下golang开发下redis的使用。

Redis简单介绍

简介

关于Redis的讨论,其实在现在的后台开发中已经是个老生常谈的问题,基本上也是后端开发面试的基本考察点。其中 Redis的背景介绍和细节说明在这里就不赘述。不管怎么介绍,核心在于Redis是一个基于内存的key-value的多数据结构存储,并可以提供持久化服务。基于内存的特性决定了Redis天然适合高并发的数据读写缓存优化,同时也带来了内存开销过大的问题。所以在一些特定情景下,Redis是一把无往不利的大杀器,值得深入学习。

学习Redis的一个难点或者说入门点,我个人感觉在于对象存储理念的转变。刚接触 Redis 时,我刚从大学毕业,脑子里基本都是关系型数据存储的理念,使用时总想着靠数据内的关系来建立数据之间的联系,用起来很不顺手。后来慢慢入门了才感受到了一些操作的好处。举个栗子,比如查询用户在某个文章下的评论,用 sql 的思路就是搜索评论表里面用户ID和文章ID匹配的数据,有时还需要联合查询出其他信息,但是如果是 Redis 操作,以'前缀:文章ID:用户ID'为key,比如'comment:666:888'就可以快速取出用户评论,十分方便。 Redis 的强大远不仅如此,可以在实践中慢慢体会。

主要数据结构

Redis主要有五种基本数据结构,满足了绝大多数缓存结构的需要,如果你在使用一种结构存储时感觉别扭时,很有可能是选错了存储结构,可以考虑一下其他结构的正确实现。

  1. String ,可以是字符串、整数和浮点数。如果是序列化数据,并涉及到修改操作的话,不推荐用 string ,可以考虑用 Hash
  2. Hash, key-value 对象,可以存放对象数据,比如用户信息之类。
  3. List,有序数据集合,元素可以重复,用 LPUSH LPOP RPUSH RPOP 等指令组合可以实现栈和队列操作。
  4. Set,无序集合,元素唯一。
  5. Sorted Set,Sort的有序版,可以设定 Score 值来决定元素排序,适合用户排名这样的业务场景。

常见使用场景

  1. 高并发下数据缓存。 比如在某个场景下,大量日志同时写入数据库会给服务器带来巨大压力,这时可以先将数据写入 redis 中,再由 redis 写入数据库,减轻同时写入压力。
  2. 热点信息快速显示。假设现在有一个新闻首页,需要快速显示各栏目前20条热点新闻,如果直接查询数据库,在大量用户同时访问下,会消耗极大数量的数据库请求。这时就可以用 redis 来优化,在新闻录入的时候将标题、时间和来源写入 redis 中,客户端访问时,可以从内存中一次性取出当天热单新闻列表,极大地提高请求速度和节约了服务器开销。
  3. 保存会话信息。可以将登录后用户信息缓存入 redis 并同时设置 key 过期时间,这样后台 api 过滤请求时,就可以从内存中读取用户信息,而且 redis 的过期机制,天然支持用户身份有效期校验,用起来十分方便。
  4. 统计计数。比如系统中常见一个功能是限制同一用户固定时间段内的登录次数或者所有请求次数,这时就可以以用户id为key,次数值为value,将计数信息缓存起来,并且有 INCRBY 命令原生支持。
  5. 其他。Redis的应用场景十分广发,队列、发布订阅、统计分析等等,可以看看其他文章的介绍说明。

Golang连接Redis

使用 Golang 开发的一大直观感受就是,基本上你日常遇到的开发问题,都有官方或者第三方包帮你辅助实现,同时这些包都是开源的,只要你感兴趣,都可以深入到包的内部实现去学习理解包的实现思路和方法。当然这也有利有弊,第三包的不稳定和质量参差不齐也增加了一些开发成本,目前还是感受利大于弊。研究好的包源码实现,也是目前我的一个学习方向。

garyburd/redigo 包简介

garyburd/redigo 包是网上很多博文都在推荐使用的一个高Star的 Redis 连接包,但是当我自己去 Github 的项目地址 garyburd/redigo 上查看 API 时,发现这个项目目前是归档状态,项目已经迁移到了 gomodule/redigo ,同时包的获取也理所当然地改成了 go get github.com/gomodule/redigo/redis ,这已经不是我第一次感受了第三方包的不稳定,之前用 dep 进行包管理时,就遇到过 dep 拉取的包版本和本地包版本 API 冲突的问题,这个有时间单独再说。总之,暂时不管这两个包的详细区别,以下就以新包为准,介绍下 redigo 包使用。

建立连接池

Redigo Pool 结构维护一个 Redis 连接池。应用程序调用 Get 方法从池中获取连接,并使用连接的 Close 方法将连接的资源返回到池中。一般我们在系统初始化时声明一个全局连接池,然后在需要操作 redis 时获得连接,执行指令。

pool := &redis.Pool{
    MaxIdle:   3, /*最大的空闲连接数*/
    MaxActive:  8, /*最大的激活连接数*/
    Dial: func() (redis.Conn, error) {
      c, err := redis.Dial("tcp", '链接地址,例如127.0.0.1:6379', redis.DialPassword('密码'))
      if err != nil {
        return nil, err
      }
      return c, nil
    }
}
c:=pool.Get()
defer c.Close()

执行指令

查看源码,发现 Conn 接口有一个执行 Redis 命令的通用方法:

```

//gomodule/redigo/redis/redis.go

// Conn represents a connection to a Redis server.

type Conn interface {

// Close closes the connection.

Close() error

// Err returns a non-nil value when the connection is not usable.
Err() error

// Do sends a command to the server and returns the received reply.
Do(commandName string, args ...interface{}) (reply interface{}, err error)

// Send writes the command to the client's output buffer.
Send(commandName string, args ...interface{}) error

// Flush flushes the output buffer to the Redis server.
Flush() error

// Receive receives a single reply from the Redis server
Receive() (reply interface{}, err error)
}

```

http://redis.io/commands 中的 Redis 命令参考列出了可用的命令。 do 的参数和 redis-cli 命令参数格式一致,比如 SET key value EX 360 对应函数调用为 Do("SET", "key", "value","EX",360) ,常用的命令示例有:

c:=pool.Get()
defer c.Close()
//存值,
_, err := c.Do("SET", "key", "value")
//设置过期时间
_, err := c.Do("SET", "key", "value","EX",360)
//存int
_, err := c.Do("SET", "key", 2)

//取值
v,err:=redis.String(c.Do("GET","key"))
bytes, err := redis.Bytes(c.Do("GET", "key"))

总结

golang 中连接使用 redis 相对比较简单,所以暂时也没什么其他好说的,如果后面自己使用过程中发现有遗漏再进行补充,关键还是在于熟悉 redis-cli 原生的指令操作。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

相关文章

  • go循环依赖的最佳解决方案

    go循环依赖的最佳解决方案

      import cycle not allowed(循环依赖不被允许)相信作为每一个golang语言使用研发,都遇到过这个令人头痛的报错,循环依赖是指两个或多个模块之间互相依赖,形成了一个闭环的情况,本文会结合部分案例对解决方案进行讲解,需要的朋友可以参考下
    2023-10-10
  • Go gRPC进阶教程服务超时设置

    Go gRPC进阶教程服务超时设置

    这篇文章主要为大家介绍了Go gRPC进阶,gRPC请求的超时时间设置,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-06-06
  • Go语言中结构体方法副本传参与指针传参的区别介绍

    Go语言中结构体方法副本传参与指针传参的区别介绍

    这篇文章主要给大家介绍了关于Go语言中结构体方法副本传参与指针传参的区别的相关资料,文中先对GO语言结构体方法跟结构体指针方法的区别进行了一些简单的介绍,来帮助大家理解学习,需要的朋友可以参考下。
    2017-12-12
  • go singleflight缓存雪崩源码分析与应用

    go singleflight缓存雪崩源码分析与应用

    这篇文章主要为大家介绍了go singleflight缓存雪崩源码分析与应用示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-09-09
  • 深入了解Go语言中database/sql是如何设计的

    深入了解Go语言中database/sql是如何设计的

    在 Go 语言中内置了 database/sql 包,它只对外暴露了一套统一的编程接口,便可以操作不同数据库,那么database/sql 是如何设计的呢,下面就来和大家简单聊聊吧
    2023-07-07
  • Golang 实现简单随机负载均衡

    Golang 实现简单随机负载均衡

    均衡算法又分为 随机,轮询,加权轮询,哈希,而随机负载均衡算法就是本文的重点,需要的朋友们下面随着小编来一起学习学习吧
    2021-06-06
  • golang实现各种情况的get请求操作

    golang实现各种情况的get请求操作

    这篇文章主要介绍了golang实现各种情况的get请求操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-12-12
  • 三种Golang数组拷贝方式及性能分析详解

    三种Golang数组拷贝方式及性能分析详解

    在Go语言中,我们可以使用for、append()和copy()进行数组拷贝。这篇文章主要为大家详细介绍一下这三种方式的具体实现与性能分析,需要的可以参考一下
    2022-08-08
  • Go 编程复杂数据类型 Map

    Go 编程复杂数据类型 Map

    这篇文章主要介绍了Go编程复杂数据类型Map,Go中的Map是一组无需的K-V类型的数据,与Python中的字典Dict和Java中的HashMap结构类似。未被初始化的Map为nil
    2022-08-08
  • Go 热加载之fresh详解

    Go 热加载之fresh详解

    这篇文章主要为大家介绍了Go 热加载之fresh详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-08-08

最新评论