go语言使用redis(redigo)

本文涉及的产品
Redis 开源版,标准版 2GB
推荐场景:
搭建游戏排行榜
云数据库 Tair(兼容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数据库实现在线游戏中的游戏玩家积分排行榜功能。
相关文章
|
7月前
|
编译器 Go
揭秘 Go 语言中空结构体的强大用法
Go 语言中的空结构体 `struct{}` 不包含任何字段,不占用内存空间。它在实际编程中有多种典型用法:1) 结合 map 实现集合(set)类型;2) 与 channel 搭配用于信号通知;3) 申请超大容量的 Slice 和 Array 以节省内存;4) 作为接口实现时明确表示不关注值。此外,需要注意的是,空结构体作为字段时可能会因内存对齐原因占用额外空间。建议将空结构体放在外层结构体的第一个字段以优化内存使用。
|
7月前
|
运维 监控 算法
监控局域网其他电脑:Go 语言迪杰斯特拉算法的高效应用
在信息化时代,监控局域网成为网络管理与安全防护的关键需求。本文探讨了迪杰斯特拉(Dijkstra)算法在监控局域网中的应用,通过计算最短路径优化数据传输和故障检测。文中提供了使用Go语言实现的代码例程,展示了如何高效地进行网络监控,确保局域网的稳定运行和数据安全。迪杰斯特拉算法能减少传输延迟和带宽消耗,及时发现并处理网络故障,适用于复杂网络环境下的管理和维护。
|
1月前
|
数据采集 Go API
Go语言实战案例:多协程并发下载网页内容
本文是《Go语言100个实战案例 · 网络与并发篇》第6篇,讲解如何使用 Goroutine 和 Channel 实现多协程并发抓取网页内容,提升网络请求效率。通过实战掌握高并发编程技巧,构建爬虫、内容聚合器等工具,涵盖 WaitGroup、超时控制、错误处理等核心知识点。
|
1月前
|
数据采集 JSON Go
Go语言实战案例:实现HTTP客户端请求并解析响应
本文是 Go 网络与并发实战系列的第 2 篇,详细介绍如何使用 Go 构建 HTTP 客户端,涵盖请求发送、响应解析、错误处理、Header 与 Body 提取等流程,并通过实战代码演示如何并发请求多个 URL,适合希望掌握 Go 网络编程基础的开发者。
|
2月前
|
JSON 前端开发 Go
Go语言实战:创建一个简单的 HTTP 服务器
本篇是《Go语言101实战》系列之一,讲解如何使用Go构建基础HTTP服务器。涵盖Go语言并发优势、HTTP服务搭建、路由处理、日志记录及测试方法,助你掌握高性能Web服务开发核心技能。
|
2月前
|
Go
如何在Go语言的HTTP请求中设置使用代理服务器
当使用特定的代理时,在某些情况下可能需要认证信息,认证信息可以在代理URL中提供,格式通常是:
196 0
|
3月前
|
JSON 编解码 API
Go语言网络编程:使用 net/http 构建 RESTful API
本章介绍如何使用 Go 语言的 `net/http` 标准库构建 RESTful API。内容涵盖 RESTful API 的基本概念及规范,包括 GET、POST、PUT 和 DELETE 方法的实现。通过定义用户数据结构和模拟数据库,逐步实现获取用户列表、创建用户、更新用户、删除用户的 HTTP 路由处理函数。同时提供辅助函数用于路径参数解析,并展示如何设置路由器启动服务。最后通过 curl 或 Postman 测试接口功能。章节总结了路由分发、JSON 编解码、方法区分、并发安全管理和路径参数解析等关键点,为更复杂需求推荐第三方框架如 Gin、Echo 和 Chi。
|
4月前
|
分布式计算 Go C++
初探Go语言RPC编程手法
总的来说,Go语言的RPC编程是一种强大的工具,让分布式计算变得简单如同本地计算。如果你还没有试过,不妨挑战一下这个新的编程领域,你可能会发现新的世界。
104 10
|
7月前
|
存储 Go
Go 语言入门指南:切片
Golang中的切片(Slice)是基于数组的动态序列,支持变长操作。它由指针、长度和容量三部分组成,底层引用一个连续的数组片段。切片提供灵活的增减元素功能,语法形式为`[]T`,其中T为元素类型。相比固定长度的数组,切片更常用,允许动态调整大小,并且多个切片可以共享同一底层数组。通过内置的`make`函数可创建指定长度和容量的切片。需要注意的是,切片不能直接比较,只能与`nil`比较,且空切片的长度为0。
170 3
Go 语言入门指南:切片
|
7月前
|
算法 安全 Go
公司局域网管理系统里的 Go 语言 Bloom Filter 算法,太值得深挖了
本文探讨了如何利用 Go 语言中的 Bloom Filter 算法提升公司局域网管理系统的性能。Bloom Filter 是一种高效的空间节省型数据结构,适用于快速判断元素是否存在于集合中。文中通过具体代码示例展示了如何在 Go 中实现 Bloom Filter,并应用于局域网的 IP 访问控制,显著提高系统响应速度和安全性。随着网络规模扩大和技术进步,持续优化算法和结合其他安全技术将是企业维持网络竞争力的关键。
142 2
公司局域网管理系统里的 Go 语言 Bloom Filter 算法,太值得深挖了