go语言使用redis(redigo)

本文涉及的产品
云数据库 Redis 版,社区版 2GB
推荐场景:
搭建游戏排行榜
简介: go的redis client用的比较多两个包是redix和redigo,因为beego cache模块里redis使用的是redigo,所以我也就使用这个包了。因为代码内容偏多,结构不清晰,不方便阅读,最后整理成一份思维导图,便于学习。

go的redis client用的比较多两个包是redix和redigo,因为beego cache模块里redis使用的是redigo,所以我也就使用这个包了。因为代码内容偏多,结构不清晰,不方便阅读,最后整理成一份思维导图,便于学习。当把整体分析,会发现提供给开发者使用的内容非常巧妙。

image

点击下载

Demo:

 1package main
 2
 3import (
 4    "fmt"
 5    "github.com/gomodule/redigo/redis"
 6    "log"
 7)
 8
 9func main() {
10    c1, err := redis.Dial("tcp", "127.0.0.1:6379")
11    if err != nil {
12        log.Fatalln(err)
13    }
14    defer c1.Close()
15    c2, err := redis.DialURL("redis://127.0.0.1:6379")
16    if err != nil {
17        log.Fatalln(err)
18    }
19    defer c2.Close()
20
21
22    rec1, err := c1.Do("Get", "name")
23    fmt.Println(string(rec1.([]byte)))
24
25    c2.Send("Get", "name")
26    c2.Flush()
27    rec2, err := c2.Receive()
28    fmt.Println(string(rec2.([]byte)))
29}

下面内容是更加详细的源码分析

提供给开发者使用的内容
(1)变量
(2)常量
(3)新类型
(4)接口
(5)结构体
(6)函数

1、变量
var ErrNil = errors.New("redigo: nil returned")
2、常量
3、新类型
(1)type Args []interface{}
(2)type Error string
4、接口
(1)Conn
(2)ConnWithTimeout
(3)Scanner
(4)Argument
5、结构体
(1)DialOption
(2)Pool
(3)PoolStats
(4)Subscription
(5)PubSubConn
(6)Message
(7)Script
(8)Pong
6、函数
(1)func NewPool(newFn func() (Conn, error), maxIdle int) *Pool
(2)func NewScript(keyCount int, src string) *Script
(3)func NewLoggingConn(conn Conn, logger *log.Logger, prefix string) Conn
(4)func NewLoggingConnFilter(conn Conn, logger log.Logger, prefix string, skip func(cmdName string) bool) Conn
(5)func DoWithTimeout(c Conn, timeout time.Duration, cmd string, args ...interface{}) (interface{}, error)
(6)func DoWithTimeout(c Conn, timeout time.Duration, cmd string, args ...interface{}) (interface{}, error)
(7)func Int(reply interface{}, err error) (int, error)
(8)func Int64(reply interface{}, err error) (int64, error)
(9)func Uint64(reply interface{}, err error) (uint64, error)
(10)func Float64(reply interface{}, err error) (float64, error)
(11)func String(reply interface{}, err error) (string, error)
(12)func Bytes(reply interface{}, err error) ([]byte, error)
(13)func Bool(reply interface{}, err error) (bool, error)
(14)func MultiBulk(reply interface{}, err error) ([]interface{}, error)
(15)func Values(reply interface{}, err error) ([]interface{}, error)
(16)func Float64s(reply interface{}, err error) ([]float64, error)
(17)func Strings(reply interface{}, err error) ([]string, error)
(18)func ByteSlices(reply interface{}, err error) ([][]byte, error)
(19)func Int64s(reply interface{}, err error) ([]int64, error)
(20)func Ints(reply interface{}, err error) ([]int, error)
(21)func StringMap(result interface{}, err error) (map[string]string, error)
(22)func IntMap(result interface{}, err error) (map[string]int, error)
(23)func Int64Map(result interface{}, err error) (map[string]int64, error)
(24)func Positions(result interface{}, err error) ([][2]float64, error)
(25)func DialTimeout(network, address string, connectTimeout, readTimeout, writeTimeout time.Duration) (Conn, error)
(26)func DialReadTimeout(d time.Duration) DialOption
(27)func DialWriteTimeout(d time.Duration) DialOption
(28)func DialConnectTimeout(d time.Duration) DialOption
(29)func DialKeepAlive(d time.Duration) DialOption
(30)func DialNetDial(dial func(network, addr string) (net.Conn, error)) DialOption
(31)func DialDatabase(db int) DialOption
(32)func DialPassword(password string) DialOption
(33)func DialTLSConfig(c *tls.Config) DialOption
(34)func DialTLSSkipVerify(skip bool) DialOption

