当前位置:   article > 正文

Golang操作Redis_golang 连接redis

golang 连接redis

Redis是一种流行的内存键值数据库,被广泛用于构建高性能的缓存和消息队列应用。本文将介绍如何通过go-redis访问redis。

1. 安装依赖

go get github.com/go-redis/redis
  • 1

golang 如何连接 redis

client := redis.NewClient(&redis.Options{
        Addr:     "localhost:6379", // redis地址
        Password: "",               // 密码
        DB:       0,                // 使用默认数据库
		ReadTimeout: 3,             // socket读取超时时间, 默认 3s
        WriteTimeout: 10,           // socket写超时时间
        MinRetryBackoff: 10 * time.Second,  // 最大重试时间间隔, 默认是 512ms; -1 表示关闭
})
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

提示:go-redis包自带了连接池,会自动维护redis连接,因此创建一次client即可,不要查询一次redis就关闭client。

Options参数详解

type Options struct {
    // 网络类型 tcp 或者 unix.
    // 默认是 tcp.
    Network string
    // redis地址,格式 host:port
    Addr string
	
    // 新建一个redis连接的时候,会回调这个函数
    OnConnect func(*Conn) error
    
    // redis密码,redis server没有设置可以为空。
    Password string
    
    // redis数据库,序号从0开始,默认是0,可以不用设置
    DB int
    
    // redis操作失败最大重试次数,默认不重试。
    MaxRetries int
    
    // 最小重试时间间隔. 默认是 8ms ; -1 表示关闭.
    MinRetryBackoff time.Duration    
    // 最大重试时间间隔. 默认是 512ms; -1 表示关闭.
    MaxRetryBackoff time.Duration
    
    // redis连接超时时间. 默认是 5 秒.
    DialTimeout time.Duration
    
    // socket读取超时时间. 默认 3 秒.
    ReadTimeout time.Duration    
    // socket写超时时间
    WriteTimeout time.Duration
    
    // redis连接池的最大连接数. 默认连接池大小等于 cpu个数 * 10
    PoolSize int
    
    // redis连接池最小空闲连接数.
    MinIdleConns int
    // redis连接最大的存活时间,默认不会关闭过时的连接.
    MaxConnAge time.Duration
    
    // 当你从redis连接池获取一个连接之后,连接池最多等待这个拿出去的连接多长时间。 默认是等待 ReadTimeout + 1 秒.
    PoolTimeout time.Duration
    // redis连接池多久会关闭一个空闲连接. 默认是 5 分钟. -1 则表示关闭这个配置项
    IdleTimeout time.Duration
    // 多长时间检测一下,空闲连接. 默认是 1 分钟. -1 表示关闭空闲连接检测
    IdleCheckFrequency time.Duration
    
    // 只读设置,如果设置为true, redis只能查询缓存不能更新。
    readOnly bool
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50

2. 基本的 set、get 操作

package main

import (
    "fmt"
    "github.com/go-redis/redis"
	"time"
)

/**
    安装依赖:
	    go get github.com/go-redis/redis
*/

// 创建redis客户端
func newClient() *redis.Client {
    client := redis.NewClient(&redis.Options{
        Addr:     "localhost:6379", // redis地址
        Password: "",               // 密码
        DB:       0,                // 使用默认数据库
		ReadTimeout: 3,             // socket读取超时时间, 默认 3s
        WriteTimeout: 10,           // socket写超时时间
        MinRetryBackoff: 10 * time.Second,  // 最大重试时间间隔, 默认是 512ms; -1 表示关闭
    })
    return client
}

func main() {
    // 创建redis客户端
    client := newClient()
    defer client.Close() 

    // 设置 key, 第三个参数代表key的过期时间, 0代表不会过期
    err := client.Set("name", "john", 0).Err()
    if err != nil {
        panic(err)
    }
	// 设置过期时间 key
	// err := client.Set("key", "value", 100* time.Second ).Err()

    // 获取key
    val, err := client.Get("name").Result()
    if err != nil {
        panic(err)
    }
    fmt.Println("name", val)
	
	val2, err := rdb.Get("age").Result()
    // redis.Nil 表示这个key 在Redis中不存在
	if err == redis.Nil {
		fmt.Println("key2 does not exists")
	} else if err != nil {
		panic(err)
	} else {
		fmt.Println("key2", val2)
	}
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56

redis.NewClient 创建了一个Redis客户端。然后使用 set方法设置了一个key-value,之后使用get方法获取它的值。 Get的结果可能是 redis.Nil 表示这个key 在Redis中不存在。

3. hash 操作

  // Set hash field
  err := client.HSet( "myhash", "field1", "value1").Err()
  if err != nil {
    panic(err)
  }

  // Fetch hash field
  val, err := client.HGet("myhash", "field1").Result()
  if err != nil {
    panic(err)
  }
  fmt.Println("myhash field1:", val)

  // Delete hash field
  err = client.HDel( "myhash", "field1").Err()
  if err != nil {
    panic(err)
  }

  // Fetch all hash fields
  vals, err := client.HGetAll( "myhash").Result()
  if err != nil {
    panic(err)
  }
  fmt.Println("myhash:", vals)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25

4. pubsub发布订阅

package main

import (
    "fmt"
    "github.com/go-redis/redis"
)

func subscriber(client *redis.Client) {
    pubsub := client.Subscribe("mychannel")
    defer pubsub.Close()

    // 处理订阅接收到的消息
    for {
        msg, err := pubsub.ReceiveMessage()
        if err != nil {
            return
        }
        fmt.Println(msg.Channel, msg.Payload)
    }
}

func publisher(client *redis.Client) {
    for {
        // 发布消息到频道
        err := client.Publish("mychannel", "hello").Err()
        if err != nil {
            panic(err)
        }
    }
}

func main() {
    client := redis.NewClient(&redis.Options{
        Addr: "localhost:6379",
    })

    go subscriber(client)
    go publisher(client)

    <-make(chan struct{})
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41

使用 go-redis 可以方便地实现发布订阅模型:

  • 通过 client.Subscribe 订阅了一个频道,然后在循环里接收消息。
  • 另开一个 goroutine发布消息。

5. 消息队列示例

package main

import (
    "fmt"
    "math/rand"
    "time"
    "github.com/go-redis/redis"
)

var client *redis.Client 

// 初始化连接
func initClient() {
    client = redis.NewClient(&redis.Options{
        Addr:     "localhost:6379",
        Password: "", 
        DB:       0, 
    })
}

// 生产者 - 发布消息
func producer() {
    for {
        message := rand.Intn(1000)
        err := client.LPush("queue", message).Err()
        if err != nil {
            panic(err)
        }
        fmt.Println("pushed", message)
        time.Sleep(1 * time.Second)
    }
}

// 消费者 - 处理消息
func consumer(id int) {
    for {
        message, err := client.BRPop(0, "queue").Result()
        if err != nil {
            panic(err)
        }
        fmt.Printf("consumer%d popped %s \n", id, message[1])
        time.Sleep(500 * time.Millisecond)
    }
}

func main() {
    // 初始化
    initClient()
    // 生产者goroutine
    go producer()
    // 3个消费者goroutine
    for i := 0; i < 3; i++ {
        go consumer(i)
    }
    // 阻塞主goroutine
    <-make(chan struct{}) 
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57

使用BRPop实现阻塞式出队,LPush入队,可以构建基于Redis的消息队列。 多个消费者可以共享队列实现负载均衡。

更加详细的redis操作,见下一篇讲解 go-redis 的各种 API 使用。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/IT小白/article/detail/813712
推荐阅读
相关标签
  

闽ICP备14008679号