0
0

More than 3 years have passed since last update.

Redis Pipeliningはネットワークレイテンシの壁を超えるか

Posted at

RedisをマルチAZに配置したときの問題

az-1に配置したRedisに対して、az-2に配置したアプリケーションからアクセスすると、az間のネットワークレイテンシの問題で遅くなるという話。

Redis Pipeliningとは

Spring Data Redis - 10.13. Pipelining

Redis provides support for pipelining, which involves sending multiple commands to the server without waiting for the replies and then reading the replies in a single step.

通常は1コマンドごとにサーバに送られるので、大量のデータをRedisとやりとりすると、サーバとの通信も大量に発生することになります。100件のsetで100回通信が発生するのはもちろん、100件のgetでも100回通信が発生します。(setやhashも同様)
Redis RepositoriesのfindByXXとかやると、裏でkeys + レコード数分のhgetallが走るので、通信量が膨大になります。
Pipeliningは、上記の通り複数のコマンドを1度の通信で送るので、ネットワークレイテンシの問題が解消するのでは?という仮説のもと検証をしました。

検証内容

配置パターン

ローカル、AWS(同一az)、AWS(azまたがり)の3パターンを検証。

ローカル

ローカルPCのJavaアプリから、ローカルPCのRedisコンテナ on Docker Desktopへアクセスする構成。

ThinkPad X390
redis 6.0.9 (docker run -p 6379:6379 redis)
openjdk version "11.0.2" 2019-01-15
Spring Data Redis 2.4.2

AWS(同一VPC、同一az)

同一VPC上、同一az内に、Redisサーバ、Javaクライアントのサーバをそれぞれ起動して、同一az内でアクセスする構成。

・Redisサーバ
東京リージョン、ap-northeast-1c
Amazon Linux2
m5.xlarge
Redis 6.0.9

・Javaクライアント
東京リージョン、ap-northeast-1c
Amazon Linux2
t2.micro
openjdk version "11.0.9.1" 2020-11-04 LTS(Coretto)
Spring Data Redis 2.4.2

AWS(同一VPC、別az)

同一VPC上、異なるaz内に、Redisサーバ、Javaクライアントのサーバをそれぞれ起動して、azまたがりでアクセスする構成。

・Redisサーバ
東京リージョン、ap-northeast-1c
Amazon Linux2
m5.xlarge
Redis 6.0.9

・Javaクライアント
東京リージョン、ap-northeast-1d
Amazon Linux2
t2.micro
openjdk version "11.0.9.1" 2020-11-04 LTS(Coretto)
Spring Data Redis 2.4.2

動作検証アプリ

レコード数

1, 10, 100, 1000の4パターンを検証。

Redisへのアクセスパターン

setをレコード数分x3回、getをレコード数分x3回やって、set/getそれぞれの平均処理時間[ms]を計測。
setは、"key[n]", "value[n]"
getは、"keys *"した後、それぞれのkeyをgetする

Redisへのアクセス方法

下記3パターンを検証。
* 1つずつコマンドを発行する方法
* Pipeliningを使ってコマンドを発行する方法
* Parallel Streamを使ってコマンドを発行する方法

検証結果

縦軸は処理時間[ms]です。

ローカル

image.png

AWS(同一az)

image.png

AWS(azまたがり)

image.png

考察

  • Pipeliningは少量のレコードを扱う場合のオーバーヘッドが結構ある(1件の処理でnormalやParallel Steramに比べて倍以上時間がかかっている)。
  • azまたがりのケースでは、Pipeliningは有効であるが、100件まではParallel Streamとほとんど変わらなかった。1000件でようやく差が出た。
  • Parallel Streamかなり優秀。とはいえ、裏でスレッドを生成して実行する仕組みなので、CPU負荷がかかることに注意する。

結論

Redis Pipeliningはネットワークレイテンシの壁を超えるけど、オーバーヘッドもあるので、数百~千件単位のバルク処理にのみ使うのが良い。
Javaの場合、CPU負荷との兼ね合いにもなるが、ほとんどのケースでは、Parallel Steramを使っておけば解決するのではないかと思う。

参考

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0