一、变量
var ErrNil = errors.New("redigo: nil returned")
暴露给开发者的目的是,因为从redis服务器获取数据的时候可能遇到值为空的情况。
二、常量
三、新类型
(1)type Args []interface{}

  1type Args []interface{}
  2
  3func (args Args) Add(value ...interface{}) Args
  4// Add是直接将值追加到args后面的结果返回,但是并不会修改到args
  5func (args Args) AddFlat(v interface{}) Args 
  6// AddFlat根据值的类型存储,分为以下五种情况:Struct、Slice、Map、Ptr、其他类型
  7(1)Struct:
  8package main
  9
 10import (
 11    "fmt"
 12    "github.com/gomodule/redigo/redis"
 13)
 14
 15type Ints struct {
 16    A int
 17    b int
 18    C float32
 19}
 20
 21func (Ints)Add() {
 22    fmt.Println(123)
 23}
 24
 25func main() {
 26    i := Ints{1,2,1.2}
 27    args := redis.Args{1,2,3}
 28    args1 := args.AddFlat(i)
 29    fmt.Println(args, len(args))
 30    fmt.Println(args1, len(args1))
 31}
 32输出:
 33[1 2 3] 3
 34[1 2 3 A 1 C 1.2] 7
 35(2)Slice:
 36package main
 37
 38import (
 39    "fmt"
 40    "github.com/gomodule/redigo/redis"
 41)
 42
 43func main() {
 44    i := []int{1,2,12}
 45    args := redis.Args{1,2,3}
 46    args1 := args.AddFlat(i)
 47    fmt.Println(args, len(args))
 48    fmt.Println(args1, len(args1))
 49}
 50输出:
 51[1 2 3] 3
 52[1 2 3 1 2 12] 6
 53(3)Map:
 54package main
 55
 56import (
 57    "fmt"
 58    "github.com/gomodule/redigo/redis"
 59)
 60
 61func main() {
 62    i := map[int]string{1:"你好",2:"测试"}
 63    args := redis.Args{1,2,3}
 64    args1 := args.AddFlat(i)
 65    fmt.Println(args, len(args))
 66    fmt.Println(args1, len(args1))
 67}
 68输出:
 69[1 2 3] 3
 70[1 2 3 1 你好 2 测试] 7
 71(4)Prt
 72package main
 73
 74import (
 75    "fmt"
 76    "github.com/gomodule/redigo/redis"
 77)
 78
 79func main() {
 80    a := 123
 81    i := &a
 82    args := redis.Args{1,2,3}
 83    args1 := args.AddFlat(i)
 84    fmt.Println(args, len(args))
 85    fmt.Println(args1, len(args1))
 86}
 87输出:
 88[1 2 3] 3
 89[1 2 3 0xc00008a2d8] 4
 90(5)其他类型:
 91package main
 92
 93import (
 94    "fmt"
 95    "github.com/gomodule/redigo/redis"
 96)
 97
 98type Int int8
 99
