Redis 6.0の新機能が段階的に議論され、最適化されてきました。
機能の多くはすでにRCや他のリリースで導入されています。
しかし、公式GAリリースではいくつかの新しい変更があります。
- SSL
- ACL: 改良、コマンドサポート
- RESP3
- クライアント側キャッシュ:再設計
- スレッド化されたI/O
- レプリカのディスクレスレプリケーション
- Redis-benchmarkのクラスタサポートとredis-cliのクラスタサポートの改善
- RedisのモジュールとしてのDisqueのベータ版: メッセージキュー空間への侵入を開始
- Redisクラスタプロキシ
- RDBが使用されなくなった場合の即時削除のサポート。
- PSYNC2: 最適化されたレプリケーションプロトコル
- タイムアウト設定のフレンドリーなサポート
- RDBロードの高速化、20%~30%の改善
- STRALGO、新しい文字列コマンド、現在 LCS の実装は一つだけ
antirezは、Redis史上最大のバージョン更新に言及し、アプリケーションでの製品のテストと評価をさらに行うことを提案し、大きなバグが発生したらバージョン6.0.1を緊急リリースすることを約束しました。予想通り、バージョン6.0.1は1日後にリリースされ、最適化のために導入されたアロケータのバグが修正され、現在は一時的に削除されています。
残念ながら、Redis 6.0.0にはリリースの数日前に導入されたバグがありました。-デフォルトでないアロケータを使用した場合にのみ発生します。 最適化は元に戻され、6.0.1がリリースされました。
この記事はこの機能に焦点を当てています。
smallnest/RESP3はRedis RESP3プロトコルのパーサライブラリで、基礎となるRedisレイヤとの通信に使用したり、新しいバージョンのRedisクライアントライブラリやRedisサーバサイドを実装するためにラップしたりすることができます。
1年前、ニューヨークで開催されたRedisカンファレンスに参加した後、@antirezが朝5時半にホステルで目を覚ましたとき、マンハッタンの美しい街並みに向かい、大勢の人々の中でRedisの将来について考えていました。クライアントサイド・キャッシングも含めて。
マンハッタンの通りに立って物思いにふけった@antirezは、その後ホテルに戻り、そこでクライアントサイド・キャッシングの最初のバージョンの実装を始めました。もちろん、最終的なRedis 6.0の実装はこの最初の実装とは大きく異なりましたが、クライアントサイドの進化が@antirezがこの機能で行ったトレードオフを示していることは明らかです。この記事では、この機能が最終的にどのようになるかに重点を置くため、この歴史についてあまり詳しく説明しません。
Redisはtrackingと呼ばれるサーバー支援型のクライアントサイドキャッシュを実装しています。
CLIENT TRACKING ON|OFF [REDIRECT client-id] [PREFIX prefix] [BCAST] [OPTIN] [OPTOUT] [NOLOOP]
トラッキングをオンにすると、Redisは各クライアントリクエストのキーを「記憶」し、キーの値が変更されるとクライアントに無効化メッセージを送信します。無効メッセージはRESP3プロトコルを介して要求元のクライアントに送信されるか、別の接続に転送されます。ブロードキャストモードが有効な場合、トラッキングに参加している クライアントは、対応する鍵を要求していなくても、プレフィックス経由で サブスクライブしている鍵に関する通知を受け取ることができ、OPTIN、 OPTOUTなどのモードも提供されます。
無効化メッセージ: ある鍵のデータが変更された場合、以前にキャッシュされたデータが無効であることをクライアントに伝える必要があります。
- 別のクライアントに無効化メッセージを転送します。RESP3を使用せず、古いRESP2を使用してRedisと通信する場合、クライアント自体が無効化メッセージの処理をサポートしていないため、Pub/Subクライアントで無効化メッセージを処理できるようにします。もちろん、クライアントがRESP3をサポートしていれば、失敗メッセージを別のクライアントに転送することもできます。この例は最後に示します。
- ブロードキャストモードで追跡を開始すると、クライアントは追跡する鍵のプレフィックスを設定する必要があり、それらの鍵の失敗メッセージは、その鍵を要求/キャッシュしたかどうかに関係なく、参加しているすべてのクライアントにブロードキャストされます。ブロードキャストモードを使用しない場合、Redisは読み取り専用コマンドで要求された鍵のみを追跡し、失敗メッセージは一度だけ報告されます。鍵は読み取り専用コマンドで要求されたものだけを追跡し、失敗メッセージは一度しか報告しません。
- ブロードキャストモードのみを適用し、鍵のプレフィックスを登録します。このプレフィックスで始まる鍵はすべて、 変更されたときに失敗メッセージを送ります。複数のプレフィックスを登録することもできます。プレフィックスを設定しない場合は、ブロードキャスト・モードですべての鍵を追跡します。
- ブロードキャスト・モードがアクティブでない場合、読み取り専用コマンドのキーは、CLIENT CACHING yesの後に呼び出されない限り、普通に追跡されます。
- ブロードキャスト・モードがアクティブでない場合、CLIENT CACHING offの後に呼び出されない限り、読み取り専用コマンドのキーは通常どおり追跡されます。
- クライアント自身が変更した鍵は送信しません。
これらの各オプションについては後述します。
テスト環境の設定
最初にRESP3プロトコルに関するオプションを紹介し、
試すには、まずredis 6.x(現在は6.0.1)をインストールする必要があります。ソースコードは公式サイトからダウンロードでき、コンパイルやインストールも簡単です:
make distclean
make
make test
sudo make install
コンパイルされたバイナリがすぐにダウンロードできるようになると思います。
サーバーを起動すると、ポート6379でサービスが開始されます。
redis-serverデフォルトでは、ローカルの6379インスタンスにアクセスするためにredis-cliを使います。
redis-cliもちろん、-h を使って他のポートの使用など、追加の設定パラメータを確認することもできます。ここでは、クライアント側のキャッシュの特性を理解することに重点を置いて、最も単純な例を使用します。
redis が返す結果をよりよく観察するには、redis-cli ではなく telnet をクライアントとして使用して redis に接続します。
BCASTブロードキャストモード
redisサーバーを起動します。
redis-cliの起動。
もちろん、テストにtelnetを使用することで、redisから返される結果を簡単に観察することができます。先ほどredis-cliはテストの補助としてキーの値を更新するために使用されます。接続後、hello 3 を送信して RESP3 プロトコルを有効にします:
redis-server
その後、トラッキングを有効にして a の値を読んでみてください。
redis-cli
この時点で、redis-cliを別のクライアントとして使ってaの値を更新すると、このクライアントにtelnetで接続して通知を受け取ることができるはずです。
127.0.0.1:6379> set a 2 OKtelnetを見ると、invalidateメッセージを受信しています:
>2 $10 invalidate *1 $1 aRESP3のPUSH型を使用していることに注意してください。
redis-cliを使用してaの値を再び更新すると、telnetはinvalidateメッセージを再び受け取ることはありません。telnetクライアントが再びaを取得しない限り、aの値を再トラッキングします。
トラッキングはいつでもキャンセルできます。
クライアント追跡オフ特定のプレフィックスを持つキーの追跡
上のメソッドはすべてのキーを追跡しますが、 特定のキーだけを追跡したい場合は、redis は現在プレフィックスマッチという方法を提供しています。特定のプレフィックスを持つキーのみを追跡することができ、 その値にはブロードキャストモードが適用されます。
telnetクライアントを使用してプレフィックスを設定し、追跡を有効にします:
~ telnet localhost 6379
Trying ::1...
Connected to localhost.
Escape character is '^]'.
hello 3
%7
$6
server
$5
redis
$7
version
$5
6.0.1
......
aで始まるすべてのキーとuserで始まるすべてのキーの2つのプレフィックスを追跡し、aで始まるすべてのキーとuserで始まるすべてのキー(aとuserを含む)が変更されたときにメッセージを受信する必要があります。
次に redis-cli を使って、abc、user:42332723213、feed:3562343243432 の 3 つのキーを更新します。
client tracking on
+OK
set a 1
+OK
get a
$1
1
telnetクライアントはabcとuser:42332723213の失敗メッセージを受け取りますが、feed:3562343243432の失敗メッセージは受け取りません:
.1:6379> set a 2
OK
クライアントトラッキングをオフにすることで、クライアントのキャッシュを停止できます。>2
$10
invalidate
*1
$1
a
現在のところ、単一のプレフィックスに対してだけ追跡を停止することはできないようです。
>2
$10
invalidate
*1
$1
a
オプトイン
optinを使うと、選択的にトラッキングを有効にすることができます。
このとき、redis-cliクライアントを使用してaの値を1000に変更し、aが無効であるというメッセージを受け取らないようにします。
client tracking off
次に、クライアントのキャッシュyesを送信すると、すぐにaの値を取得した後、この時間は、再びaの値を変更する場合は、失敗のメッセージを受け取ることができます:。
hello 3
.......
client tracking on prefix a bcast
+OK
client tracking on prefix user bcast
+OK
その直後にクライアント・キャッシングyesを送信する必要がありますか?例えば、次のコマンドを送信すると、aではなくbだけを追跡します。
.1:6379> set abc 100
OK
.1:6379> set user:3 good
OK
.1:6379> set feed:432 abc
OK
OPT OUT
OPTOUTを使用すると、トラッキングを停止することもできます。クライアントキャッシュを停止した後、次の読み取り専用コマンドのキーだけがトラッキングを停止します。
OPTINの逆であることがわかるように、シナリオに応じて選択することができます。
例えば、以下の例では、OPTOUTをオンにした後、キーが変更されると無効化メッセージが表示されます:
>2
$10
invalidate
*1
$3
abc
>2
$10
invalidate
*1
$16
user:3
キー "b "を除外したい場合は、キー "b "のみを設定します。
......
} else if (!strcasecmp(c->argv[2]->ptr,"off")) {
disableTracking(c);
} else {
......
その後、bに対する変更は、bに対する有効期限切れメッセージを 受けません。
OPTINとOPTOUTは非BCASTシナリオ用です。つまり、鍵の読み取り専用コマンドを送った場合のみ、対応する鍵が追跡されます。一方、ブロードキャストモードでは、鍵の読み取り専用コマンドを送ったかどうかに関係なく、redisが鍵を変更する限り、対応する鍵(またはプレフィックスが一致する鍵)の有効期限切れメッセージを送信します。
NOLOOP
普通に設定すると、有効期限切れメッセージは参加しているすべてのクライアントに送られますが、NOLOOPが設定されていると、鍵を更新したクライアントには送られません。
client tracking on optin
+OK
get a
$1
2
トラッキングをキャンセルするには、単にクライアントトラッキングをオフと呼ぶことに注意してください。
REDIRECT
最後に、転送されたメッセージの処理を見てみましょう。これはRESP2に準拠した、無効なメッセージを別のクライアントに転送する方法です。
まずredis-cliのクライアントIDを確認してください。
client caching yes
+OK
get a
$4
1000
>2
$10
invalidate
*1
$1
a
telnetを使ってredisに接続し、クライアントIDを確認してください。
クライアントID :12telnetクライアントで失敗メッセージの購読を有効にします:
client caching yes
+OK
get b
_
get a
$4
2000
redis-cliの失敗メッセージをtelnetクライアントに転送します。
client tracking on optout
+OK
get a
$4
3000
>2
$10
invalidate
*1
$1
a
telnetクライアントが失敗メッセージを受信したことがわかります:
client caching no
+OK
get b
$1
3
転送先のクライアントでRESP3プロトコルが有効になっていれば、RESP3のPub/Subは必要ありません。
redisのトラッキング機能の実装コードは:tracking.cにあります。