Redis
Redis はオープンソースで ANSI C 言語で書かれ、BSD プロトコルに準拠し、ネットワークをサポートし、メモリベース、分散型、オプションの永続性を備えたキーバリュー(Key-Value)ストレージデータベースです。複数の言語の API を提供し、Redis は NoSQL データベースとしても、高速キャッシュストレージとしても、シンプルなメッセージキューとしても使用できます。
この記事では Go 言語ドライバーを使用して Redis データベースを操作する方法を説明し、Redis 自体については説明しません。
公式ドキュメント:Golang Redis client (uptrace.dev)
公式リポジトリ:go-redis/redis: Type-safe Redis client for Golang (github.com)
インストール
Redis ドライバーには多くの種類がありますが、この記事では github.com/go-redis/redis を使用します。
Redis のバージョンが 6 の場合
go get github.com/go-redis/redis/v8Redis のバージョンが 7 の場合
go get github.com/go-redis/redis/v9クイックスタート
go
import (
"fmt"
"log"
"testing"
"github.com/go-redis/redis"
)
func TestQuickStart(t *testing.T) {
// Redis 接続クライアントを作成
redisClient := redis.NewClient(&redis.Options{
Addr: "192.168.48.134:6379",
Password: "123456",
DB: 0, // デフォルト DB を使用
})
// キーバリューを設定、0 は永久に有効期限なし
redisClient.Set("hello", "world", 0)
// 値を読み取り
result, err := redisClient.Get("hello").Result()
if err == redis.Nil {
fmt.Println("ket not exist")
} else if err != nil {
log.Panic(err)
}
fmt.Println(result)
}接続設定
go
type Options struct {
// ネットワークタイプ tcp または unix.
// デフォルトは tcp.
Network string
// redis アドレス、フォーマット host:port
Addr string
// 新しいネットワーク接続を作成する Dialer。Network と Addr オプションより優先度が高い
// Network and Addr options.
Dialer func() (net.Conn, error)
// 新しい redis 接続を作成する際にコールバックされる関数
OnConnect func(*Conn) error
// redis パスワード、redis server に設定されていない場合は空でも可
Password string
// redis データベース、0 から始まるシーケンス番号、デフォルトは 0、設定しなくても可
DB int
// redis 操作失敗時の最大リトライ回数、デフォルト 0。
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
// TLS 設定
TLSConfig *tls.Config
}接続の確立
go
// Redis 接続クライアントを作成
redisClient := redis.NewClient(&redis.Options{
Addr: "192.168.48.134:6379",
Password: "123456",
DB: 0, // デフォルト DB を使用
})接続の閉鎖
ドライバー内部で接続プールを管理しているため、操作ごとに接続を閉じる必要はありません。
go
defer redisClient.Close()この Redis ドライバーはほぼすべての操作をカプセル化しており、Redis コマンドとメソッド名が 1 対 1 に対応しています。基本的に Redis コマンドの使用方法を知っていれば、ドライバーの対応するメソッドもほぼ使用できます。
Redis コマンド:redis コマンドマニュアル
基本操作
キーの削除
go
redisClient.Set("name", "jack", 0)
fmt.Println(redisClient.Del("name").Result())有効期限
go
redisClient.Set("name", "jack", 0)
// 有効期限を設定
redisClient.Expire("name", time.Second*2)
fmt.Println(redisClient.Get("name").Val())
time.Sleep(time.Second * 3)
fmt.Println(redisClient.Get("name").Val())有効期限のキャンセル
go
redisClient.Set("name", "jack", 2)
// 有効期限をキャンセル
redisClient.Persist("name")
time.Sleep(time.Second * 2)
fmt.Println(redisClient.Get("name"))有効期限のクエリ
go
fmt.Println(redisClient.TTL("name"))
fmt.Println(redisClient.PTTL("name"))名前の変更
go
redisClient.Rename("name", "newName")タイプのクエリ
go
redisClient.Type("name")スキャン
go
fmt.Println(redisClient.Scan(0, "", 4))文字列
シンプルな保存と取得
go
redisClient.Set("token", "abcefghijklmn", 0)
fmt.Println(redisClient.Get("token").Val())バッチ保存と取得
go
redisClient.MSet("cookie", "12345", "token", "abcefg")
fmt.Println(redisClient.MGet("cookie", "token").Val())数値の増減
go
redisClient.Set("age", "1", 0)
// 自動増分
redisClient.Incr("age")
fmt.Println(redisClient.Get("age").Val())
// 自動減算
redisClient.Decr("age")
fmt.Println(redisClient.Get("age").Val())ハッシュテーブル
読み取り・書き込み操作
go
// 単一設定
redisClient.HSet("map", "name", "jack")
// バッチ設定
redisClient.HMSet("map", map[string]interface{}{"a": "b", "c": "d", "e": "f"})
// 単一アクセス
fmt.Println(redisClient.HGet("map", "a").Val())
// バッチアクセス
fmt.Println(redisClient.HMGet("map", "a", "b").Val())
// 全体の map を取得
fmt.Println(redisClient.HGetAll("map").Val())出力
b
[b <nil>]
map[a:b c:d e:f name:jack]キーの削除
go
// map のフィールドを 1 つ削除
redisClient.HDel("map", "a")キーの存在判断
go
// フィールドが存在するかどうかを判断
redisClient.HExists("map", "a")すべてのキーの取得
go
// map のすべてのキーを取得
redisClient.HKeys("map")ハッシュテーブルのキー長さの取得
go
// map の長さを取得
redisClient.HLen("map")ハッシュテーブルのキーバリューのトラバース
go
// map 内のキーバリューをトラバース
redisClient.HScan("map", 0, "", 1)リスト
要素の修正
go
// 左側に追加
redisClient.LPush("list", "a", "b", "c", "d", "e")
// 右側に追加
redisClient.RPush("list", "g", "i", "a")
// 参照値の前に値を挿入
redisClient.LInsertBefore("list", "a", "aa")
// 参照値の後に値を挿入
redisClient.LInsertAfter("list", "a", "gg")
// 指定インデックスの要素の値を設定
redisClient.LSet("list", 0, "head")長さのアクセス
go
// リストの長さにアクセス
redisClient.LLen("list")要素のアクセス
go
// 左側から要素をポップ
redisClient.LPop("list")
// 右側から要素をポップ
redisClient.RPop("list")
// 指定インデックスの要素にアクセス
redisClient.LIndex("list", 1)
// 指定範囲内の要素にアクセス
redisClient.LRange("list", 0, 1)要素の削除
go
// 指定要素を削除
redisClient.LRem("list", 0, "a")
// 指定範囲の要素を削除
redisClient.LTrim("list", 0, 1)
// 指定範囲の要素を保持
redisClient.LTrim("list", 0, 1)セット
要素の追加
go
// セット内に要素を追加
redisClient.SAdd("set", "a", "b", "c")
redisClient.SAdd("set2", "c", "d", "e")セット要素のアクセス
go
// セット内のすべてのメンバーを取得
redisClient.SMembers("set")
// 要素がセットに属しているかどうかを判断
redisClient.SIsMember("set", "a")
// ランダムに count 個の要素を返す
redisClient.SRandMemberN("set", 1)
// セットの要素数を取得
redisClient.SCard("set")セット操作
go
// 指定されたセットの差集合を返す
redisClient.SDiff("set", "set2")
// 指定されたセットの差集合を結果セットに保存し、結果セットの長さを返す
redisClient.SDiffStore("store", "set", "se2")
// 指定されたセットの共通部分を返す
redisClient.SInter("set", "set2")
// 指定されたセットの共通部分を結果セットに保存し、結果セットの長さを返す
redisClient.SInterStore("store", "set", "set2")
// 指定されたセットの和集合を返す
redisClient.SUnion("set", "set2")
// 指定されたセットの和集合を結果セットに保存し、結果セットの長さを返す
redisClient.SUnionStore("store", "set", "store")要素の削除
go
// ポップして要素を削除
redisClient.SPop("set")
// N 個の要素をポップして削除
redisClient.SPopN("set", 2)要素の移動
go
// ソースセットから指定要素をターゲットセットに移動
redisClient.SMove("set", "set2", "a")要素の削除
go
// 指定要素を削除
redisClient.SRem("set", "a", "b")トラバース
go
// セットをトラバース
redisClient.SScan("set", 0, "", 2)ソート済みセット
要素の追加
go
// ソート済みセットに要素を追加
redisClient.ZAdd("ss", redis.Z{
Score: 1,
Member: "a",
}, redis.Z{
Score: 2,
Member: "b",
})要素のランキング
go
// ソート済みセット内の要素のランキングを返す、低から高へ並列
redisClient.ZRank("ss", "1")
// ソート済みセット内の要素のランキングを返す、高から低へ並列
redisClient.ZRevRank("ss", "1")要素のアクセス
go
// min と max の間のメンバー数を返す
redisClient.ZCount("ss", "1", "2")
// 要素の重みを返す
redisClient.ZScore("ss", "a")
// 指定区間の要素を返す
redisClient.ZRange("ss", 1, 2)
// min と max の間のすべてのメンバーリストを返す
redisClient.ZRangeByScore("ss", redis.ZRangeBy{
Min: "1",
Max: "2",
Offset: 0,
Count: 1,
})重みの修正
go
// 対応する要素に重みを追加
redisClient.ZIncr("ss", redis.Z{
Score: 2,
Member: "b",
})要素の削除
go
// 指定要素を削除
redisClient.ZRem("ss", "a")
// 指定ランキング区間の要素を削除
redisClient.ZRemRangeByRank("ss", 1, 2)
// 重みが min と max の区間にある要素を削除
redisClient.ZRemRangeByScore("ss", "1", "2")スクリプト
go
// スクリプトをロードし、sha 値を返す
redisClient.ScriptLoad("return 0")
// sha 値に基づいてスクリプトを実行
redisClient.EvalSha("sha", []string{}, "")
// 直接スクリプトを実行
redisClient.Eval("return 0", []string{}, "")
// スクリプトキャッシュをクリア
redisClient.ScriptFlush()
// 現在実行中のスクリプトを停止
redisClient.ScriptKill()
// 対応するハッシュ値のスクリプトが存在するかどうかを検証
redisClient.ScriptExists("")公開・購読
go
// 指定チャンネルにメッセージを送信
redisClient.Publish("channel", "message")
// 指定チャンネルを購読
redisClient.Subscribe("channel")
// 購読ステータスを確認
redisClient.PubSubNumSub("channel")