100func main() {
101    a := 123
102    b := Int(8)
103    args := redis.Args{1,2,3}
104    args1 := args.AddFlat(a)
105    args1 = args1.AddFlat(b)
106    fmt.Println(args, len(args))
107    fmt.Println(args1, len(args1))
108}
109输出:
110[1 2 3] 3
111[1 2 3 123 8] 5

(2)type Error string

1type Error string
2func (err Error) Error() string { return string(err) }

四、接口
(1)Conn
(2)ConnWithTimeout
(3)Scanner
(4)Argument
五、结构体
(1)DialOption
源码:

1type DialOption struct {
2    f func(*dialOptions)
3}
4

作用:该结构体是被设计成 当创建与redis服务器连接时,进行参数设置。
与该结构体有关的函数:

 1(1)func DialReadTimeout(d time.Duration) DialOption
 2设置读超时时间
 3(2)func DialWriteTimeout(d time.Duration) DialOption
 4设置读超时时间
 5(3)func DialConnectTimeout(d time.Duration) DialOption
 6设置连接超时时间
 7(4)func DialKeepAlive(d time.Duration) DialOption 
 8(5)func DialNetDial(dial func(network, addr string) (net.Conn, error)) DialOption
 9(6)func DialDatabase(db int) DialOption
10设置连接数据库
11(7)func DialPassword(password string) DialOption
12设置连接redis密码
13(8)func DialTLSConfig(c *tls.Config) DialOption
14设置TLS配置信息
15(9)func DialTLSSkipVerify(skip bool) DialOption
16是否跳过TLS验证
17(10)func DialUseTLS(useTLS bool) DialOption
18是否使用TLS
19

(2)Pool
源码:

 1type Pool struct {
 2    Dial func() (Conn, error)
 3    TestOnBorrow func(c Conn, t time.Time) error
 4    MaxIdle int
 5    MaxActive int
 6    IdleTimeout time.Duration
 7    Wait bool
 8    MaxConnLifetime time.Duration
 9    chInitialized uint32
10    mu     sync.Mutex 
11    closed bool 
12    active int 
13    ch     chan struct{} 
14    idle   idleList
15}

作用:用来管理redis连接池
相关函数:

 1(1)func NewPool(newFn func() (Conn, error), maxIdle int) *Pool
 2            创建一个连接池对象
 3(2)func (p *Pool) Get() Conn
 4            获取一个连接 
 5(3)func (p *Pool) Stats() PoolStats
 6            获取池的状态
 7(4)func (p *Pool) ActiveCount() int
 8            获取存活数量
 9(5)func (p *Pool) IdleCount() int
10            获取空闲数量
11(6)func (p *Pool) Close() error
12            关闭
13

(3)PoolStats
源码:

1type PoolStats struct {
2    ActiveCount int 
3    IdleCount int
4}

作用:记录redis池中存活连接数量和空闲连接数
(4)Subscription
源码:

1type Subscription struct {
2    Kind string          
3    Channel string  
4    Count int
5}

作用:Subscription用于订阅或取消订阅通知。
相关函数:

Demo:

 1package main
 2
 3import (
 4    "fmt"
 5    "github.com/gomodule/redigo/redis"
 6    "log"
 7    "reflect"
 8)
 9
10func main() {
11    rc, err := redis.Dial("tcp", "127.0.0.1:6379")
12    if err != nil {
13        log.Fatalln(err)
14    }
15    defer rc.Close()
16
17    rc.Send("SUBSCRIBE", "example")
18    rc.Flush()
19    for {
20        reply, err := redis.Values(rc.Receive())
21        if err != nil {
22            fmt.Println(err)
23        }
24        if len(reply) == 3 {
25            if reflect.TypeOf(reply[2]).String() == "[]uint8" {
26                fmt.Println(string(reply[2].([]byte)))
27            }
28        }
29    }
30}

(5)PubSubConn
源码:


1type PubSubConn struct {
2    Conn Conn
3}

相关函数:

