Начало работы с Golang Redis

Установка

Сначала вам нужно инициализировать модуль Go:

go mod init github.com/my/repo

Чтобы установить go-redis/v9:

go get github.com/redis/go-redis/v9

Подключение к серверу Redis

Чтобы подключиться к серверу Redis Server:

import "github.com/redis/go-redis/v9"

rdb := redis.NewClient(&redis.Options{
	Addr:	  "localhost:6379",
	Password: "", // no password set
	DB:		  0,  // use default DB
})

Другой популярный способ:

opt, err := redis.ParseURL("redis://<user>:<pass>@localhost:6379/<db>")
if err != nil {
	panic(err)
}

rdb := redis.NewClient(opt)

Использование TLS

Чтобы включить TLS/SSL, необходимо предоставить пустой файл tls.Config. Если вы используете частные сертификаты, вам необходимо указать их в tls.Config.

rdb := redis.NewClient(&redis.Options{
	TLSConfig: &tls.Config{
		MinVersion: tls.VersionTLS12,
		//Certificates: []tls.Certificate{cert}
	},
})

Если вы получаете x509: cannot validate certificate for xxx.xxx.xxx.xxx, потому что он не содержит никаких IP SAN, попробуйте установить параметр ServerName:

rdb := redis.NewClient(&redis.Options{
	TLSConfig: &tls.Config{
		MinVersion: tls.VersionTLS12,
		ServerName: "your.domain.com",
	},
})

Через SSH

Для подключения по каналу SSH:

sshConfig := &ssh.ClientConfig{
	User:			 "root",
	Auth:			 []ssh.AuthMethod{ssh.Password("password")},
	HostKeyCallback: ssh.InsecureIgnoreHostKey(),
	Timeout:		 15 * time.Second,
}

sshClient, err := ssh.Dial("tcp", "remoteIP:22", sshConfig)
if err != nil {
	panic(err)
}

rdb := redis.NewClient(&redis.Options{
	Addr: net.JoinHostPort("127.0.0.1", "6379"),
	Dialer: func(ctx context.Context, network, addr string) (net.Conn, error) {
		return sshClient.Dial(network, addr)
	},
	// Disable timeouts, because SSH does not support deadlines.
	ReadTimeout:  -1,
	WriteTimeout: -1,
})

dial tcp: i/o timeout

Вы получаете ошибку dial tcp: i/o timeout, когда go-redis не может подключиться к серверу Redis, например, когда сервер не работает или порт защищен брандмауэром. Чтобы проверить, прослушивает ли сервер Redis порт, выполните команду telnet на хосте, где запущен клиент go-redis:

telnet localhost 6379
Trying 127.0.0.1...
telnet: Unable to connect to remote host: Connection refused

Если вы используете Docker, Istio или любой другой сервис mesh / sidecar, убедитесь, что приложение запускается после того, как контейнер полностью доступен, например, настроив healthchecksopen in new window в Docker и holdApplicationUntilProxyStarts в Istio.

Контекст

Каждая команда Redis принимает контекст, который вы можете использовать для установки таймаутов или распространения какой-либо информации, например, контекст трассировки.

ctx := context.Background()

Выполнение команд

Чтобы выполнить команду:

val, err := rdb.Get(ctx, "key").Result()
fmt.Println(val)

В качестве альтернативы вы можете сохранить команду и позже получить доступ к значению и ошибке отдельно:

get := rdb.Get(ctx, "key")
fmt.Println(get.Val(), get.Err())

Выполнение неподдерживаемых команд

Для выполнения произвольной/настроенной команды:

val, err := rdb.Do(ctx, "get", "key").Result()
if err != nil {
	if err == redis.Nil {
		fmt.Println("key does not exists")
		return
	}
	panic(err)
}
fmt.Println(val.(string))

Do возвращает Cmdopen in new window, который имеет кучу помощников для работы со значением interface{}:

// Text is a shortcut for get.Val().(string) with proper error handling.
val, err := rdb.Do(ctx, "get", "key").Text()
fmt.Println(val, err)

Полный список помощников:

s, err := cmd.Text()
flag, err := cmd.Bool()

num, err := cmd.Int()
num, err := cmd.Int64()
num, err := cmd.Uint64()
num, err := cmd.Float32()
num, err := cmd.Float64()

ss, err := cmd.StringSlice()
ns, err := cmd.Int64Slice()
ns, err := cmd.Uint64Slice()
fs, err := cmd.Float32Slice()
fs, err := cmd.Float64Slice()
bs, err := cmd.BoolSlice()

redis.Nil

go-redis экспортирует ошибку redis.Nil и возвращает ее всякий раз, когда сервер Redis отвечает (nil). Вы можете использовать redis-cli, чтобы проверить, какой ответ возвращает Redis.

В следующем примере мы используем redis.Nil для различения ответа в виде пустой строки и ответа nil (ключ не существует):

val, err := rdb.Get(ctx, "key").Result()
switch {
case err == redis.Nil:
	fmt.Println("key does not exist")
case err != nil:
	fmt.Println("Get failed", err)
case val == "":
	fmt.Println("value is empty")
}

GET – не единственная команда, возвращающая нулевой ответ, например, BLPOP и ZSCORE также могут вернуть redis.Nil.

Conn

Conn представляет собой одно соединение Redis, а не пул соединений. Предпочтительнее выполнять команды из Client, если нет особой необходимости в непрерывном одиночном соединении Redis.

cn := rdb.Conn(ctx)
defer cn.Close()

if err := cn.ClientSetName(ctx, "myclient").Err(); err != nil {
	panic(err)
}

name, err := cn.ClientGetName(ctx).Result()
if err != nil {
	panic(err)
}
fmt.Println("client name", name)
+1
0
+1
1
+1
0
+1
0
+1
0

Ответить

Ваш адрес email не будет опубликован. Обязательные поля помечены *