Redisプロトコルのプロファイリング(続き)

2557 ワード

Jedisというredisのclientパッケージによって、get Device:99という基本的なコマンドが実行され、Jedisソースコードを追跡することによってredisが呼び出されたことがわかる.clients.jedis.Jedisのgetメソッド:
public String get(final String key) {
    checkIsInMultiOrPipeline();
    client.sendCommand(Protocol.Command.GET, key);
    return client.getBulkReply();
  }

redisを呼び出すclients.jedis.接続:
protected Connection sendCommand(final Command cmd, final String... args) {
    final byte[][] bargs = new byte[args.length][];
    for (int i = 0; i < args.length; i++) {
      bargs[i] = SafeEncoder.encode(args[i]);
    }
    return sendCommand(cmd, bargs);
  }

コード解読:SafeEncoder.Encode(args[i])は実際にはstr.getBytes(Protocol.CHARSET);私のここのテストの時cache keyはDevice:99で、SafeEncoder.Encode(args[i])の結果、new byte[]{681011181105,99101,58,57,57}、68というASCII値に対応する文字がD、101というASCII値に対応する文字がe、このbyte[]の数値が今回のテストを示すcache key:Device:99であった。

最終的に実際にredisを呼び出す.clients.jedis.Protocol.JAva:
private static void sendCommand(final RedisOutputStream os, final byte[] command,
      final byte[]... args) {
    try {
      os.write(ASTERISK_BYTE);
      os.writeIntCrLf(args.length + 1);
      os.write(DOLLAR_BYTE);
      os.writeIntCrLf(command.length);
      os.write(command);
      os.writeCrLf();

      for (final byte[] arg : args) {
        os.write(DOLLAR_BYTE);
        os.writeIntCrLf(arg.length);
        os.write(arg);
        os.writeCrLf();
      }
    } catch (IOException e) {
      throw new JedisConnectionException(e);
    }
  }

コード解読:上のJavaコードからredisプロトコルの端緒が見えます:os.write(ASTERISK_BYTE):RedisサーバSocketポートにアスタリスク「*」を書き込みます。os.writeIntCrLf(args.length+1)今回の実行コマンドの総パラメータ長を書き込み、パラメータ長1+1、1はGETコマンドがあることを示す。os.write(DOLLAR_BYTE)はDollar記号:"$"osを書き込む.writeIntCrLf(command.length)はGETコマンドの長さを書き込み、「r」(CrLf)に書き込む。os.write(command)書き込みGETコマンド:GETコマンドはbyte数値(new byte[]{71,69,84})osに移行する.writeCrLf()書き込み"r"(CrLf)次にforループループパラメータ、今回のテストは1つのパラメータしかありません:Device:99なので、forループは1回でいいです;forループで解読:os.write(DOLLAR_BYTE)はDollar記号:"$"osを書き込む.writeIntCrLf(arg.length)はパラメータの長さを書き込み、「r」(CrLf)を書き込む。os.write(arg)はパラメータosに書き込む.writeCrLf()は"r"(CrLf)に書き込まれる。

Redisプロトコルテキストの反転


上記のコード解読により、GET Device:99というコマンドを実行するRedisプロトコルを逆発行します.
*2\r
$3\r
71 69 84\r
$9\r
68 101 118 105 99 101 58 57 57\r

プロトコルテキストに変換します(テキストはunix 2 dosでrを補う必要があります):
*2
$3
GET
$9
Device:99