+ - 0:00:00
Notes for current slide
Notes for next slide

Apache Kafka
を使った
マイクロサービス基盤

2016/01/31 Scala Matsuri

CC-BY-NC-SA

1 / 76

発表後に追記

当日の発表動画はこちら

2 / 76

今日たぶん話すこと

  • Kafkaの簡単な説明
  • 仕事としてどういうものを作ったか、やっていたか
  • Kafka使う上での具体的な知見、設定例
  • ScalaのClientについて
  • Kafkaのつらいところ色々
    • GC, Clientが残念, コードが残念, ボトルネック箇所
4 / 76

Kafkaとは

5 / 76

Kafkaとは

  • ScalaとJavaで作られてる
  • LinkedInが最初に作ってOSS化
  • その後Apacheプロジェクト
8 / 76

Kafkaとは

  • わりといくつかの大企業で使ってるらしい
  • 公式のWikiに一覧がある
  • LinkedIn, Yahoo, Twitter, Netflix, Square, Tumblr, PayPal, Cisco
9 / 76

Kafkaとは

  • 巨大なメッセージキューのような何か?
  • サーバー側がどこまで読み込んだのかを直接管理しない
  • 一定期間か量までは、何度読み込んでも保持され、古いものも(原理的には)何度でも読める
10 / 76

11 / 76

12 / 76

13 / 76

Kafkaとは

  • 2016/01/31現在の最新版は0.9.0.0
    • 2015年11月リリース
  • Amazon Kinesisと似てるらしい?
  • Kafka自体の一般的な詳細な解説は時間なくなるので省略
14 / 76

Kafkaとは

いっぱいはてブついてて多分わかりやすい(?)ので
あとは以下の記事か、公式ドキュメントを

Apache Kafkaに入門した

15 / 76

Kafkaとは

  • 独自なバイナリプロトコル( プロトコル詳細 )
  • 0.8までは認証がなかった。0.9で追加された
16 / 76

0.8までは認証がない

  • なんでも出来てしまう
    • Topicの追加、削除、publish、subscribe
  • 危険性を考えると、そのまま(社内ですら)公開できない
17 / 76

マイクロサービス基盤・・・?

  • 別に社内的にはそう呼ばれてるわけではないけど、なんとなくそういう言い方してみた
  • とにかく、いろんな社内の様々なサービス同士のデータやりとりするのに使う
18 / 76
  • マイクロサービス増えると連携の仕組み工夫したほうがいいよね?
  • なぜそこでKafkaが適切なのか?

そういった話さえも省略して、ひたすら具体的な実践結果を報告していく

そういった話は探せば出てくるので

19 / 76

社内的なサービス要件

  • 落ちない、ずっと動き続ける
    • 当たり前だが、他のシステムよりそれが求められる
  • とにかくAt Least Onceの死守
  • Exactory Onceや順序保証はひとまずしない
20 / 76

歴史

  • 2015年2月
    • 作りはじめる(RabbitMQ)
    • kafkaを一瞬検討したが、publishのack出来ないのでは?と勘違いして却下
  • 2015年3月, 4月
    • 作るというよりは、ほぼRabbitMQの検証や設計の話し合い
21 / 76

歴史

  • 2015年5月
    • スケールや耐障害性考えるとRabbitMQ辛いね、となり、Kafkaで作ることになるという方向転換
  • 2015年6, 7, 8 月
    • 頑張って実装
    • Akkaつらい
22 / 76

歴史

  • 2015年9月
    • 大体完成してて、ひたすら負荷試験と改善の日々
  • 2015年10月
    • 動き出した(まだ本格的な利用チームなし)
23 / 76

歴史

  • 2015年11月
    • 社内のいろんなところから試験的に利用してもらうための調整
    • 管理ツールなどを充実させる
    • kafka 0.9 がリリースされる
  • 2015年12月
    • kafka 0.9 の調査や検証
    • ある程度利用するチームが増えてくる
24 / 76

歴史

  • 2016年1月
    • kafka 0.9 の調査や検証
    • つい数日前に無停止で0.8.2.1から0.9.0.0のアップデートに成功!
25 / 76

0.8から0.9の無停止
アップデート

  • それぞれのbroker1台毎に順にやる
  • zookeeperはアップデート必要なし
26 / 76

0.8から0.9の無停止
アップデート

  • 全broker設定に inter.broker.protocol.version=0.8.2.X を追加
  • その状態でkafkaを0.9にアップデート
  • inter.broker.protocol.version0.9.0.0に変更
  • client側をアップデート(任意)
27 / 76

RabbitMQやめた理由

  • subscriber数に対してスケールアウトしない気がした(ある意味設計上の問題?)
  • publisherのスケール面倒
  • 分散DBとしてのスケールアウト性能がkafkaに比べたら弱い
  • kafkaのほうが、subscriberが多い場合データ保持量が少なくてすむ
