tencent cloud

Tencent Cloud Distributed Cache (Redis OSS-Compatible)

ドキュメントTencent Cloud Distributed Cache (Redis OSS-Compatible)ユースケースクラスタアーキテクチャにおけるグローバルSCAN利用ガイド

クラスタアーキテクチャにおけるグローバルSCAN利用ガイド

ダウンロード
フォーカスモード
フォントサイズ
最終更新日: 2026-10-20 19:07:18
AI翻訳
本文では、クラウド分散キャッシュデータベース(Redis互換)クラスタアーキテクチャにおいて、拡張SCANコマンドを使用してクラスタデータを走査し、カーソル失効シナリオを処理して、スキャンが無限ループに入ることを回避する方法について説明します。

業務シナリオ

バッチでの期限切れKeyのクリーンアップ、Key分布の統計、データ検査、移行前の照合などの運用保守シナリオでは、インスタンス内のすべてのKeyを走査する必要があります。ネイティブRedis Clusterのデータは複数のシャードノードに分散しており、グローバルSCANをサポートしていないため、ノードを跨いで直接スキャンすることができず、上記の運用保守操作に不便をもたらします。クラウド分散キャッシュデータベースのクラスタアーキテクチャは、Proxyアーキテクチャを通じてSCAN機能を拡張し、単一コマンドでシャードを跨いだ走査を完了できるようにし、クラスタにおける全Key走査操作を簡素化します。

背景情報

クラウド分散キャッシュデータベースのクラスタアーキテクチャは、Proxyアーキテクチャを通じてSCANコマンドを拡張し、2種類のスキャンモードをサポートします:
定向スキャン: コマンドの末尾にNODEIDパラメータを追加し、指定したシャードノードのみをスキャンします。
グローバルスキャン: Proxy 5.8.9バージョンから、ノード制限のないグローバルSCANをサポートし、クラスタ内のすべてのシャードのデータを完全に走査できます。

前提条件

クラウド分散キャッシュデータベースクラスタアーキテクチャインスタンスを作成し、インスタンスの接続アドレスとアクセスパスワードを取得しました。
インスタンスのProxyバージョンは5.8.9以上(グローバルスキャン機能に必要)です。
クライアント接続設定が完了しました。接続方法についてはJedisによるRedis接続を参照してください。

利用制限

説明:
クラスタでノード切り替え(マスター/スレーブの役割変更)またはシャード削減(クラスタ縮小)が発生した場合、SCANカーソルが低確率で無効になり、カーソルに対応するシャードインデックスと実際のノードマッピング関係が切断され、次のエラーが発生する可能性があります:-ERR invalid cursor(master node idx out of range)
このエラーを無視して反復を続けると、有効なデータを取得できないだけでなく、カーソルとシャードロジックの不整合により無限ループに陥り、システムリソースを継続的に消費します。そのため、スキャンロジックはカーソル失効に対して例外処理を行う必要があります。

操作手順

ステップ1:指定シャードのターゲットスキャン

SCANコマンドの末尾にNODEIDパラメータを追加すると、指定したシャードノードのデータのみをスキャンでき、シャード単位の調査やシャードレベルの処理に適しています。
使用例:クラスタ内の特定のシャードでホットKeyが発生して遅延が増加した場合、そのシャードを定向スキャンすることで、大Keyや異常Keyの分布状況を迅速に特定できます。全クラスタデータを走査する必要はありません。そのシャードのノードIDがf2f3c387b9fab0e67af02039845c60278b13bed0であると仮定し、以下のコマンドを実行します:
scan 0 MATCH * COUNT 100 f2f3c387b9fab0e67af02039****************
ノードIDは40桁の16進数文字列です。コンソールの「ノード管理」ページで確認するか、cluster nodesコマンドを実行して取得できます。

ステップ2:グローバルスキャンを実行する

NODEIDパラメータを指定しない場合、SCANはクラスタ内のすべてのシャードのデータを走査します(Proxy 5.8.9以上が必要です)。カーソル0から反復を開始し、カーソルが再び0に戻ると走査完了です。