1(1)func (c PubSubConn) Subscribe(channel ...interface{}) error
 2            订阅给定的一个或多个频道的信息。
 3(2)func (c PubSubConn) PSubscribe(channel ...interface{}) error
 4            订阅一个或多个符合给定模式的频道。
 5(3)func (c PubSubConn) Unsubscribe(channel ...interface{}) error
 6            指退订给定的频道。
 7(4)func (c PubSubConn) PUnsubscribe(channel ...interface{}) error
 8            退订所有给定模式的频道。
 9(5)func (c PubSubConn) Ping(data string) error 
10            测试客户端是否能够继续连通
11(6)func (c PubSubConn) Receive() interface{}
12             获取回复信息
13(7)func (c PubSubConn) ReceiveWithTimeout(timeout time.Duration) interface{}
14             在指定时间内获取时间
15(8)func (c PubSubConn) Close() error 
16              关闭
17

(6)Message
源码:


1type Message struct {
2    Channel string    // 频道名称
3    Pattern string      // 频道模式
4    Data []byte            // 数据
5}

(7)Script
源码:

1type Script struct {
2    keyCount int
3    src               string
4    hash           string
5}

相关函数:

1(1)func NewScript(keyCount int, src string) *Script 
2(2)func (s *Script) Hash() string
3(3)func (s *Script) Do(c Conn, keysAndArgs ...interface{}) (interface{}, error) 
4(4)func (s *Script) SendHash(c Conn, keysAndArgs ...interface{}) error 
5(5)func (s *Script) Send(c Conn, keysAndArgs ...interface{}) error 
6(6)func (s *Script) Load(c Conn) error
7

(8)Pong
源码:

1type Pong struct {
2    Data string
3}

(6)函数

 1(1)func NewPool(newFn func() (Conn, error), maxIdle int) *Pool
 2(2)func NewScript(keyCount int, src string) *Script 
 3(3)func NewLoggingConn(conn Conn, logger *log.Logger, prefix string) Conn
 4(4)func NewLoggingConnFilter(conn Conn, logger *log.Logger, prefix string, skip func(cmdName string) bool) Conn
 5(5)func DoWithTimeout(c Conn, timeout time.Duration, cmd string, args ...interface{}) (interface{}, error)
 6(6)func DoWithTimeout(c Conn, timeout time.Duration, cmd string, args ...interface{}) (interface{}, error)
 7(7)func Int(reply interface{}, err error) (int, error)
 8(8)func Int64(reply interface{}, err error) (int64, error)
 9(9)func Uint64(reply interface{}, err error) (uint64, error)
10(10)func Float64(reply interface{}, err error) (float64, error)
11(11)func String(reply interface{}, err error) (string, error)
12(12)func Bytes(reply interface{}, err error) ([]byte, error)
13(13)func Bool(reply interface{}, err error) (bool, error) 
14(14)func MultiBulk(reply interface{}, err error) ([]interface{}, error) 
15(15)func Values(reply interface{}, err error) ([]interface{}, error)
16(16)func Float64s(reply interface{}, err error) ([]float64, error)
17(17)func Strings(reply interface{}, err error) ([]string, error) 
18(18)func ByteSlices(reply interface{}, err error) ([][]byte, error)
19(19)func Int64s(reply interface{}, err error) ([]int64, error)
20(20)func Ints(reply interface{}, err error) ([]int, error)
21(21)func StringMap(result interface{}, err error) (map[string]string, error) 
22(22)func IntMap(result interface{}, err error) (map[string]int, error)
23(23)func Int64Map(result interface{}, err error) (map[string]int64, error)
24(24)func Positions(result interface{}, err error) ([]*[2]float64, error)
25(25)func DialTimeout(network, address string, connectTimeout, readTimeout, writeTimeout time.Duration) (Conn, error) 
26(26)func DialReadTimeout(d time.Duration) DialOption
27(27)func DialWriteTimeout(d time.Duration) DialOption
28(28)func DialConnectTimeout(d time.Duration) DialOption
29(29)func DialKeepAlive(d time.Duration) DialOption 
30(30)func DialNetDial(dial func(network, addr string) (net.Conn, error)) DialOption
31(31)func DialDatabase(db int) DialOption
32(32)func DialPassword(password string) DialOption
33(33)func DialTLSConfig(c *tls.Config) DialOption
34(34)func DialTLSSkipVerify(skip bool) DialOption
35