28 / 76

kafka以外の全体的なシステム

  • 他とのインターフェイス部分
    • httpでデータを受け付ける
    • httpでデータ送る
    • AMQPでデータ送る
    • その他も増えるかも?(pull型作りたい)
  • つまり(今のところ)Kafkaと直接通信させない
  • その他MySQL(ちょっとした管理用データ)、manageサーバー、ログ収集して置くところ、など
29 / 76

既存のhttpアダプタないの?

30 / 76

httpでの受け付け

  • playframework(2.4)で受け取る
  • publish可能なトピックやパブリッシャの権限チェック
  • kafkaに送る
  • レスポンス返す
31 / 76

kafkaから取得して他へ
送りつける

  • サブスクライバ毎にAkka Actor動かす(akka2.3)
  • kafkaから一定数(100個くらい)とってくる
  • 送る
    • httpなら事前に指定されたURLに
    • AMQPなら指定されたキューに入れる
  • 全部送ったらコミット
32 / 76

kafkaから取得して他へ
送りつける

  • At Least Onceを死守するためのコミットタイミングと、パフォーマンスの兼ね合いが難しい
  • Kafkaに入れる方に比べて100倍くらい(?)難しい
  • reactive-kafka使っても良かった気がする・・・?(全部akkaで独自実装)
33 / 76

kafkaの冗長度など

  • replication factorは3に
  • 書き込むときは3台全部に書き込まないとOKにしてない
  • LinkedInより厳しい?
  • LinkedInは基本2と書いてあった記憶
  • min.insync.replicaは2
34 / 76

設定について

  • 結構多くの設定項目がある
  • デフォルトだとat least onceにならない
  • 接続情報などの、当たり前に変える設定を除いて紹介
  • まだまだ設定を調整しての試験をやりきれていない
  • 0.8のときに調査検証したのが主なので、0.9になってもっと色々あるかも?
35 / 76

デフォルトから変えた設定(broker)

  • auto.create.topics.enable=false
  • unclean.leader.election.enable=false
    • デフォルトのままだと、最悪データ消える?
  • delete.topic.enable=true
    • テストとかで必要だった(?)
36 / 76

デフォルトから変えた設定(broker)

  • kafka.offsets.topic.num.partitions=200
    • デフォルト50
    • 後から変えられない、かつパフォーマンスに影響するので慎重に考える必要?
37 / 76

デフォルトから変えた設定(producer)

  • metadata.fetch.timeout.ms
    • 6000 から 3000
  • timeout.ms
    • 30000 から 3000
38 / 76

デフォルトから変えた設定(producer)

  • acks
    • 1 から all
    • 重要
  • retries
    • 0 から 3
    • 3という深い理由なし?
39 / 76

デフォルトから変えた設定(consumer)

  • auto.offset.reset=smallest
  • offsets.storage=kafka
  • dual.commit.enabled=false
  • auto.commit.enable=false
  • consumer.timeout.ms
40 / 76

罠など

  • clientがどれ使えばいいかわかりづらい問題
    • とくに0.9出る前は酷かった
  • 公式にそれぞれ2種類以上ある
    • Consumerは厳密には3種類
  • producerはnewがいいらしい
    • new使った
  • 0.8時点では、新consumerは作りかけなのにjarがcentralにpublishされてて罠
    • 0.9では一応完成したらしい?
41 / 76

作りかけなのに
maven centralに
publish?

42 / 76
  • 互換性のため、(0.8では?)デフォルトだとoffsetの保存先がzookeeperだが、明示的にkafkaに変更する
    • そもそもoffsetをサーバーで管理しないと言いながら、offset自体を保存するのにkafka使う構造になってるというのを理解するのに時間かかった
44 / 76
  • LinkedInは(少なくとも古いversionで動かす際)zkがボトルネックになるから、SSD使ってるらしいみたいな知見
45 / 76

つらかったところ

  • KafkaのソースがScala的に残念
  • producerもconsumerも、APIがいけてなくて使いづらい(とくにconsumer)
    • 0.9になって新しいconsumerになったので、それへの移行計画中
  • topic作り過ぎるとパフォーマンス落ちる?
  • 高負荷かけるとGCで止まる
46 / 76

Kafkaのコードが残念

47 / 76

Kafkaのコードが残念

48 / 76

Kafkaのコードが残念

49 / 76

Kafkaのコードが残念

50 / 76

Kafkaのコードが残念

51 / 76

Publicかつvarかつmutableなコレクション!?

public-var-mutable

KafkaController.scala

52 / 76

Kafkaのコードが残念

