Kafkaクラスタの安定性を向上させるCustom Partitionerの紹介 #kafkajp

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についてお話しさせていただきました。

profile-image

2023年10月からSpeaker Deckに移行しました。最新情報はこちらをご覧ください。 https://speakerdeck.com/lycorptech_jp

シェア

またはPlayer版

埋め込む »CMSなどでJSが使えない場合

(ダウンロード不可)

関連スライド

各ページのテキスト
1.

Kafkaクラスタの安定性を向上させる Custom Partitionerの紹介 ヤフー株式会社 データ統括本部データプラットフォーム本部 データデリバリー部 橘 拓⾺ ©2020 Yahoo Japan Corporation All rights reserved.

2.

⾃⼰紹介 橘 • 拓⾺ データ統括本部データプラットフォーム本部 データデリバリー部所属 • Kafkaと向き合い始め3年⽬ • 趣味︓ • 旅⾏(Go to ⼀⼈旅しました) • エレクトーン演奏 • IoT(ハッカソンのネタにしがち) ©2020 Yahoo Japan Corporation All rights reserved. 2

3.

背景 Kafkaでは、⽋損なくDataをProduceし続けるためには min.insync.replicas = 2以上, acks=allに設定し、2つ以上のレプリカを維持する必要 万⼀これを下回るとその間は… Produceが停⽌(Brokerが拒否)する ©2020 Yahoo Japan Corporation All rights reserved. 3

4.

背景 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

5.

要求事項と⼀般的な解決⽅法 ヤフー社内のデータパイプラインは • End to Endでログを⽋損なく運ぶこと • クラスタがリクエストを受け⼊れられる状態を保ち続けること の両⽴が求められている 単純な解決策 ︓Replica数の増加 • 費⽤増⼤ • Replicationの負荷増⼤ • 何台増やしても根本的解決にならない ©2020 Yahoo Japan Corporation All rights reserved. 不採⽤ 5

6.

要求事項と⼀般的な解決⽅法 ヤフー社内のデータパイプラインは • End to Endでログを⽋損なく運ぶこと • クラスタがリクエストを受け⼊れられる状態を保ち続けること Replica数に頼らない解決策が必要 の両⽴が求められている 単純な解決策 ︓Replica数の増加 • 費⽤増⼤ • Replicationの負荷増⼤ • 何台増やしても根本的解決にならない ©2020 Yahoo Japan Corporation All rights reserved. 不採⽤ 6

7.

発想の転換 Replica数が2を下回らないように努⼒する Replica数が2を下回っても問題ないように⼯夫する Replica数が2を下回るPartitionだけ避ければ Produceを続⾏できそう ©2020 Yahoo Japan Corporation All rights reserved. 7

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 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

9.

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

10.
[beta]
基本的な実装イメージ
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

11.

周辺の実装ポリシー ⼀度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

12.

実装ポリシーと設定変更 (MirrorMaker) MirrorMakerはProduceに失敗したら Offset Commitを⾏わずプロセス終了という実装 RecordのConsume => MirrorMakerではProduceに失敗しても データロストしない RecordのProduce Produce失敗︖ Yes No Offset Commit プロセス終了 ©2020 Yahoo Japan Corporation All rights reserved. 12

13.

実装ポリシーと設定変更 (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

14.

実装ポリシーと設定変更 (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

15.

実装ポリシーと設定変更 (Go Producer) • Go Producerではエラーを起こしたメッセージを再び新たなメッセージとして Produceを⾏うためリトライ⽤コンポーネントを新たに設計/実装 • retriesを短めに設定することで、失敗したメッセージはもう⼀度Produceされる From Source Producer To Kafka Broker Only Failed Message ©2020 Yahoo Japan Corporation All rights reserved. 15

16.

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

17.

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

18.

結果 通信障害によりReplica数が1になるPartitionが複数発⽣しても、 Produceに影響は出なかった🎉 Q:どこが障害発⽣時刻かわかりますか︖ ©2020 Yahoo Japan Corporation All rights reserved. 18

19.

結果 通信障害によりReplica数が1になるPartitionが複数発⽣しても、 Produceに影響は出なかった🎉 ここ↑ ©2020 Yahoo Japan Corporation All rights reserved. 19

20.

結果 通信障害によりReplica数が1になるPartitionが複数発⽣しても、 Produceに影響は出なかった🎉 メッセージ到達率 もちろん⽋損なし︕ ©2020 Yahoo Japan Corporation All rights reserved. ここ↑ 20

21.

余談: 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

22.

3.Failover Partitioner 参考 こちらの話の⼀部はYahoo Japan Tech Blogにも掲載されていますので ぜひご⼀読ください https://techblog.yahoo.co.jp/entry/20191216789293/ ©2020 Yahoo Japan Corporation All rights reserved. 22

23.

まとめ l Replica数が2を下回っても⽋損なくProduceを続けるため Failover Partitionerを開発 l ProducerはPartitioningを再度⾏うことはできないため、 Replica数が下回った際の失敗メッセージを拾って再送する⼯夫が別に必要 l 本番環境下で実際に運⽤し、 実際の障害時でも正常にProduceを続けることに成功︕ ©2020 Yahoo Japan Corporation All rights reserved. 23

24.

©2020 Yahoo Japan Corporation All rights reserved.