Подключение к базе данных в кластере Redis
Способы подключения
К хосту базы данных Redis можно подключиться двумя способами:
- Напрямую через порт
6379
. - C использованием Redis Sentinel через порт
26379
. Это система управления хостами Redis с возможностями мониторинга, отправки уведомлений о состояниях хостов, переключения мастера и передачи клиентам актуальных адресов хостов.
Не все клиентские приложения Redis поддерживают подключение через Sentinel. В этом случае вы можете подключиться к хосту напрямую. Обратите внимание, что при этом вам придется самостоятельно отслеживать роли всех хостов. Если в прямом подключении нет необходимости, используйте Sentinel для более надежной работы с хостами кластера.
Подключение к кластеру
Хостам кластера Redis нельзя назначать публичные IP-адреса. Доступ к хостам возможен только из той же виртуальной сети, в которой находится хост.
Чтобы подключиться к хосту кластера Redis:
- Создайте виртуальную машину с публичным IP-адресом в той же виртуальной сети, что и хост.
- Подключитесь к созданной виртуальной машине через через SSH и из нее подключитесь к Redis с помощью одного из примеров строк подключений.
Примеры строк подключения
Примеры проверялись в следующем окружении:
- Виртуальная машина в Облаке c Ubuntu 20.04 LTS.
- Bash:
5.0.16
. - Python:
3.8.2
; pip3:20.0.2
. - PHP:
7.4.3
. - OpenJDK:
11.0.8
; Maven:3.6.3
. - Node.JS:
10.19.0
, npm:6.14.4
. - Go:
1.13.8
. - Ruby:
2.7.0p0
. - unixODBC:
2.3.6
.
Приведены примеры строк как для подключения с Sentinel, так и для подключения напрямую.
Пример команды с заполненным FQDN хоста вы можете посмотреть в консоли управления, нажав на кнопку Подключиться на странице кластера.
Перед подключением установите зависимости:
sudo apt update && sudo apt install -y redis-tools
Подключение с помощью Sentinel:
-
Получите адрес хоста-мастера, используя Sentinel и любой хост Redis:
redis-cli -h <FQDN любого хоста Redis> -p 26379 sentinel get-master-addr-by-name <имя кластера Redis> | head -n 1
-
Подключитесь к хосту с этим адресом:
redis-cli -с -h <адрес хоста-мастера Redis> -a <пароль Redis>
Подключение напрямую к мастеру:
redis-cli -c -h <FQDN хоста-мастера Redis> -a <пароль>
После подключения к кластеру выполните команды:
SET foo bar
GET foo
Перед подключением установите зависимости:
sudo apt update && sudo apt install -y python3 python3-pip && \
pip3 install redis
Пример кода для подключения с помощью Sentinel:
connect.py
from redis.sentinel import Sentinel
sentinels = ['<FQDN хоста 1 Redis>',
...
'<FQDN хоста N Redis>']
name = '<имя кластера Redis>'
pwd = '<пароль>'
sentinel = Sentinel([(h, 26379) for h in sentinels], socket_timeout=0.1)
master = sentinel.master_for(name, password=pwd)
slave = sentinel.slave_for(name, password=pwd)
master.set('foo', 'bar')
print(slave.get('foo'))
Пример кода для подключения напрямую к мастеру:
connect.py
import redis
r = redis.StrictRedis(
host='<FQDN хоста-мастера Redis>',
port=6379,
password='<пароль>',
)
r.set('foo', 'bar')
print(r.get('foo'))
Подключение:
python3 connect.py
Перед подключением установите зависимости:
sudo apt update && sudo apt install -y php php-dev php-pear && \
sudo pear channel-discover pear.nrk.io && \
sudo pear install nrk/Predis
Пример кода для подключения с помощью Sentinel:
connect.php
<?php
require 'Predis/Autoloader.php';
Predis\Autoloader::register();
$sentinels = ['<FQDN хоста 1 Redis>:26379>',...,'<FQDN хоста N Redis>:26379>'];
$options = [
'replication' => 'sentinel',
'service' => '<имя кластера Redis>',
'parameters' => [
'password' => '<пароль>'
]
];
$conn = new Predis\Client($sentinels, $options);
$conn->set('foo', 'bar');
var_dump($conn->get('foo'));
$conn->disconnect();
?>
Пример кода для подключения напрямую к мастеру:
connect.php
<?php
require 'Predis/Autoloader.php';
Predis\Autoloader::register();
$host = ['<FQDN хоста-мастера Redis>:6379'];
$options = [
'parameters' => [
'password' => '<пароль>'
]
];
$conn = new Predis\Client($host, $options);
$conn->set('foo', 'bar');
var_dump($conn->get('foo'));
$conn->disconnect();
?>
Подключение:
php connect.php
Перед подключением:
-
Установите зависимости:
sudo apt update && sudo apt install -y default-jdk maven
-
Создайте директорию для проекта Maven:
cd ~/ && mkdir -p project/src/java/com/example && cd project/
-
Создайте конфигурационный файл для Maven:
pom.xml<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.example</groupId> <artifactId>app</artifactId> <packaging>jar</packaging> <version>0.1.0</version> <properties> <maven.compiler.source>1.8</maven.compiler.source> <maven.compiler.target>1.8</maven.compiler.target> </properties> <dependencies> <dependency> <groupId>redis.clients</groupId> <artifactId>jedis</artifactId> <version>3.3.0</version> </dependency> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-simple</artifactId> <version>1.7.30</version> </dependency> </dependencies> <build> <finalName>${project.artifactId}-${project.version}</finalName> <sourceDirectory>src</sourceDirectory> <resources> <resource> <directory>src</directory> </resource> </resources> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-assembly-plugin</artifactId> <executions> <execution> <goals> <goal>attached</goal> </goals> <phase>package</phase> <configuration> <descriptorRefs> <descriptorRef>jar-with-dependencies</descriptorRef> </descriptorRefs> <archive> <manifest> <mainClass>com.example.App</mainClass> </manifest> </archive> </configuration> </execution> </executions> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-jar-plugin</artifactId> <version>3.1.0</version> <configuration> <archive> <manifest> <mainClass>com.example.App</mainClass> </manifest> </archive> </configuration> </plugin> </plugins> </build> </project>
Актуальные версии зависимостей для Maven:
Пример кода для подключения с помощью Sentinel:
src/java/com/example/App.java
package com.example;
import java.util.HashSet;
import redis.clients.jedis.JedisSentinelPool;
import redis.clients.jedis.Jedis;
public class App {
public static void main(String[] args) {
String redisName = "<имя кластера Redis>";
String redisPass = "<пароль>";
HashSet sentinels = new HashSet();
sentinels.add("<FQDN хоста 1 Redis>:26379");
...
sentinels.add("<FQDN хоста N Redis>:26379");
try {
JedisSentinelPool pool = new JedisSentinelPool(redisName, sentinels);
Jedis conn = pool.getResource();
conn.auth(redisPass);
conn.set("foo", "bar");
System.out.println(conn.get("foo"));
pool.close();
}
catch(Exception ex) {ex.printStackTrace();}
}
}
Пример кода для подключения напрямую к мастеру:
src/java/com/example/App.java
package com.example;
import redis.clients.jedis.Jedis;
public class App {
public static void main(String[] args) {
String redisHost = "<FQDN хоста-мастера Redis>";
String redisPass = "<пароль>";
try {
Jedis conn = new Jedis(redisHost);
conn.auth(redisPass);
conn.set("foo", "bar");
System.out.println(conn.get("foo"));
conn.close();
}
catch(Exception ex) {ex.printStackTrace();}
}
}
Подключение:
mvn clean package && \
java -jar target/app-0.1.0-jar-with-dependencies.jar
Перед подключением установите зависимости:
sudo apt update && sudo apt install -y nodejs npm && \
npm install ioredis
Пример кода для подключения с помощью Sentinel:
app.js
"use strict"
const Redis = require('ioredis');
const conn = new Redis({
sentinels: [
{ host: "<FQDN хоста 1 Redis>", port: 26379 },
...,
{ host: "<FQDN хоста N Redis>", port: 26379 },
],
name: "<имя кластера Redis>",
password: "<пароль>",
});
conn.set("foo", "bar", function (err) {
if (err) {
console.error(err);
conn.disconnect();
}
});
conn.get("foo", function (err, result) {
if (err) {
console.error(err);
} else {
console.log(result);
}
conn.disconnect();
});
Пример кода для подключения напрямую к мастеру:
app.js
"use strict"
const Redis = require('ioredis');
const conn = new Redis({
host: "<FQDN хоста-мастера Redis>",
port: 6379,
password: "<пароль>",
});
conn.set("foo", "bar", function (err) {
if (err) {
console.error(err);
conn.disconnect();
}
});
conn.get("foo", function (err, result) {
if (err) {
console.error(err);
} else {
console.log(result);
}
conn.disconnect();
});
Подключение:
node app.js
Перед подключением установите зависимости:
sudo apt update && sudo apt install -y golang git && \
go mod init github.com/go-redis/redis && \
go get github.com/go-redis/redis/v7
Пример кода для подключения с помощью Sentinel:
connect.go
package main
import (
"fmt"
"github.com/go-redis/redis/v7"
)
func main() {
conn := redis.NewUniversalClient(
&redis.UniversalOptions{
Addrs: []string{
"<FQDN хоста 1 Redis>:26379",
...,
"<FQDN хоста N Redis>:26379"},
MasterName: "<имя кластера Redis>",
Password: "<пароль>",
ReadOnly: false,
},
)
err := conn.Set("foo", "bar", 0).Err()
if err != nil {
panic(err)
}
result, err := conn.Get("foo").Result()
if err != nil {
panic(err)
}
fmt.Println(result)
conn.Close()
}
Пример кода для подключения напрямую к мастеру:
connect.go
package main
import (
"fmt"
"github.com/go-redis/redis/v7"
)
func main() {
conn := redis.NewUniversalClient(
&redis.UniversalOptions{
Addrs: []string{ "<FQDN хоста-мастера Redis>:6379" },
Password: "<пароль>",
ReadOnly: false,
},
)
err := conn.Set("foo", "bar", 0).Err()
if err != nil {
panic(err)
}
result, err := conn.Get("foo").Result()
if err != nil {
panic(err)
}
fmt.Println(result)
conn.Close()
}
Подключение:
go run connect.go
Перед подключением установите зависимости:
sudo apt update && sudo apt install -y ruby && \
sudo gem install redis
Пример кода для подключения с помощью Sentinel:
connect.rb
require "redis"
SENTINELS = [{host: "<FQDN хоста 1 Redis>", port: 26379},
...,
{host: "<FQDN хоста N Redis>", port: 26379}]
conn = Redis.new(
host: "<имя кластера Redis>",
sentinels: SENTINELS,
role: "master",
password: "<пароль>"
)
conn.set("foo", "bar")
puts conn.get("foo")
conn.close()
Пример кода для подключения напрямую к мастеру:
connect.rb
require "redis"
conn = Redis.new(
host: "<FQDN хоста-мастера Redis>",
port: 6379,
password: "<пароль>"
)
conn.set("foo", "bar")
puts conn.get("foo")
conn.close()
Подключение:
ruby connect.rb
При успешном подключении к кластеру и выполнении тестового запроса будет выведена строка bar
.