我尝试轻松地用Go操作Redis

首先

我想这可能是老生常谈的话题,但我还是整理了一下我的知识。
我将试着使用 Golang 来轻松操作 Redis。本文假设您已经安装了 Docker。

请采用以下方式改写:
环境如下。

    • macOS (ver 10.14)

 

    • Docker (ver 19.3.1)

 

    Golang (ver 1.12.7)

大致上,Redis 是什么?

    • 永続化可能なインメモリデータベース

 

    • KVS(Key Value Store)

 

    • 5つのデータ型をサポート

string / hash / list / set / sorted set

优点是什么?

    • 高速

 

    • シングルスレッドなので,必然的に処理が排他的になる

 

    • データの生存期間(TTL)が設定できる

 

    • ランキングの扱い

ソートをやってくれるデータ構造があるので.

请您参考以下内容。

参考一:

关于Redis,这篇文章非常详细,请务必阅读。
对于数据结构和命令,我觉得尝试一下TryRedis会更容易掌握感觉。

建立 Redis

首先,在 Docker 中准备 Redis。
使用的 Docker 镜像在这里。

$ docker run --name redis -d -p 6379:6379 redis redis-server --appendonly yes

在本地安装Redis。(在使用Go访问Redis时进行确认等情况下使用。)

$ brew install redis

如果达到以下情况,就可以了。

$ redis-cli
127.0.0.1:6379> 

让我们尝试一些Redis命令。

// key を全て取得
127.0.0.1:6379> KEYS *
(empty list or set)

// SET key value
127.0.0.1:6379> SET test-key test-val
OK

127.0.0.1:6379> KEYS *
1) "test-key"

// key の削除
127.0.0.1:6379> DEL test-key
(integer) 1

127.0.0.1:6379> KEYS *
(empty list or set)

127.0.0.1:6379> exit

尝试使用 Go 接触 Redis

终于到了主题。我们将轻松使用 Go 操作 Redis。我们将使用一个叫做 redigo 的包。

安装 redigo

go get github.com/gomodule/redigo/redis

实际尝试一下

    データの登録と取得
package main

import(
    "fmt"

    "github.com/gomodule/redigo/redis"
)

// Connection
func Connection() redis.Conn {
    const Addr = "127.0.0.1:6379"

    c, err := redis.Dial("tcp", Addr)
    if err != nil {
        panic(err)
    }
    return c
}

// データの登録(Redis: SET key value)
func Set(key, value string, c redis.Conn) string{
    res, err := redis.String(c.Do("SET", key, value))
    if err != nil {
        panic(err)
    }
    return res
}

// データの取得(Redis: GET key)
func Get(key string, c redis.Conn) string {
    res, err := redis.String(c.Do("GET", key))
    if err != nil {
        panic(err)
    }
    return res
}

func main() {
    // 接続
    c := Connection()
    defer c.Close()

    // データの登録(Redis: SET key value)
    res_set := Set("sample-key", "sample-value", c)
    fmt.Println(res_set) // OK

    // データの取得(Redis: GET key)
    res_get := Get("sample-key", c)
    fmt.Println(res_get) // sample-value
}
実行結果:
$ go run redis.go
OK
sample-value

Redis: 
127.0.0.1:6379> KEYS *
1) "sample-key"

当需要执行基本的Redis命令时,调用Do()函数。
Do()函数的返回值是interface{}和error类型,如果要进行类型转换,需要调用redis.String()。
根据包的代码,似乎可以将其转换为int、float64、byte等类型。调用方法类似redis.Int()。

    複数の値を同時に登録,取得.かつ TTL をつけてみる
package main

import(
    "fmt"

    "github.com/gomodule/redigo/redis"
)

// Connection
func Connection() redis.Conn {
    const Addr = "127.0.0.1:6379"

    c, err := redis.Dial("tcp", Addr)
    if err != nil {
        panic(err)
    }
    return c
}

type Data struct {
    Key string
    Value string
}

// 複数のデータの登録(Redis: MSET key [key...])
func Mset(datas []Data, c redis.Conn){
    var query []interface{}
    for _, v := range datas {
        query = append(query, v.Key, v.Value)
    }
    fmt.Println(query) // [key1 value1 key2 value2]

    c.Do("MSET", query...)
}

// 複数の値を取得 (Redis: MGET key [key...])
func Mget(keys []string, c redis.Conn) []string{
    var query []interface{}
    for _, v := range keys {
        query = append(query, v)
    }
    fmt.Println("MGET query:", query) // [key1 key2]

    res, err := redis.Strings(c.Do("MGET", query...))
    if err != nil {
        panic(err)
    }
    return res
}

// TTLの設定(Redis: EXPIRE key ttl)
func Expire(key string, ttl int, c redis.Conn) {
    c.Do("EXPIRE", key, ttl)
}

func main() {
    // 接続
    c := Connection()
    defer c.Close()

    // 複数データの登録
    datas := []Data{
        Data{Key:"key1", Value:"value1"},
        Data{Key:"key2", Value:"value2"},
    }
    Mset(datas, c)

    // 複数データの取得
    keys := []string{"key1", "key2"}
    res_mget := Mget(keys, c)
    fmt.Println(res_mget)

    // TTLの設定
    Expire("key1", 10, c)
}
実行結果:
$ go run redis.go
MSET query: [key1 value1 key2 value2]
MGET query: [key1 key2]
[value1 value2]

Redis:
127.0.0.1:6379> KEYS *
1) "sample-key"
2) "key2"
3) "key1"

Redis(10秒以上後):
127.0.0.1:6379> KEYS *
1) "sample-key"
2) "key2"

如果要获取多个值作为结果(本例中为MGET),并且需要进行类型转换,例如redis.Strings(),在末尾加上s。其他类型也是一样的,比如redis.Ints等。
关于TTL的设置,可以使用以秒为单位的EXPIRE进行设置,也可以使用以毫秒为单位的PEXPIRE进行设置。

在Redis中,可以通过TTL key来确认键值的过期时间。

127.0.0.1:6379> TTL key1
(integer) 4

127.0.0.1:6379> TTL key1
(integer) -2

127.0.0.1:6379> TTL key2
(integer) -1

关于结果,可以如下所示。

    • 0以上:残りのTTL

 

    • -1 :TTLが設定されていない場合

 

    -2 :key が存在しない場合

结束

感谢您读到这里!虽然内容有点长,但也有很多重复的部分,就到这里吧。
看了包的代码之后,感觉可以把Do()的结果存储在map里面…。还有很多学习的地方呢。
如果有错误的代码或者解释,请您指出来,我将不胜感激。

bannerAds