您的位置:

使用GoRedis轻松实现Redis功能

Redis(远程字典服务器)是一种高性能的内存键值型数据库。它可以作为多种应用程序的缓存、数据库、消息代理和排行榜等。而GoRedis是Golang实现的Redis客户端,增加了不少方便易用的特性。本文将从多个方面详细阐述GoRedis的使用。

一、连接Redis数据库

GoRedis的最基本用法是连接Redis数据库。连接可以使用以下两种方式:

import "github.com/go-redis/redis/v8"
func main() {
    rdb := redis.NewClient(&redis.Options{
        Addr:     "localhost:6379",
        Password: "", 
        DB:       0,  
    })

    pong, err := rdb.Ping(ctx).Result()
    fmt.Println(pong, err)
}

或者使用连接池:

func main() {
import (
    "context"
    "fmt"
    "time"

    "github.com/go-redis/redis/v8"
)

func main() {
    rdb := redis.NewClient(&redis.Options{
        Addr: "localhost:6379",
        DB:   0,
    })
    defer rdb.Close()

    ctx, cancel := context.WithTimeout(context.Background(), time.Second*5)
    defer cancel()

    pong, err := rdb.Ping(ctx).Result()
    fmt.Println(pong, err)


    poolSize := 10
    maxPoolSize := 30
    timeout := 2 * time.Second

    rdbPool := &redis.Pool{
        MaxIdle:     poolSize,
        MaxActive:   maxPoolSize,
        IdleTimeout: timeout,
        Dial: func() (redis.Conn, error) {
            conn, err := redis.Dial("tcp", "localhost:6379")
            if err != nil {
                return nil, err
            }
            return conn, nil
        },
    }

    defer rdbPool.Close()

    conn := rdbPool.Get()
    defer conn.Close()

    pong2, err := redis.String(conn.Do("PING"))
    fmt.Println(pong2, err)  
}

二、设置和获取过期时间

Redis的值可以设置过期时间,通过GoRedis也能轻易应用。使用TTL方法获取一个键的剩余过期时间,EXPIRE和EXPIREAT方法设置, DEL方法删除这个键值即可。

import "github.com/go-redis/redis/v8"
func main() {
    rdb := redis.NewClient(&redis.Options{
        Addr:     "localhost:6379",
        Password: "", 
        DB:       0,  
    })

    err := rdb.Set(ctx, "key", "value", time.Hour).Err()
    if err != nil {
        panic(err)
    }

    ttl, err := rdb.TTL(ctx, "key").Result()
    if err != nil {
        panic(err)
    }
    fmt.Println(ttl)     

    err = rdb.Expire(ctx, "key", time.Minute).Err()
    if err != nil {
        panic(err)
    }  

    err = rdb.ExpireAt(ctx, "key", time.Now().Add(24*time.Hour)).Err()
    if err != nil {
        panic(err)
    }

    n, err := rdb.Del(ctx, "key").Result()
    if err != nil {
        panic(err)
    }
    fmt.Println(n)     
}

三、GoRedis和Redis的数据类型匹配

Redis有多种数据类型,GoRedis也提供了对应的Go语言数据结构相应的API,相对应的数据类型包括:

字符串(Strings)

操作字符串可以使用GET方法获取整个字符串,SET方法设置。也可以使用SETEX方法设置带有过期时间的键值对,使用APPEND方法增加字符串长度。

哈希(Hashes)

对于哈希,可使用HSET方法设置,HMSET方法设置多组键值对。添加、删除和获取同理,并且通过HGETALL方法可以获得哈希表中所有的键值对。

列表(Lists)

对于列表,使用LPUSH方法可以在列表前面添加元素,使用RPUSH方法可以在列表尾部添加元素。

import "github.com/go-redis/redis/v8"
func main() {
    rdb := redis.NewClient(&redis.Options{
        Addr:     "localhost:6379",
        Password: "", 
        DB:       0,  
    })

    err := rdb.LPush(ctx, "key", "value", "value2").Err()
    if err != nil {
        panic(err)
    }

    err = rdb.RPush(ctx, "key", "value", "value2").Err()
    if err != nil {
        panic(err)
    }

    val, err := rdb.LPop(ctx, "key").Result()
    if err != nil {
        panic(err)
    }
    fmt.Println(val)            

    vals, err := rdb.LRange(ctx, "key", 0, -1).Result()
    if err != nil {
        panic(err)
    }

    for _, val := range vals {
        fmt.Println(val)
    }
}

集合(Sets)

对于集合,SET和SADD方法可以添加元素,SPOP方法可以删除并返回随机一个元素。

有序集合(Sorted Sets)

对于有序集合,ZADD方法可以添加有序元素的成员和score值,ZRANGE和ZREVRANGE获取对应元素的区间。

import "github.com/go-redis/redis/v8"
func main() {
    rdb := redis.NewClient(&redis.Options{
        Addr:     "localhost:6379",
        Password: "", 
        DB:       0,  
    })

    err := rdb.ZAdd(ctx, "key", &redis.Z{Score: 1, Member: "value1"}, &redis.Z{Score: 2, Member: "value2"}).Err()
    if err != nil {
        panic(err)
    }

    vals, err := rdb.ZRange(ctx, "key", 0, -1).Result()
    if err != nil {
        panic(err)
    }
    fmt.Println(vals)            

    vals, err = rdb.ZRevRange(ctx, "key", 0, -1).Result()
    if err != nil {
        panic(err)
    }
    fmt.Println(vals)            
}

四、GoRedis的一些高级特性

事务(Transactions)

在GoRedis中,MULTI,EXEC,WATCH方法可以实现事务操作。首先使用WATCH方法监视某个值,当这个值发生变化时,MULTI方法之间的代码块才会执行,而EXEC方法会执行MULTI方法块内的所有操作。

import "github.com/go-redis/redis/v8"
func main() {
    rdb := redis.NewClient(&redis.Options{
        Addr:     "localhost:6379",
        Password: "", 
        DB:       0,  
    })

    err := rdb.Watch(ctx, func(tx *redis.Tx) error {
        v, err := tx.Get(ctx, "key").Result()
        if err != nil {
            return err
        }

        new := v + "bar"
        _, err = tx.TxPipelined(ctx, func(pipe redis.Pipeliner) error {
            pipe.Set(ctx, "key", new, 0)
            return nil
        })
        if err != nil {
            return err
        }

        return nil
    }, "key")

    if err != nil {
        panic(err)
    }
}

发布和订阅(Pub/Sub)

GoRedis也支持Redis中的发布和订阅功能。通过Subscrip和Subscribe方法,连接到频道并接收消息。使用Publish方法发布数据。

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

func main() {
    ctx := context.Background()
    rdb := redis.NewClient(&redis.Options{
        Addr:     "localhost:6379",
        Password: "",  
        DB:       0, 
    })

    pubsub := rdb.Subscribe(ctx, "channel1")

    _, err := pubsub.Receive(ctx)  
    if err != nil {
        panic(err)
    }

    ch := pubsub.Channel()

    go func() {
        for msg := range ch {
            fmt.Println(msg.Channel, msg.Payload)
        }
    }()

    err = rdb.Publish(ctx, "channel1", "hello").Err()
    if err != nil {
        panic(err)
    }

    time.Sleep(time.Second)

    _ = pubsub.Close()
    _ = rdb.Close()
}

管道(Pipeline)

GoRedis的另一个高级功能是管道。使用该功能可将多个Redis操作组合成一组命令,可以显著减少网络延迟,并在秒级别执行这些操作。

import "github.com/go-redis/redis/v8"
func main() {
    rdb := redis.NewClient(&redis.Options{
        Addr:     "localhost:6379",
        Password: "", 
        DB:       0,  
    })

    pipe := rdb.Pipeline()

    incr := pipe.Incr(ctx, "pipeline_counter")
    pipe.Expire(ctx, "pipeline_counter", time.Hour)
    _, err := pipe.Exec(ctx)
    if err != nil {
        panic(err)
    }

    fmt.Println(incr.Val()) 
}

结论

本文从连接Redis数据库,设置和获取过期时间,GoRedis和Redis的数据类型匹配,GoRedis的一些高级特性等方面详细阐述了GoRedis的使用方法。GoRedis不仅支持Redis的基本操作,还提供了一些高级特性,如事务、发布和订阅、管道等。