Redisの負荷検証(1000万レコード突っ込んだ時の動きをみてみる)

先日入れたRedis(RedisをインストールしてSET/GETするにインストール方法書いてあります)ですが、 実際に運用する時に、ウン百万~ウン千万レコードのデータを扱う事になりそうっていうことで、 どんな動きするのか検証してみました。   ■ 環境 とりあえず↓こんなんで。

サーバ(Ubuntu)
⇒ Redis。Masterだけ。設定もデフォルトのまま。CPUはPentiumD。メモリは2ギガ。
クライアント(Windows)
⇒ jedis。業務で使う時もJavaから呼ぶ事になると思うので。Core i5のノートPC。

jedisの使い方は簡単でした(Maven便利だなぁ)。 https://github.com/xetorthio/jedis の How do I use it? の通りです。   ■ Redisへセット KEYもVALUEも適当にcommon-langのRandomStringUtils使って。。

import java.util.Date;
import org.apache.commons.lang.RandomStringUtils;
import redis.clients.jedis.Jedis;
public class RedisSetter {
 public static void main(String args[]) {
  Jedis jedis = new Jedis("UbuntuIPアドレス");
  String key = null;
  String value = null;
  for (int i = 0; i < 10000000; i++) {
   key = RandomStringUtils.randomAlphanumeric(20);
   value = RandomStringUtils.randomAlphanumeric(10);
   jedis.set(key, value);
   if (i % 10000 == 0) {
    System.out.println(new Date());
    System.out.println("SET Counter : " + i);
   }
  }
 }
}

  ■ Redisからゲット

import java.util.Date;
import org.apache.commons.lang.RandomStringUtils;
import redis.clients.jedis.Jedis;
public class RedisGetter {
 public static void main(String args[]) {
  Jedis jedis = new Jedis("UbuntuIPアドレス");
  String key = null;
  String result = null;
  for (int i = 0; i < 1000000; i++) {
   key = RandomStringUtils.randomAlphanumeric(20);
   result = jedis.get(key);
   if (result != null) {
    System.out.println("Matched! " + result);
   }
   if (i % 10000 == 0) {
    System.out.println(new Date());
    System.out.println("GET Counter : " + i);
   }
  }
 }
}

  ■ クライアント側 GETを3多重、SETを2多重で動作させてみます。    ■ サーバー側 Redisが吐いてるログみると5つのコネクション受け付けてます。    ■ 結果 ● サーバのリソース #下のネットワークが上がりはじめたとこくらいか検証はじめました。 ・CPU : 件数増えてもそんなに上がっていかない。 ・メモリ: ひたすら右肩上がり。 定期的に取得されるダンプファイル(dump.rdb)が250メガを越えてきたくらいから怪しくなってきて、 スワップするようになったら極端にスループット落ちて検証にならなくなりました。。   ● クライアント コンスタントに4~5秒で1万回セットしていましたが、 サーバ側がスワップするようになったらSocketTimeoutで落ちました。

Exception in thread "main" redis.clients.jedis.JedisException: java.net.SocketTimeoutException: Read timed out
 at redis.clients.jedis.Protocol.process(Protocol.java:68)
 at redis.clients.jedis.Protocol.read(Protocol.java:116)
 at redis.clients.jedis.Connection.getStatusCodeReply(Connection.java:121)
 at redis.clients.jedis.Jedis.set(Jedis.java:58)
 at RedisSetter.main(RedisSetter.java:14)

  ■ ということで、、、 自分のメモリ2ギガのマシンだと750万件くらいしか突っ込めませんでした。 次はSETのループを500万回までにして、業務上想定されるGETのリクエストを もっと多重度上げて実施してみようと思います。