我尝试轻松地用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里面…。还有很多学习的地方呢。
如果有错误的代码或者解释,请您指出来,我将不胜感激。