このトピックでは、redis-cli とコードを使用して Tair Serverless KV インスタンスに接続する方法について説明します。
前提条件
クライアントの IP アドレスを ホワイトリスト に追加します。
クライアントを実行する Elastic Compute Service (ECS) インスタンスと Tair インスタンスは、同じ Virtual Private Cloud (VPC) 内にある必要があります。
重要Tair Serverless KV は、同じ VPC 内からの接続のみをサポートします。ECS インスタンスと Tair Serverless KV インスタンスが異なる VPC にある場合はどうすればよいですか?
インスタンスへの接続
次の表からインスタンスへの接続に必要なパラメーターを取得します。
パラメーター | 説明 | 取得方法 |
hostname | エンドポイント |
|
port | ポート番号 | デフォルトのポート番号は 6379 です。ポート番号をカスタマイズすることもできます。詳細については、「エンドポイントまたはポート番号の変更」をご参照ください。 |
password | パスワード | アカウントの種類に基づいてユーザー名とパスワードを入力します:
パスワードを忘れた場合、または設定していない場合は、パスワードを変更またはリセットできます。 |
Tair Serverless KV は分散アーキテクchaを使用しており、ネイティブの Redis Cluster プロトコル、接続メソッド、および使用方法と互換性があります。クライアントが Redis Cluster モードでインスタンスに接続していることを確認する必要があります。
コードを使用した接続
Jedis
この例では、Jedis 4.3.0 を使用します。詳細については、「GitHub」をご参照ください。
カスタム接続プール (推奨)
import redis.clients.jedis.*; import java.util.HashSet; import java.util.Set; public class DirectTest { private static final int DEFAULT_TIMEOUT = 2000; private static final int DEFAULT_REDIRECTIONS = 5; private static final ConnectionPoolConfig config = new ConnectionPoolConfig(); public static void main(String args[]) { // 最大接続数を指定します。直接接続モードでは、クライアントはクラスターインスタンスのシャードに直接接続します。したがって、次の要件を満たす必要があります: クライアント数 × MaxTotal の値 < 単一シャードへの最大接続数。 config.setMaxTotal(30); // ビジネスニーズに基づいて最大アイドル接続数を指定します。 config.setMaxIdle(20); config.setMinIdle(15); // クラスターインスタンスに割り当てられているプライベートエンドポイントを指定します。 String host = "r-bp1xxxxxxxxxxxx.redis.rds.aliyuncs.com"; int port = 6379; // クラスターインスタンスへの接続に使用するパスワードを指定します。 String password = "xxxxx"; Set<HostAndPort> jedisClusterNode = new HashSet<HostAndPort>(); jedisClusterNode.add(new HostAndPort(host, port)); JedisCluster jc = new JedisCluster(jedisClusterNode, DEFAULT_TIMEOUT, DEFAULT_TIMEOUT, DEFAULT_REDIRECTIONS, password, "clientName", config); jc.set("key", "value"); jc.get("key"); jc.close(); // アプリケーションが終了し、リソースを破棄する場合は、このメソッドを呼び出します。これにより、接続が閉じられ、リソースが解放されます。 } }デフォルトの接続プール
import redis.clients.jedis.ConnectionPoolConfig; import redis.clients.jedis.HostAndPort; import redis.clients.jedis.JedisCluster; import java.util.HashSet; import java.util.Set; public class DirectTest{ private static final int DEFAULT_TIMEOUT = 2000; private static final int DEFAULT_REDIRECTIONS = 5; private static final ConnectionPoolConfig DEFAULT_CONFIG = new ConnectionPoolConfig(); public static void main(String args[]){ // クラスターインスタンスに割り当てられているプライベートエンドポイントを指定します。 String host = "r-bp1xxxxxxxxxxxx.redis.rds.aliyuncs.com"; int port = 6379; String password = "xxxx"; Set<HostAndPort> jedisClusterNode = new HashSet<HostAndPort>(); jedisClusterNode.add(new HostAndPort(host, port)); JedisCluster jc = new JedisCluster(jedisClusterNode, DEFAULT_TIMEOUT, DEFAULT_TIMEOUT, DEFAULT_REDIRECTIONS,password, "clientName", DEFAULT_CONFIG); jc.set("key","value"); jc.get("key"); jc.close(); // アプリケーションが終了し、リソースを破棄する場合は、このメソッドを呼び出します。これにより、接続が閉じられ、リソースが解放されます。 } }
Spring Data Redis
次のサンプルプロジェクトは Maven を使用して作成されます。Lettuce または Jedis クライアントを手動でダウンロードすることもできます。
次の Maven 依存関係を追加します:
<?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> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.4.2</version> <relativePath/> <!-- lookup parent from repository --> </parent> <groupId>com.aliyun.tair</groupId> <artifactId>spring-boot-example</artifactId> <version>0.0.1-SNAPSHOT</version> <name>spring-boot-example</name> <description>Demo project for Spring Boot</description> <properties> <java.version>1.8</java.version> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> </dependency> <dependency> <groupId>redis.clients</groupId> <artifactId>jedis</artifactId> </dependency> <dependency> <groupId>io.lettuce</groupId> <artifactId>lettuce-core</artifactId> <version>6.3.0.RELEASE</version> </dependency> <dependency> <groupId>io.netty</groupId> <artifactId>netty-transport-native-epoll</artifactId> <version>4.1.100.Final</version> <classifier>linux-x86_64</classifier> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> </project>Spring Data Redis エディターに次のコードを入力し、コメントに基づいてコードを変更します。
この例では、Spring Data Redis 2.4.2 を使用します。
(推奨) Jedis を使用した Spring Data Redis
@Bean JedisConnectionFactory redisConnectionFactory() { List<String> clusterNodes = Arrays.asList("r-bp10noxlhcoim2****.redis.rds.aliyuncs.com:6379"); RedisClusterConfiguration redisClusterConfiguration = new RedisClusterConfiguration(clusterNodes); redisClusterConfiguration.setUsername("user"); redisClusterConfiguration.setPassword("password"); JedisPoolConfig jedisPoolConfig = new JedisPoolConfig(); // 最大アイドル接続数を指定します。直接接続モードでは、クライアントはクラスターインスタンスのシャードに直接接続します。したがって、次の要件を満たす必要があります: クライアント数 × MaxTotal の値 < 単一シャードへの最大接続数。 jedisPoolConfig.setMaxTotal(30); // ビジネスニーズに基づいて最大アイドル接続数を指定します。 jedisPoolConfig.setMaxIdle(20); // 追加の ping コマンドの生成を防ぐために testOn[Borrow|Return] を無効にします。 jedisPoolConfig.setTestOnBorrow(false); jedisPoolConfig.setTestOnReturn(false); return new JedisConnectionFactory(redisClusterConfiguration, jedisPoolConfig); }Lettuce を使用した Spring Data Redis
警告Lettuce のデフォルト構成では、インスタンスが変更されたときにアプリケーションのレイテンシーの増加やアクセシビリティなどの問題が発生する可能性があります。Lettuce を正しく構成するには、「Lettuce 関連のパラメーター」の説明をよくお読みください。
Lettuce のバージョンは 6.3.0.RELEASE 以降である必要があります。詳細については、「[お知らせ] Lettuce のアップグレードに関する提案」をご参照ください。
/** * TCP keepalive を有効にし、次の 3 つのパラメーターを構成します: * TCP_KEEPIDLE = 30 * TCP_KEEPINTVL = 10 * TCP_KEEPCNT = 3 */ private static final int TCP_KEEPALIVE_IDLE = 30; /** * TCP_USER_TIMEOUT パラメーターを使用すると、Lettuce が障害またはクラッシュイベント中に連続タイムアウトループでスタックしたままになるシナリオを回避できます。 * 参照: https://github.com/lettuce-io/lettuce-core/issues/2082 */ private static final int TCP_USER_TIMEOUT = 30; @Bean public LettuceConnectionFactory redisConnectionFactory() { List<String> clusterNodes = Arrays.asList("r-bp10noxlhcoim2****.redis.rds.aliyuncs.com:6379"); RedisClusterConfiguration redisClusterConfiguration = new RedisClusterConfiguration(clusterNodes); redisClusterConfiguration.setUsername("user"); redisClusterConfiguration.setPassword("password"); // Config TCP KeepAlive SocketOptions socketOptions = SocketOptions.builder() .keepAlive(KeepAliveOptions.builder() .enable() .idle(Duration.ofSeconds(TCP_KEEPALIVE_IDLE)) .interval(Duration.ofSeconds(TCP_KEEPALIVE_IDLE / 3)) .count(3) .build()) .tcpUserTimeout(TcpUserTimeoutOptions.builder() .enable() .tcpUserTimeout(Duration.ofSeconds(TCP_USER_TIMEOUT)) .build()) .build(); ClusterTopologyRefreshOptions topologyRefreshOptions = ClusterTopologyRefreshOptions.builder() .enablePeriodicRefresh(Duration.ofSeconds(60)) .dynamicRefreshSources(false) .enableAllAdaptiveRefreshTriggers() .adaptiveRefreshTriggersTimeout(Duration.ofSeconds(15)).build(); LettuceClientConfiguration lettuceClientConfiguration = LettuceClientConfiguration.builder(). clientOptions(ClusterClientOptions.builder() .socketOptions(socketOptions) .validateClusterNodeMembership(false) .topologyRefreshOptions(topologyRefreshOptions).build()).build(); return new LettuceConnectionFactory(redisClusterConfiguration, lettuceClientConfiguration); }
PhpRedis
この例では、PhpRedis 5.3.7 を使用します。詳細については、「GitHub」をご参照ください。
<?php
// クラスターインスタンスへの接続に使用するプライベートエンドポイントとポート番号を指定します。
$array = ['r-bp1xxxxxxxxxxxx.redis.rds.aliyuncs.com:6379'];
// クラスターインスタンスへの接続に使用するパスワードを指定します。
$pwd = "xxxx";
// パスワードを使用してクラスターインスタンスに接続します。
$obj_cluster = new RedisCluster(NULL, $array, 1.5, 1.5, true, $pwd);
// 接続の結果を表示します。
var_dump($obj_cluster);
if ($obj_cluster->set("foo", "bar") == false) {
die($obj_cluster->getLastError());
}
$value = $obj_cluster->get("foo");
echo $value;
?>redis-py
この例では、Python 3.9 と redis-py 4.4.1 を使用します。詳細については、「GitHub」をご参照ください。
# !/usr/bin/env python
# -*- coding: utf-8 -*-
from redis.cluster import RedisCluster
# host および port パラメーターの値を、インスタンスへの接続に使用するエンドポイントとポート番号に置き換えます。
host = 'r-bp10noxlhcoim2****.redis.rds.aliyuncs.com'
port = 6379
# user および pwd パラメーターの値を、インスタンスへの接続に使用するユーザー名とパスワードに置き換えます。
user = 'testaccount'
pwd = 'Rp829dlwa'
rc = RedisCluster(host=host, port=port, username=user, password=pwd)
# 接続が確立された後、インスタンスで操作を実行できます。次のコードは、set メソッドと get メソッドを呼び出す方法の例を示しています:
rc.set('foo', 'bar')
print(rc.get('foo')).NET
この例では、.NET 6.0 と StackExchange.Redis 2.6.90 を使用します。
using StackExchange.Redis;
class RedisConnSingleton {
// クラスターインスタンスへの接続に使用するエンドポイント、ポート番号、ユーザー名、およびパスワードを指定します。
private static ConfigurationOptions configurationOptions = ConfigurationOptions.Parse("r-bp10noxlhcoim2****.redis.rds.aliyuncs.com:6379,user=testaccount,password=Rp829dlwa,connectTimeout=2000");
// シングルトンのロック
private static readonly object Locker = new object();
// シングルトン
private static ConnectionMultiplexer redisConn;
// シングルトン
public static ConnectionMultiplexer getRedisConn()
{
if (redisConn == null)
{
lock (Locker)
{
if (redisConn == null || !redisConn.IsConnected)
{
redisConn = ConnectionMultiplexer.Connect(configurationOptions);
}
}
}
return redisConn;
}
}
class Program
{
static void Main(string[] args)
{
ConnectionMultiplexer cm = RedisConnSingleton.getRedisConn();
var db = cm.GetDatabase();
db.StringSet("key", "value");
String ret = db.StringGet("key");
Console.WriteLine("get key: " + ret);
}
}node-redis
この例では、Node.js 19.4.0 と node-redis 4.5.1 を使用します。
import { createCluster } from 'redis';
// インスタンスへの接続に使用するエンドポイント、ポート番号、ユーザー名、およびパスワードを指定します。
// url パラメーターにユーザー名とパスワードを指定した後、defaults パラメーターにグローバルなユーザー名とパスワードも指定する必要があります。
// グローバルなユーザー名とパスワードは、残りのノードを認証するために使用されます。残りのノードが認証されない場合、NOAUTH エラーが発生します。
const cluster = createCluster({
rootNodes: [{
url: 'redis://testaccount:Rp829dlwa@r-bp10noxlhcoim2****.redis.rds.aliyuncs.com:6379'
}],
defaults: {
username: 'testaccount',
password: 'Rp829dlwa'
}
});
cluster.on('error', (err) => console.log('Redis Cluster Error', err));
await cluster.connect();
await cluster.set('key', 'value');
const value = await cluster.get('key');
console.log('get key: %s', value);
await cluster.disconnect();
Go-redis
この例では、Go 1.19.7 と go-redis 9.5.1 を使用します。
go-redis 9.0 以降を使用してください。9.0 より前の go-redis バージョンを使用すると、プライベートエンドポイントに接続するときに互換性エラーが発生する可能性があります。詳細については、「一般的なエラーとトラブルシューティング」をご参照ください。
package main
import (
"context"
"fmt"
"github.com/go-redis/redis/v9"
)
var ctx = context.Background()
func main() {
rdb := redis.NewClusterClient(&redis.ClusterOptions{
Addrs: []string{"r-bp10noxlhcoim2****.redis.rds.aliyuncs.com:6379"},
Username: "testaccount",
Password: "Rp829dlwa",
})
err := rdb.Set(ctx, "key", "value", 0).Err()
if err != nil {
panic(err)
}
val, err := rdb.Get(ctx, "key").Result()
if err != nil {
panic(err)
}
fmt.Println("key", val)
}Lettuce
Lettuce のデフォルト構成では、インスタンスが変更されたときにアプリケーションのレイテンシーの増加やアクセシビリティなどの問題が発生する可能性があります。Lettuce を正しく構成するには、「Lettuce 関連のパラメーター」の説明をよくお読みください。
Lettuce のバージョンは 6.3.0.RELEASE 以降である必要があります。詳細については、「[お知らせ] Lettuce のアップグレードに関する提案」をご参照ください。
次の Maven 依存関係を追加します:
<dependency> <groupId>io.lettuce</groupId> <artifactId>lettuce-core</artifactId> <version>6.3.0.RELEASE</version> </dependency> <dependency> <groupId>io.netty</groupId> <artifactId>netty-transport-native-epoll</artifactId> <version>4.1.65.Final</version> <classifier>linux-x86_64</classifier> </dependency>次のコードを追加し、コメントに基づいてコードを変更します:
import io.lettuce.core.RedisURI; import io.lettuce.core.SocketOptions; import io.lettuce.core.cluster.ClusterClientOptions; import io.lettuce.core.cluster.ClusterTopologyRefreshOptions; import io.lettuce.core.cluster.RedisClusterClient; import io.lettuce.core.cluster.api.StatefulRedisClusterConnection; import java.time.Duration; public class ClusterDemo { /** * TCP keepalive を有効にし、次の 3 つのパラメーターを構成します: * TCP_KEEPIDLE = 30 * TCP_KEEPINTVL = 10 * TCP_KEEPCNT = 3 */ private static final int TCP_KEEPALIVE_IDLE = 30; /** * TCP_USER_TIMEOUT パラメーターは、Lettuce が障害またはクラッシュイベント中に連続タイムアウトループでスタックしたままになる状況を回避できます。 * 参照: https://github.com/lettuce-io/lettuce-core/issues/2082 */ private static final int TCP_USER_TIMEOUT = 30; public static void main(String[] args) throws Exception { // host、port、および password の値を実際のインスタンス情報に置き換えます。 String host = "r-bp1ln3c4kopj3l****.redis.rds.aliyuncs.com"; int port = 6379; String password = "Da****3"; RedisURI redisURI = RedisURI.Builder.redis(host) .withPort(port) .withPassword(password) .build(); ClusterTopologyRefreshOptions refreshOptions = ClusterTopologyRefreshOptions.builder() .enablePeriodicRefresh(Duration.ofSeconds(60)) .dynamicRefreshSources(false) .enableAllAdaptiveRefreshTriggers() .adaptiveRefreshTriggersTimeout(Duration.ofSeconds(15)).build(); // Config TCP KeepAlive SocketOptions socketOptions = SocketOptions.builder() .keepAlive(SocketOptions.KeepAliveOptions.builder() .enable() .idle(Duration.ofSeconds(TCP_KEEPALIVE_IDLE)) .interval(Duration.ofSeconds(TCP_KEEPALIVE_IDLE/3)) .count(3) .build()) .tcpUserTimeout(SocketOptions.TcpUserTimeoutOptions.builder() .enable() .tcpUserTimeout(Duration.ofSeconds(TCP_USER_TIMEOUT)) .build()) .build(); RedisClusterClient redisClient = RedisClusterClient.create(redisURI); redisClient.setOptions(ClusterClientOptions.builder() .socketOptions(socketOptions) .validateClusterNodeMembership(false) .topologyRefreshOptions(refreshOptions).build()); StatefulRedisClusterConnection<String, String> connection = redisClient.connect(); connection.sync().set("key", "value"); System.out.println(connection.sync().get("key")); } }上記のコードを実行します。正常に完了すると、次の出力が期待されます:
value
次の表に、Lettuce 関連のパラメーターを示します。
パラメーター | デフォルト構成 | 説明 | 推奨構成 |
enablePeriodicRefresh(Duration refreshPeriod) | 無効 | クラスターのトポロジーの定期的なリフレッシュを有効にします。 | リフレッシュ期間を 60 秒に設定することをお勧めします。 このオプションを有効にすると、アクティブでない持続的接続でもローカルトポロジーの最新のビューを維持できます。 |
dynamicRefreshSources(boolean dynamicRefreshSources) | true | このパラメーターを true に設定すると、Cluster Nodes コマンドによって返されたすべてのノードがクラスタートポロジーのリフレッシュに使用されます。このパラメーターを false に設定すると、指定されたノードエンドポイントが使用されます。 | 特に必要がない限り、このパラメーターを false に設定することをお勧めします。 このオプションを有効にすると、CLUSTER NODES コマンドがすべてのノードに送信され、サーバーの負荷が増加します。さらに、構成の変更中は、エンドポイントを使用してトポロジーを更新する方が、通常は高速で信頼性が高くなります。 |
enableAllAdaptiveRefreshTriggers() | 無効 | MOVED メッセージを受信したときにクラスタートポロジーの自動リフレッシュを有効にします。 | このパラメーターは有効にする必要があります。 このオプションを有効にすると、Lettuce はトポロジーの変更後にローカルトポロジーを迅速に更新できます。 |
adaptiveRefreshTriggersTimeout(Duration timeout) | 30s | 指定されたタイムアウト期間内に 1 回のリフレッシュのみを許可するように、クラスタートポロジーのリフレッシュの頻度を制限します。 | このパラメーターを 15s に設定することをお勧めします。 クラスター内の複数のノードにまたがるトポロジーの変更はアトミックではありません。その結果、Lettuce によってトリガーされた最初のトポロジーリフレッシュが失敗する可能性があります。迅速な後続のリフレッシュは、トポロジーが正しく更新されることを保証するのに役立ちます。アプリケーションの数が少ない場合、同時に CLUSTER NODES コマンドを送信するクライアントの数が少なくなります。この場合、トポロジーテーブルの収束を高速化するために、この値を適切に小さくすることができます。 |
validateClusterNodeMembership(boolean validateClusterNodeMembership) | true | トポロジーの変更中、Lettuce は MOVED を使用してコマンドを正しいノードにリダイレクトします。このパラメーターを true に設定すると、コマンドは CLUSTER NODES コマンドの出力に明示的にリストされているノードにのみリダイレクトできます。 | このパラメーターは false に設定する必要があります。 このパラメーターを false に設定すると、クラスタートポロジーの変更後にローカルトポロジーのリフレッシュが完了する前に、新しく追加されたノードにアクセスできます。 |
redis-cli を使用した接続
インスタンスに接続します:
./redis-cli -h r-bp1zxszhcgatnx****.redis.rds.aliyuncs.com -p 6379 -cパスワードで認証します。
AUTH testaccount:Rp829dlwa
redis-cli の詳細については、「redis-cli を使用してインスタンスに接続する」をご参照ください。
よくある質問
Q: ECS インスタンスと Tair Serverless KV インスタンスが同じ VPC にない場合はどうすればよいですか?
A: ECS インスタンスの VPC を Tair インスタンスの VPC に変更するか、ECS インスタンスと同じ VPC に Tair Serverless KV インスタンスを作成できます。