1.9K Views
December 21, 20
スライド概要
2020/12/18に行われたApache Kafka Meetup Japan #8での発表資料です。
当日のイベントページはこちらです:https://kafka-apache-jp.connpass.com/event/196426/
Kafka Clusterの安定性を向上させるためにヤフー社内で実装し、本番投入したCustom Partitionerについてお話しさせていただきました。
2023年10月からSpeaker Deckに移行しました。最新情報はこちらをご覧ください。 https://speakerdeck.com/lycorptech_jp
Kafkaクラスタの安定性を向上させる Custom Partitionerの紹介 ヤフー株式会社 データ統括本部データプラットフォーム本部 データデリバリー部 橘 拓⾺ ©2020 Yahoo Japan Corporation All rights reserved.
⾃⼰紹介 橘 • 拓⾺ データ統括本部データプラットフォーム本部 データデリバリー部所属 • Kafkaと向き合い始め3年⽬ • 趣味︓ • 旅⾏(Go to ⼀⼈旅しました) • エレクトーン演奏 • IoT(ハッカソンのネタにしがち) ©2020 Yahoo Japan Corporation All rights reserved. 2
背景 Kafkaでは、⽋損なくDataをProduceし続けるためには min.insync.replicas = 2以上, acks=allに設定し、2つ以上のレプリカを維持する必要 万⼀これを下回るとその間は… Produceが停⽌(Brokerが拒否)する ©2020 Yahoo Japan Corporation All rights reserved. 3
背景 Kafkaでは、⽋損なくDataをProduceし続けるためには min.insync.replicas = 2以上, acks=allに設定し、2つ以上のレプリカを維持する必要 万⼀これを下回るとその間は… Produceが停⽌(Brokerが拒否)する 加えてどちらかを選択する必要がある unclean.leader.election.enable = True => 復帰時にPartiion内で⽋損する可能性 unclean.leader.election.enable = False => Leader復帰までProduceが停⽌する ©2020 Yahoo Japan Corporation All rights reserved. 4
要求事項と⼀般的な解決⽅法 ヤフー社内のデータパイプラインは • End to Endでログを⽋損なく運ぶこと • クラスタがリクエストを受け⼊れられる状態を保ち続けること の両⽴が求められている 単純な解決策 ︓Replica数の増加 • 費⽤増⼤ • Replicationの負荷増⼤ • 何台増やしても根本的解決にならない ©2020 Yahoo Japan Corporation All rights reserved. 不採⽤ 5
要求事項と⼀般的な解決⽅法 ヤフー社内のデータパイプラインは • End to Endでログを⽋損なく運ぶこと • クラスタがリクエストを受け⼊れられる状態を保ち続けること Replica数に頼らない解決策が必要 の両⽴が求められている 単純な解決策 ︓Replica数の増加 • 費⽤増⼤ • Replicationの負荷増⼤ • 何台増やしても根本的解決にならない ©2020 Yahoo Japan Corporation All rights reserved. 不採⽤ 6
発想の転換 Replica数が2を下回らないように努⼒する Replica数が2を下回っても問題ないように⼯夫する Replica数が2を下回るPartitionだけ避ければ Produceを続⾏できそう ©2020 Yahoo Japan Corporation All rights reserved. 7
Failover Partitioner Topic A , Par,,on 0, Replica 0 Topic A , Par,,on 1, Replica 1 Topic A , Par,,on 0, Replica 1 Topic A , Par,,on 1, Replica 0 Topic A , Par,,on 0, Replica 2 Topic A , Par,,on 1, Replica 2 Producer Produce Broker PartitionのReplica数を確認、Replica数が2を下回ったPartitionは利⽤不可と判断。 => そのPartitionにProduceする予定だったデータは別のPartitionにProduce ©2020 Yahoo Japan Corporation All rights reserved. 8
Failover Partitioner Topic A , Par,,on 0, Replica 0 Topic A , Par,,on 1, Replica 1 Topic A , Par,,on 0, Replica 1 Topic A , Par,,on 1, Replica 0 Go Producer Topic A , Par,,on 0, Replica 2 Mirror Maker 一次受けクラスタ 集約クラスタ ( ) ヤフーでは2箇所に実装済み • Sarama Producer(Golang) • MirrorMaker (Java) Producer Topic A , Par,,on 1, Replica 2 Produce Broker PartitionのReplica数を確認、Replica数が2を下回ったPartitionは利⽤不可と判断。 => そのPartitionにProduceする予定だったデータは別のPartitionにProduce ©2020 Yahoo Japan Corporation All rights reserved. 9
基本的な実装イメージ
KafkaのPartitionメソッドに与えられるcluster変数から inSyncReplicas の情報が取れるので
その情報をもとにPartitionListを作り直す
=> 作り直したPartitionListを元にRoundrobinでPartitioning
public static final int MIN̲INSYNC̲REPLICAS = 2;
/**
* @param topic The topic name
* @param cluster The current cluster metadata
*/
private List<Par77onInfo> createAlivePar--onList(String topic, Cluster cluster) {
実装イメージ(Java)
List<Par--onInfo> topicAlivePar--onList = new ArrayList<>();
List<Par--onInfo> par--ons = cluster.par--onsForTopic(topic);
par--ons.stream()
.filter(p -> p.inSyncReplicas().length >= MIN_INSYNC_REPLICAS)
.forEach(p -> topicAlivePar--ons.add(p));
return topicAlivePar--onList;
}
©2020 Yahoo Japan Corporation All rights reserved.
10
周辺の実装ポリシー ⼀度Partitioningをしたログはリトライ時に再度Partitioningができない • PartitionごとにBatchキューを作成し、 Batchキューの中のリクエスト単位でリトライを⾏うため Procucer Producer Thread … ここで Par((oning Sender Thread ここで リトライ Batch Queue => min.insync.replicaが下回った瞬間のFailoverができない 新たなリトライ戦略が必要 ©2020 Yahoo Japan Corporation All rights reserved. 11
実装ポリシーと設定変更 (MirrorMaker) MirrorMakerはProduceに失敗したら Offset Commitを⾏わずプロセス終了という実装 RecordのConsume => MirrorMakerではProduceに失敗しても データロストしない RecordのProduce Produce失敗︖ Yes No Offset Commit プロセス終了 ©2020 Yahoo Japan Corporation All rights reserved. 12
実装ポリシーと設定変更 (MirrorMaker) MirrorMakerはProduceに失敗したら Par$$onList⽣成 Offset Commitを⾏わずプロセス終了という実装 RecordのConsume => MirrorMakerではProduceに失敗しても データロストしない RecordのProduce Produce失敗︖ No Yes 初回起動時にReplicaが2以上のPartitionListを作成 Offset Commit + プロセスダウンはsupervisordなどで再起動 プロセス終了 ©2020 Yahoo Japan Corporation All rights reserved. 13
実装ポリシーと設定変更 (MirrorMaker) Par$$onList⽣成 RecordのConsume ⼀般に推奨されるretries = 2147483647 RecordのProduce Produce失敗︖ No Offset Commit (=INTMAX)では失敗と判断されるまでに Yes かなり時間がかかるため変更 (流量依存だが1-2分でretryが終了する程度の retry回数を選定) プロセス終了 ©2020 Yahoo Japan Corporation All rights reserved. 14
実装ポリシーと設定変更 (Go Producer) • Go Producerではエラーを起こしたメッセージを再び新たなメッセージとして Produceを⾏うためリトライ⽤コンポーネントを新たに設計/実装 • retriesを短めに設定することで、失敗したメッセージはもう⼀度Produceされる From Source Producer To Kafka Broker Only Failed Message ©2020 Yahoo Japan Corporation All rights reserved. 15
Go Producerの実装上の⼯夫点 • SaramaではProducerのinput/outputはgoroutine/channelを使って実装 => 失敗したchannelをそのままinputのchannelにつなぐと goroutineがデットロック状態に陥る • これを避けるためBufferを中間に挟むが、適切なBufferのサイズはわからない • どのくらいのメッセージが失敗するかは流量や状況によって異なる Producerに流⼊制限を設け、流⼊制限内なら 全メッセージがFailしても問題ないサイズのBufferを⽤意 ©2020 Yahoo Japan Corporation All rights reserved. 16
Go Producerの実装上の⼯夫点 • Sourceからのinputと、KafkaへのProduceに成功したメッセージ数をカウント • 差分をとり、差分が⼀定以上出たらSourceからのinputを⽌める => FailedBufferに⼊る可能性のあるメッセージ数を制限 Message Counter 最終的なアーキテクチャ From Source FailedBuffer Merger Producer To Kafka Broker Only Failed Message どちらのメッセージをProducerに流すかを制御 ©2020 Yahoo Japan Corporation All rights reserved. 17
結果 通信障害によりReplica数が1になるPartitionが複数発⽣しても、 Produceに影響は出なかった🎉 Q:どこが障害発⽣時刻かわかりますか︖ ©2020 Yahoo Japan Corporation All rights reserved. 18
結果 通信障害によりReplica数が1になるPartitionが複数発⽣しても、 Produceに影響は出なかった🎉 ここ↑ ©2020 Yahoo Japan Corporation All rights reserved. 19
結果 通信障害によりReplica数が1になるPartitionが複数発⽣しても、 Produceに影響は出なかった🎉 メッセージ到達率 もちろん⽋損なし︕ ©2020 Yahoo Japan Corporation All rights reserved. ここ↑ 20
余談: KIP-637 今年の夏にKafkaのMetadataにmin_insync_replicasを⼊れるという KIPが登場したため、もしこれが進めば公式でFailover Partitionerが 提供される可能性がある (ただし12/4現在Under discussionであるため 全く議論が進んでおらず、Fix Versionも未定…) https://cwiki.apache.org/confluence/display/KAFKA/KIP637%3A+Include+min.insync.replicas+in+MetadataResponse+to+make+Pro ducer+smarter+in+partitioning+events ©2020 Yahoo Japan Corporation All rights reserved. 21
3.Failover Partitioner 参考 こちらの話の⼀部はYahoo Japan Tech Blogにも掲載されていますので ぜひご⼀読ください https://techblog.yahoo.co.jp/entry/20191216789293/ ©2020 Yahoo Japan Corporation All rights reserved. 22
まとめ l Replica数が2を下回っても⽋損なくProduceを続けるため Failover Partitionerを開発 l ProducerはPartitioningを再度⾏うことはできないため、 Replica数が下回った際の失敗メッセージを拾って再送する⼯夫が別に必要 l 本番環境下で実際に運⽤し、 実際の障害時でも正常にProduceを続けることに成功︕ ©2020 Yahoo Japan Corporation All rights reserved. 23
©2020 Yahoo Japan Corporation All rights reserved.