经过学习源码发现,这些顶尖的设计者与我们普通开发者的区别在于,他们包设计非常巧妙,以及只把有必要的内容提供给开发者。

原文发布时间为:2019-1-5
本文作者:Golang语言社区
本文来自云栖社区合作伙伴“ Golang语言社区”,了解相关信息可以关注“Golangweb”微信公众号

相关实践学习
基于Redis实现在线游戏积分排行榜
本场景将介绍如何基于Redis数据库实现在线游戏中的游戏玩家积分排行榜功能。
云数据库 Redis 版使用教程
云数据库Redis版是兼容Redis协议标准的、提供持久化的内存数据库服务,基于高可靠双机热备架构及可无缝扩展的集群架构,满足高读写性能场景及容量需弹性变配的业务需求。 产品详情:https://www.aliyun.com/product/kvstore     ------------------------------------------------------------------------- 阿里云数据库体验:数据库上云实战 开发者云会免费提供一台带自建MySQL的源数据库 ECS 实例和一台目标数据库 RDS实例。跟着指引,您可以一步步实现将ECS自建数据库迁移到目标数据库RDS。 点击下方链接,领取免费ECS&RDS资源,30分钟完成数据库上云实战!https://developer.aliyun.com/adc/scenario/51eefbd1894e42f6bb9acacadd3f9121?spm=a2c6h.13788135.J_3257954370.9.4ba85f24utseFl
相关文章
|
2天前
|
监控 算法 Go
Golang深入浅出之-Go语言中的服务熔断、降级与限流策略
【5月更文挑战第4天】本文探讨了分布式系统中保障稳定性的重要策略:服务熔断、降级和限流。服务熔断通过快速失败和暂停故障服务调用来保护系统;服务降级在压力大时提供有限功能以保持整体可用性;限流控制访问频率,防止过载。文中列举了常见问题、解决方案,并提供了Go语言实现示例。合理应用这些策略能增强系统韧性和可用性。
22 0
|
16小时前
|
分布式计算 Java Go
Golang深入浅出之-Go语言中的分布式计算框架Apache Beam
【5月更文挑战第6天】Apache Beam是一个统一的编程模型,适用于批处理和流处理,主要支持Java和Python,但也提供实验性的Go SDK。Go SDK的基本概念包括`PTransform`、`PCollection`和`Pipeline`。在使用中,需注意类型转换、窗口和触发器配置、资源管理和错误处理。尽管Go SDK文档有限,生态系统尚不成熟,且性能可能不高,但它仍为分布式计算提供了可移植的解决方案。通过理解和掌握Beam模型,开发者能编写高效的数据处理程序。
88 1
|
18小时前
|
NoSQL 算法 Go
Go语言中的分布式事务处理方案
【5月更文挑战第6天】本文探讨了Go语言在分布式事务处理中的应用,包括2PC、3PC和TCC协议。通过示例展示了如何使用Go的`goroutine`和`channel`实现2PC。同时,文章指出了网络延迟、单点故障、死锁和幂等性等常见问题,并提供了相应的解决策略。此外,还以Redis Redlock为例,展示了如何实现分布式锁。理解并实施这些方案对于构建高可用的分布式系统至关重要。
83 0
|
1天前
|
缓存 测试技术 持续交付
Golang深入浅出之-Go语言中的持续集成与持续部署(CI/CD)
【5月更文挑战第5天】本文介绍了Go语言项目中的CI/CD实践,包括持续集成与持续部署的基础知识,常见问题及解决策略。测试覆盖不足、版本不一致和构建时间过长是主要问题,可通过全面测试、统一依赖管理和利用缓存优化。文中还提供了使用GitHub Actions进行自动化测试和部署的示例,强调了持续优化CI/CD流程以适应项目需求的重要性。
33 1
|
1天前
|
Kubernetes Cloud Native Go
Golang深入浅出之-Go语言中的云原生开发:Kubernetes与Docker
【5月更文挑战第5天】本文探讨了Go语言在云原生开发中的应用,特别是在Kubernetes和Docker中的使用。Docker利用Go语言的性能和跨平台能力编写Dockerfile和构建镜像。Kubernetes,主要由Go语言编写,提供了方便的客户端库与集群交互。文章列举了Dockerfile编写、Kubernetes资源定义和服务发现的常见问题及解决方案,并给出了Go语言构建Docker镜像和与Kubernetes交互的代码示例。通过掌握这些技巧,开发者能更高效地进行云原生应用开发。
34 1
|
1天前
|
负载均衡 监控 Go
Golang深入浅出之-Go语言中的服务网格(Service Mesh)原理与应用
【5月更文挑战第5天】服务网格是处理服务间通信的基础设施层,常由数据平面(代理,如Envoy)和控制平面(管理配置)组成。本文讨论了服务发现、负载均衡和追踪等常见问题及其解决方案,并展示了使用Go语言实现Envoy sidecar配置的例子,强调Go语言在构建服务网格中的优势。服务网格能提升微服务的管理和可观测性,正确应对问题能构建更健壮的分布式系统。
20 1
|
2天前
|
消息中间件 Go API
Golang深入浅出之-Go语言中的微服务架构设计与实践
【5月更文挑战第4天】本文探讨了Go语言在微服务架构中的应用,强调了单一职责、标准化API、服务自治和容错设计等原则。同时,指出了过度拆分、服务通信复杂性、数据一致性和部署复杂性等常见问题,并提出了DDD拆分、使用成熟框架、事件驱动和配置管理与CI/CD的解决方案。文中还提供了使用Gin构建HTTP服务和gRPC进行服务间通信的示例。
17 0
|
2天前
|
Prometheus 监控 Cloud Native
Golang深入浅出之-Go语言中的分布式追踪与监控系统集成
【5月更文挑战第4天】本文探讨了Go语言中分布式追踪与监控的重要性,包括追踪的三个核心组件和监控系统集成。常见问题有追踪数据丢失、性能开销和监控指标不当。解决策略涉及使用OpenTracing或OpenTelemetry协议、采样策略以及聚焦关键指标。文中提供了OpenTelemetry和Prometheus的Go代码示例,强调全面可观测性对微服务架构的意义,并提示选择合适工具和策略以确保系统稳定高效。
17 5
|
2天前
|
负载均衡 算法 Go
Golang深入浅出之-Go语言中的服务注册与发现机制
【5月更文挑战第4天】本文探讨了Go语言中服务注册与发现的关键原理和实践,包括服务注册、心跳机制、一致性问题和负载均衡策略。示例代码演示了使用Consul进行服务注册和客户端发现服务的实现。在实际应用中,需要解决心跳失效、注册信息一致性和服务负载均衡等问题,以确保微服务架构的稳定性和效率。
15 3
|
2天前
|
中间件 Go
Go语言中的中间件设计与实现
【5月更文挑战第4天】Go语言中的中间件在HTTP请求处理中扮演重要角色,提供了一种插入逻辑层的方式,便于实现日志、认证和限流等功能,而不增加核心代码复杂性。中间件遵循`http.Handler`接口,通过函数组合实现。常见问题包括错误处理(确保中间件能正确处理并传递错误)和请求上下文管理(使用`context.Context`共享数据以避免并发问题)。通过理解中间件机制和最佳实践,可以构建更健壮的Web应用。
19 0