ステップ3:カーソル失効への対処と安全なトラバーサル

カーソル失効による無限ループを回避するために、スキャンロジックは例外をキャッチし、カーソルを開始位置0にリセットしてスキャンフローを再起動するとともに、最大再試行回数を設定する必要があります。完全な参考コード(Java + Jedis)は以下の通りです:
package com.example.service.impl;

public class RedisServiceImpl implements RedisService {
// scanの最大再試行回数
private static final int MAX_RETRIES = 3;
private final RedisConnectionFactory connectionFactory;

@Override
public void scanKeys(String pattern, int count) {
try (Jedis jedis = connectionFactory.getConnection()) {
int retryCount = 0;
boolean scanCompleted = false;
// scanプロセスのエラーをキャッチし、エラー発生時は0から再スキャンします。
while (!scanCompleted && retryCount <= MAX_RETRIES) {
String cursor = ScanParams.SCAN_POINTER_START;
ScanParams scanParams = new ScanParams();
scanParams.count(count);
scanParams.match(pattern);
try {
while (true) {
ScanResult<String> scanResult = jedis.scan(cursor, scanParams);
List<String> keys = scanResult.getResult();
if (!keys.isEmpty()) {
processKeysWithBusinessLogic(keys); // 業務処理
}
cursor = scanResult.getCursor();
// カーソルが「0」のときにスキャンが完了します。
if (cursor.equals(ScanParams.SCAN_POINTER_START)) {
scanCompleted = true;
break;
}
}
} catch (Exception e) {
retryCount++;
// 最大再試行回数を超えたため、再試行を終了します。
if (retryCount > MAX_RETRIES) {
throw new RuntimeException("最大再試行回数に達したため、スキャンに失敗しました", e);
}
}
}
}
}
}
主要なパラメータとロジックの説明は以下の通りです:
パラメータ / ロジック
説明
MAX_RETRIES
SCANの最大再試行回数です。例は3で、業務ニーズに応じて調整できます。
cursor
カーソルです。各スキャンは開始位置0(ScanParams.SCAN_POINTER_START)から始まり、カーソルが再び0に戻ると走査完了を表します。
scanParams.match(pattern)
パターンに基づいてKeyをマッチングします。
scanParams.count(count)
各イテレーションで返される要素数のヒントです。
異常捕捉
カーソル失効などの例外をキャッチした後、再試行カウントを1増やし、カーソル0から再スキャンします。MAX_RETRIESを超えた場合は例外をスローして終了し、無限ループを回避します。

検証方法

スキャンプロセスを観察します:カーソルが最終的に再び0に戻り、scanCompletedがtrueの場合、完全に走査され、無限ループに陥っていないことを示します。
スキャン結果を統計します:処理した総バッチ数、総Key数と所要時間を記録し、想定データ規模と照合して、走査が完全であることを確認します。

よくあるご質問

Q:スキャン時にエラーが発生しましたinvalid cursor(master node idx out of range) どうすればよいですか?
このエラーは通常、クラスタノードの切り替えや縮小によるカーソル失効が原因で発生します。例外をキャッチした後、カーソルを0にリセットして再スキャンを開始してください。エラーを無視して元のカーソルで反復を続けると、無限ループに陥ります。
Q:グローバルSCANが無限ループに陥るのを防ぐ方法
スキャンプロセスに対して必ず例外処理を行い、最大再試行回数を設定してください:カーソル例外をキャッチした場合、0からスキャンを再開し、再試行上限を超えた場合は終了して例外をスローします。
Q:特定のシャードのデータのみをスキャンする方法
定向スキャンを使用し、SCANコマンドの末尾にNODEIDパラメータを追加してください。具体的なコマンドの記述方法は、インスタンスの実際のサポート内容に準じます。

ヘルプとサポート

この記事はお役に立ちましたか?

フィードバック