カフカ安全プロデューサー
カフカのアプリケーションシナリオが異常(例えば、ネットワークの異常)が発生する場合に考慮される必要がある、メッセージが順不同で、欠落、およびメッセージを繰り返すことができるが伝送されます。
このような場合のために、我々はこれらの問題を回避するために使用される「安全なプロデューサー」を、作成することができます。以下は、私たちは、最初に紹介し、状況にこれらのタイプのための設定を説明します。最後に、構成例を。
1.のACKの詳細
我々はカフカを導入する前にACKのプロデューサーたちは、これらの三つのモードを紹介し、さらに下に、3つのモードがあります。
1.1。 = 0のACK (NOのACK )
意味= 0使用のACK:
- メッセージを送信した後、応答する必要はありません
- 組立ラインオフブローカーまたは障害が発生した場合、我々は知らないだろう、とブローカーが生産者への応答を返さないため、データを失うことになります
= 0の動作モードのACK以下に示すように、任意のACKを受信する必要はありません。
ACKの一般的な使用は、= 0シナリオがある:データは失われる可能性が受け入れることができます。例えば:
- インデックス情報の収集
- 収集ログ(ログデータ薬学的にいくつかの時折の損失)
1.2。 ACK = 1 (リーダーのACK )
次の場合のACK = 1を使用します
- プロデューサーは、メッセージが受信されたことを確認するために、応答のリーダーを取得する必要があります。しかし、複製は(バックグラウンドで複製を実行)ではない、それは保証を受けているかどうかであります
- プロデューサーは、ACKを受信しない場合は、再試行することがあり
次の図の= 1つの作品のACK、プロデューサーは、各ACKメッセージを受信する必要があります。
- リーダーブローカーがオフラインの場合または失敗したが、また、送信されたデータのレプリカがコピーされていない、我々はデータの損失を持っています
- これがデフォルトのモードです
1.3。 ACK =全て(レプリカのACK )
ACKを使用している場合=すべて:
- リーダーのニーズとACKのレプリカ
- 待ち時間の増加と高いセキュリティ「のデータが失われることはありません」
- 十分なレプリカがある場合は、データの消失はありません。
ACK =全て1は次のように、各レプリカは書き込み書き込みを確保するために、ACK返信する必要があります動作します。
あなたは完全にデータを失うする必要がある場合は、この設定は考慮する必要があります。
min.insync.replicas:(即ちレプリカのACK)全てのACKの=を提供される場合、それは他のパラメータ、すなわち、一緒に使用されなければなりません。
- min.insync.replicasブローカレベルパラメータはレベル設定(オーバーライド)またはトピックを設けてもよいです
- min.insync.replicas = 2で表される少なくとも2つのブローカは、(リーダーを含む)ISR(イン同期レプリカ)であり、それらは、データを表現するために応答する必要があり、そうでない場合はエラーが返されます。このパラメータは、最も一般的な構成である2を設定します。
データが送信されるか、プロデューサがエラーを受信する場合、パラメータreplication.factor = 3、min.insync = 2、のACK =全て、唯一最大許容例外ブローカー1設定仮定する。
異常な場合、2つのブローカが存在する請求項3つのブローカー、min.insync.replicas = 2が存在すると仮定し、プロデューサーは「NOT_ENOUGH_REPLICAS」例外を受け取ります。
2.プロデューサーの再試行
(例えばNotEnoughReplicasExceptionのための)いくつかの一時的なエラーは、アプリケーション全体に影響を与えないようにするためには、一般的に我々は、データの損失を避けるために、いくつかの例外に対処する必要があります。また、プロデューサーの再試行の設定で、デフォルトではその値は、手動で調整することができInteger.MAX_VALUEのまで可能、0です。
再試行では、デフォルトでは、それはメッセージを順不同で送られる原因になります。一般的なメッセージ送信失敗が再度キューに入り、再度送信することができるので、メッセージは、いくつかの障害が発生します。
この場合、キーベースのメッセージ・シーケンス、特に深刻。同じキーを持つすべてのメッセージが同じパーティションに送信されますので、メッセージ、その後、再送さを再キューイングすることがあれば、そして、パーティションがスクランブル鍵の一部となります。
同時に、生産要求の数が並行して開始することができます。この場合、我々は、パラメータmax.in.flight.requests.per.connectionコントロールを設定することができます。
- デフォルトは5です
- 完全なメッセージの再試行を確保するために厳格かつ秩序を維持することができる場合は、このパラメータを1に設定することができます(ただし、スループットに影響を与える可能性があります)
しかし、カフカが> =このシーンのためでは1.0.0がよりよい解決策になり、これの一部は後述します。
3.べき等プロデューサー
再送シーンでは、我々は共通の問題に遭遇しました:によりネットワークに、プロデューサーはカフカで重複したメッセージでご紹介します。
下図のように:
要求は通常のリクエストです:
- プロデューサーはカフカにメッセージを送信します
- カフカは、このメッセージをコミット
- カフカACKプロデューサーを送り返します
しかし、要求手順を生成する繰り返しメッセージです。
- プロデューサーはカフカにメッセージを送信します
- カフカは、このメッセージをコミット
- カフカは、ネットワークの理由のために、プロデューサーに戻ってACKを送信、ACKは、プロデューサーの終わりに到達していません
- いくつかの時間プロデューサーの再送信メッセージの後
- カフカは、プロデューサーに、この重複ACKメッセージとリターンをコミット
それがACKを受信したため、生産の観点から、それは、唯一の通常の送信メッセージです。ビューのカフカの観点から、それは2つのメッセージを受け取ったので、二回コミット。
カフカ後> = 0.11は、あなたが「冪等プロデューサー」を定義することができ、ネットワークの問題によって引き起こされる重複メッセージを解決することができます。下図のように:
冪等の生産のために、プロセスは、処理要求メッセージである繰り返します。
- プロデューサーは、メッセージを送信します
- カフカは、メッセージを受信し、コミット
- カフカは、ネットワークの問題のプロデューサーに到着していないプロデューサーACKに送り返さ
- Producer重试发送消息,在Producer>=0.11 的版本中,消息里会带上一个produce request id
- Kafka收到消息后,通过对比produce request id,可以辨别出这条消息是一条重复的消息,所以不会再次commit,并会再次发送一个ack
Idempotent producers可以很好的保证一个稳定,以及无重复数据的pipeline。
伴随Idempotent producers一起被设置的参数有:
- retries = Integer.MAX_VALUE (2^31-1 = 2147483647),也就是说基本会在出错时无限重传
- max.in.flight.requests=1 (Kafka >= 0.11 & < 1.1) ,也就是说在这些版本中,若是设置max.in.flight.requests > 1时仍会有可能产生乱序数据
- 或者 max.in.flight.requests=5 (Kafka >= 1.1 –> High Performance),也就是说在高于1.1版本的Kafka中,设置max.in.flight.requests=5也可以在保证不乱序的同时,保证并行的高性能
对于Idempotent Producer的配置,仅需配置类似以下参数即可:
properties.setProperty(ProducerConfig.ENABLE_IDEMPOTENCE_CONFIG, "true");
4. Safe Producer 配置总结
上面介绍了创建一个safe producer 所需的配置,下面我们总结一下在不同版本的Kafka中所需要做的配置:
Kafka < 0.11
- ack=all (procuder level):确保在发送ack前,数据已经正常备份
- min.insync.replicas=2 (broker/topic level):确保至少有两个in ISR 的brokers 有数据后再回送ack
- retires=MAX_INT (producer level):确保在发生瞬时问题时,可以无限次重试
- max.in.flight.requests.per.connection=1 (producer level):确保每次仅有一个请求发送,防止在重试时产生乱序数据
Kafka >= 0.11
- enable.idempotence=true (producer level) + min.insync.replicas=2 (broker/topic level)
- 隐含的配置为 acks=all, retries=MAX_INT, max.in.flight.requests.per.connection=5 (default)
- 可以在保证消息顺序的同时,提高performance
这里必须要提到的是:运行一个“safe producer”可能会影响系统的throughput与latency,所以在应用到生产系统前,必须先做测试以判断影响。
5. safe producer 示例
我们按照之前的步骤启动一个由Java编写的Kafka Producer,并查看输出的配置,可以看到默认的部分参数为:
acks = 1
enable.idempotence = false
max.in.flight.requests.per.connection = 5
retries = 2147483647
现在我们显式地加上以下参数:
// create a safe Producer properties.setProperty(ProducerConfig.ENABLE_IDEMPOTENCE_CONFIG, "true"); properties.setProperty(ProducerConfig.ACKS_CONFIG, "all"); properties.setProperty(ProducerConfig.MAX_IN_FLIGHT_REQUESTS_PER_CONNECTION, "5"); properties.setProperty(ProducerConfig.RETRIES_CONFIG, Integer.toString(Integer.MAX_VALUE));
然后查看producer配置的部分输出为:
以上为创建一个safe producer所需的配置介绍以及示例,在实际生产环境中,务必要先测试safe producer 对应用吞吐以及延时的影响后,再斟酌是否有必要对参数做部分调整。