53 / 76

producerやconsumer

  • とくにconsumerがつらい(0.8)
  • 原理上はoffset戻せば読み直せるけど、実際やろうとすると難しい
54 / 76

consumer

  • offsetのコミットが細かくできない
    • 少なくとも0.8の古いconsumerは
  • そのせいで若干効率悪い処理になってるかも
  • そもそもIteratorを返してnextがブロックするという謎インターフェイス
    • 普通Javaでもせめてコールバック受け渡すかたちにするのでは・・・
55 / 76

topicやpartition
作りすぎるとつらい?

56 / 76

topicやpartition
作りすぎるとつらい?

  • replication factorを少なくすると改善するという実験結果
    • 信頼性とのトレードオフ?
    • 他に方法ないのか?
57 / 76

topicやpartition
作りすぎるとつらい?

  • 0.8でも0.9でも変わらない
  • topicというより、正確にはpartition数とtopic数の組み合わせ(掛け算)
  • 流量が多いtopicでは、partitionを増やすと速くなる(可能性がある)
58 / 76
  • topicやpartitionの数の設計が超重要ということだけはわかったが、ベストプラクティスは出ていない?
  • どういった粒度で作ることにするのか?かなり重要だがベストプラクティス決めるの難しい
    • 今のところ、partition数 1 ~ 3 くらいな、かなり少なめでやる方針
59 / 76
60 / 76

GCで止まるのが発覚した経緯

  • 高負荷にするとpublishが稀に失敗する(timeout)
  • 原因特定のため、publisherのログレベル下げる
  • ここ のログに注目、解析
  • リーダーやレプリカが入れ替わっている!?
61 / 76
  • なぜリーダーが入れ替わっているのか探るためkafkaのbrokerのログみる
  • あまり有用な情報すぐには見つからない
  • GCのログみる(brokerはデフォルトで出すようになってる)
  • Full GCで止まってる!?
62 / 76

GCで止まる

  • 今のところ1万〜2万QPSだとFull GC発生確率あり
  • メモリ1Gだと、3, 4秒止まる?
  • メモリを4Gにしたら悪化(12秒止まったことあり)
64 / 76

GCで止まる

  • そもそもkafkaのbrokerはひたすらOSのページキャッシュ使う設計なのでメモリいらない
  • いきなり数万QPSの利用はないはずだが、それが必要になった場合、どうするかは未確定
65 / 76

GCとの戦い

66 / 76

GCとの戦い

  • JMX有効にする?
  • broker側、publisher側の両方で、もっとログの監視強化?
67 / 76

GCとの戦い

  • 負荷試験環境でjmapとか実行できるようにJDKも入れておく?
  • とにかくFull GCを起こさずマイナーGCのみになるように頑張る?
  • Full GC発生諦めて、別の方向性の対策
    • 今のところそんなものはなし
68 / 76

kafkaクライアントライブラリ(Scala)

結局どれも使わなかった

69 / 76

今後個人的に
やりたいこと(実際やるか不明)

  • チューニング
  • 耐障害性のさらなる調査、強化
  • Topicの設計問題や、使われ方の統一
  • 遅延の監視の強化
  • 利用者から使いやすい仕組み
70 / 76

チューニング

  • 設定色々変えるだけで速くなる可能性
  • GC問題
  • ConsumerのScalaのActorのコードが一部効率悪いかも
  • snappyの利用、検証
71 / 76

耐障害性の調査、強化

  • ある程度の実験はしたけど、もっとやる?
  • 無停止でのDisk増設やリバランス
72 / 76

Topicの設計

  • 多すぎるとつらい問題の解決
  • そもそも内部的に持ってるスキーマなどを見直す?
  • 社内での使われ方統一していかないといけない
73 / 76

遅延の監視の強化

  • 今はLinkedin製のもの使ってる
  • ある程度使えるけど、細かいところの調整やさらなる他のものとの併用?
74 / 76

社内の利用者から使いやすい

  • 利用者向けAPIを充実させるなど?
  • トピックの中身のサンプル見れる?
  • 到達にどのくらい時間かかったかなどが見れる?

利用者が大量になって本当に必要になったらやったほうがいいかもしれないけど
完全に現状では雑なアイデアなレベル

75 / 76
  • 終わり?
  • 質問タイム?
76 / 76

発表後に追記

当日の発表動画はこちら

2 / 76
Paused

Help

Keyboard shortcuts

, , Pg Up, k Go to previous slide
, , Pg Dn, Space, j Go to next slide
Home Go to first slide
End Go to last slide
b / m / f Toggle blackout / mirrored / fullscreen mode
c Clone slideshow
p Toggle presenter mode
t Restart the presentation timer
?, h Toggle this help
Esc Back to slideshow