Help us understand the problem. What is going on with this article?

Apache Kafkaの性能検証(5): システム全体のレイテンシについて

More than 1 year has passed since last update.

初版: 2018/11/16
著者: 伊藤 雅博, 株式会社日立製作所

はじめに

この投稿ではオープンソースカンファレンス2017.Enterpriseで発表した「めざせ!Kafkaマスター ~Apache Kafkaで最高の性能を出すには~」の検証時に調査した内容を紹介します(全8回の予定)。本投稿の内容は2017年6月にリリースされたKafka 0.11.0 時点のものです。

最終回となる今回は、システム全体のレイテンシについて紹介します。前回まではデータ処理のスループットに着目してチューニングを行ってきました。一般的に、スループットが増加するとレイテンシも増加しますが、これまでの検証で行ったチューニングではレイテンシを考慮していませんでした。そこで今回はレイテンシの測定結果について紹介します。

過去の投稿:
1. Apache Kafkaの概要とアーキテクチャ
2. Apache KafkaのProducer/Broker/Consumerのしくみと設定一覧
3. Apache Kafkaの推奨システム構成と性能の見積もり方法
4. Apache Kafkaの性能検証(1):検証内容と検証環境について
5. Apache Kafkaの性能検証(2):Producerのチューニング
6. Apache Kafkaの性能検証(3):Brokerのチューニング結果
7. Apache Kafkaの性能検証(4):Producerの再チューニングおよびConsumerのチューニング結果

システム全体のレイテンシ

システム全体のレイテンシは、ProducerのSend APIでRecordを追加する時点から、ConsumerのPoll APIでRecordを取得するまでの時間です。このレイテンシは以下に示す5つの処理時間の合計値となります。

kafka08_01.png

前回までのチューニングを行った状態で、上記の各処理のレイテンシを測定した結果を以下に示します。これらのレイテンシは、これまで測定してきたスループットと同様に、KafkaがJMXで公開しているメトリックを収集したものです。

① Send APIのブロック時間

ユーザスレッドがSend APIでRecordを追加するスループットが、Producerのリクエスト送信スループットよりも高い場合は、Producerのバッファがいずれ満杯となります。Producerのバッファが満杯になると、ユーザスレッドはバッファに空きが出るまでSend APIでブロックされます。

今回の検証で使用した40個のProducerについて、Producerごとの空きバッファサイズの推移を以下に示します。測定開始直後から空きバッファサイズは減少し続け、2分ほど経過した時点でバッファの空き容量がほぼ0になることが分かります。そのため、2分ほど経過した時点からSend APIでブロックが発生していたと考えられます。

kafka08_02.png

Producerの秒間リクエスト送信数の推移を以下に示します。測定開始から10秒ほど経過した後は、1Producerの秒間送信リクエスト数は3程度で推移していることが分かります。

kafka08_03.png

今回の検証ではSend APIのブロック時間を測定していませんが、リクエストが送信されればバッファが空くため、ブロック時間は1秒÷3リクエスト≒333ミリ秒程度と推定できます。

② Producerのバッファリング時間

Send APIでRecord Batchに追加されたRecordは、ネットワークスレッドがリクエストとして送信するまで、Producerのバッファに留まり続けます。Recordのバッファリング時間の推移を以下に示します。測定開始直後からバッファリング時間は徐々に増加していき、2-3分経過した後は50秒程度で推移していることが分かります。

kafka08_04.png

今回の検証では、40個のProducerによる送信スループットの合計が803MB/sだったので、1 Producerあたりの送信スループットは約20MB/sとなります。今回の検証ではProducerの buffer.memory を 1GB に設定したため、バッファが満杯になるまでRecordが溜まると、Recordは送信されるまでに 1GB ÷ 20MB/s ≒ 50秒 かかることになります。

③ Produceリクエストのレイテンシ

今回の検証はProduceリクエストの acks を all 、Topicの min.insync.replicas を 2 に設定したため、ProduceしたRecordが2個以上のReplicaに複製された時点でレスポンスが返されます。この複製が完了したRecordは、Consumerから取得できるようになります。Produceリクエストのレイテンシの推移を以下に示します。スパイク時はレイテンシが10秒を超えることもありますが、平均すると2.5秒程度で推移していることが分かります。

kafka08_05.png

④ Fetchリクエストのレイテンシ

今回の検証では6個のConsumerでConsumer Groupを構成して、TopicのデータをFetchし続けました。各Consumerが送信したFetchリクエストのレイテンシの推移を以下に示します。レイテンシは 100ミリ秒から 300ミリ秒の間でばらつきがありますが、平均すると150ミリ秒程度で推移していることが分かります。

kafka08_06.png

⑤ Poll APIのレイテンシ

Consumerを使用するユーザアプリケーションは、Poll APIを呼び出してRecordを取得します。このときConsumerがRecordを保持していればRecordが即時返却されますが、保持していない場合は新たなRecordが得られるまでブロックされます。

今回の検証ではPoll APIのレイテンシを測定していませんが、Consumeスループットは803MB/s程度で推移していました。そのためRecordは即時返却され続けたと考えられ、レイテンシは数ミリ秒程度と推定できます。

レイテンシについての考察

上記の①から⑤のレイテンシを合計すると53秒程度でした。今回は検証ではスループットを最大化するために、Producerの送信能力を超える速さでRecordを追加したので、Producerのバッファが詰まって送信まで50秒もかかっていました。Producerの buffer.memory を増やすと、ユーザアプリケーション側から流れてくるRecord流量の一時的な増加には耐えやすくなります。しかしバッファリング時間を監視していないと、Recordの送信が遅れていることに気付けないというリスクもあります。

Kafkaの最大スループット(803MB/s)を超えない範囲のRecord流量であれば、Producerで詰まることはなくなる(①、②の待ち時間ほぼ無くなる)ため、レイテンシは3秒程度になると推定できます。ただしRecord Batchの蓄積が遅くなるため、linger.msを増やす必要があるかもしれません。

おわりに

ここまで、Kafkaの調査内容と性能検証結果を8回に分けて紹介してきました。Kafkaはスケーラビリティに優れた分散メッセージキューです。しかし、データを保護するために同期レプリケーションを行いつつ性能を引き出すには、内部構造を理解した上で適切なチューニングが必要となります。

hitachi-oss
社内でのOSS活用推進や、OSSコミュニティ活動などを行っています。
http://www.hitachi.co.jp/products/it/oss/
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away