[カフカ] "カフカDefinitive Guideの" - データを書き込みます

メッセージキュー、メッセージ、バスやデータ・ストレージ・プラットフォームとしてのカフカを使用するには、常にあなたが生産者と消費者を持っている必要がありカフカを書くことができるかどうかは、カフカへのデータからデータを読み取るか、の2種類の両方ができアプリケーションロール。

例えば、クレジットカードのトランザクション処理システムでは、クライアントアプリケーションがあり、それはカフカへのトランザクションの送信を担当し、オンラインストア、いつでも支払いの行動であってもよいです。別のアプリケーション・ルール・エンジンは、承認または拒否の決定に従って、このトランザクションをチェックします。承認または拒否応答メッセージが戻っカフカに書き込まれ、その後、オンラインストアに送信されたトランザクションを開始しました。第3のアプリケーションは、カフカから読み取った後、アナリストは、これらの結果を分析することができ、データベースに保存し、事務の状態を確認し、ルールエンジンを改善するために取ることができるかもしれません。

開発者は、組み込みのクライアントAPIカフカカフカ開発するアプリケーションを使用することができます。

この章では、我々は、設計、部品生産、カプラの話を、カフカの生産を使用する方法を学習します。私たちは、カフカにレコードを送信する方法を、KafkaProducerとProducerRecordsオブジェクトを作成する方法を紹介します、そしてどのようにエラーを処理するためには、カフカから返され、その後、乾燥して生産者の行動を制御することが重要な構成オプションを紹介し、さまざまなパーティション化メソッドとシーケンスを使用する方法については、最終的な深さの議論ガス化炉、そしてどのようにパーティショナおよびシリアル化をカスタマイズします。

次の章では、カフカからのメッセージを読み取る方法と同様に、クライアントによって静かな、カプラの料金をご紹介します。

プロデューサーの概要

アプリケーションは、カフカのメッセージに、多くの場合に書き込む必要がある:情報インテリジェント家電、他のアプリケーションとの非同期通信を記録し、メッセージを、メトリクスの記録(監査および分析のための)ユーザの活動を記録したログを保存し、バッファデータベースに書き込まれるデータ、およびように。

使用シナリオの様々な多様なニーズを意味する:各メッセージが重複メッセージが時折厳しいレイテンシとスループットの要件がある場合に許容可能な表示された場合、メッセージの小さな部分が失われた許可するかどうかが非常に重要であるかどうか????

前述したクレジットカードのトランザクション処理システムでは、メッセージが失われたメッセージや重複メッセージを許可されていないされ、最大許容遅延は500ミリ秒で、高いスループット要件、我々は毎秒百万のメッセージを扱うことができることを願っています。

保存サイト情報をクリックすると、別の使用シナリオです。このシナリオでは、いくつかのメッセージの損失や重複メッセージの少量を許可し、遅延が高くなることがあり、それはライン上のユーザーエクスペリエンスに影響を与えません。言い換えれば、限り、ユーザーがリンクをクリックすると、すぐにページをロードするために、私たちは、あなたが数秒後にカフカサーバーに取得したいメッセージを気にしません。スループットは、サイトのユーザーのサイトを利用する頻度に依存します。

異なる使用シナリオに直接的な影響は、使用方法や設定のプロデューサーAPIになります。

生産者がAPIを使用するのは簡単ですが、まだ少し複雑なメッセージを送信するプロセス。次の図は、カフカへのメッセージ送信の主なステップを示しています。

図Producerコンポーネントカフカ

私たちは、ProducerRecordオブジェクトを作成することによって、ProducerRecordオブジェクトが送信されるように、ターゲットの件名と内容が含まれている必要があり始めます。また、キーまたはパーティションを指定することができます。彼らは唯一のネットワークを介して送信することができるように、バイト配列の標的配列への生産と最初のキー値にProducerRecordオブジェクトを送信するとき。

次に、データがパーティに渡されます。ProducerRecordは、指定されたパーティション内のオブジェクトの前にあれば、パーティションが返すように指定されたパーティションに直接何もしないです。パーティションを指定しない場合、パーティションは、パーティションProducerRecord・オブジェクト・キーに基づいて選択されます。パーティションを選択した後、プロデューサーは、テーマを分割し、このレコードを送信するかを知っています。その後、このレコードは、バッチ内のレコードに追加され、すべてのメッセージでバッチが同じテーマやパーティションに送信されます。別のスレッドが適切なブローカーに送信されたこれらのバッチ記録を担当してあります。

これらのメッセージサーバを受信すると応答を返します。メッセージが正常にカフカに記述されている場合、それがテーマとパーティションの情報が含まれていRecordMetaDataオブジェクトを返し、パーティションのオフセットを記録します。書き込みに失敗した場合は、エラーが返されます。プロデューサーは、失敗したいくつかの後、または、それはエラーメッセージを返す場合は、メッセージを再送信しようとした後にエラーが発生します。

作成カフカプロデューサー

カフカにメッセージを書き込むために、最初のもいくつかのプロパティを設定プロデューサオブジェクトを作成します。

次のコードは、唯一の必要な属性は、デフォルトの設定を使用して他の指定新しいプロデューサーを作成する方法を示しています。

プライベートプロパティkafkaProps = 新しいプロパティ(); 

kafkaProps.put( "bootstrap.servers"、 "broker1:9092、broker2:9092" )。
 
kafkaProps.put( "key.serializer"、 "org.apache.kafka.common.serialization.StringSerializer" ); 
 
kafkaProps.put( "value.seializer"、 "org.apache.kafka.common.serialization.StringSerializer" ); 
 
プロデューサー = 新しい KafkaProducer <文字列、文字列>(kafkaProps)。

カフカのプロデューサーは、3つの必須属性があります

bootstrap.servers

ポート:この属性は、ブローカーアドレスリストを指定し、アドレス形式は、ホストです。ブローカーのすべてのアドレスのリストに含まれる必要はなく、プロデューサーはブローカー内の他のブローカーに与えられた情報から検索します。しかし、提案されている情報は、1つがダウンしたら、生産者は、まだクラスタに接続することができ、少なくとも二つのブローカーを提供します。

key.serializer

キーブローカと所望の値は、受信したメッセージのバイト配列です。生産者インタフェースがパラメータ化された型の使用を可能にする、Javaオブジェクトのキーと値としてブローカに送信することができます。このコードは、良い読みやすさを持っていますが、生産者は、Javaのバイト配列にこれらのオブジェクトを変換する方法を知っておく必要があります。key.serializer生産がバイト配列にクラスにキーシーケンスを使用しますが、インターフェイスを実装org.apache.kafka.common.serialization.Serializerクラスに設定する必要があります。カフカクライアントはByteArraySerializer(これだけでいくつかのこと)、StringSerializerとIntegerSerializerのデフォルトを提供するので、あなただけのいくつかの一般的なJavaオブジェクトタイプを使用する場合は、独自のシリアライザを実装する必要はありません。注意することは、key.serializerは、あなただけのコンテンツの価値を送信しようとする場合でも、設定する必要があります。

value.serializer

key.serializerと同じように、指定されたクラスのvalue.serializer値がシリアライズされます。キーの文字列と値がある場合は、同じことがkey.serializerシリアライザを使用することができます。キーは整数であり、値が文字タイプのファンである場合は、別のシリアライザを使用する必要があります。

メッセージ主に3つの方法を送信

1-と-忘れて(ファイア・アンド・フォーゲット):私たちは、サーバーにメッセージを送信しますが、うまく到着する正常であるか否かを気にしません。カフカは非常に入手可能であり、生産者は自動的に再送信しようとするので、ほとんどの場合、メッセージは、通常到達します。しかし、この方法は時々メッセージを失います。

2、同期伝送:私たちは、メッセージを送信するための送信()パーティ気分を使用し、それはあなたが情報静かな成功を送信するかどうかを知ることができ、待機するようにget()メソッドを呼び出し、Futureオブジェクトを返します。

3、非同期伝送:我々はセンド()パーティ気分を呼び出し、サーバが応答を返すときに、関数が呼び出され、コールバック関数を指定します。

以下のいくつかの例では、メッセージを送信する方法、および上記のいくつかの方法を使用して発生する可能性が例外を処理する方法を説明します。

この章のすべての例では、シングルスレッドを使用しているが、実際には生産者がメッセージを送信するために複数のスレッドを使用することができます。まず、消費者にはシングルとシングルスレッドを使用することができます。あなたがより高いスループットが必要な場合は、同じ前提の下で生産者の数にスレッド数を増やすことができます。あなたはこれを十分に行う場合は、生産者の数を増やすことができます。

カフカにメッセージを送ります

メッセージの同期を送信するための最も簡単な方法は次のとおりです。

ProducerRecord <文字列、文字列>のレコード=  ProducerRecord <>( "CustomerCountry"、 "精密製品"、 "フランス" );
してみてください{ 
  producer.send(レコード)。
} キャッチ(例外e){ 
  e.printStack()。
}

プロデューサーは、彼らが文字列である、()のパラメータとしてサイドProducerRecordオブジェクトを生きるだろう、それが送信されるテーマとターゲットのキーと値のオブジェクトの名前をとり送ります。キーと値の種類は、標的配列とオブジェクトの生産者と一致する必要があります。

私たちはパーティーProducerRecordオブジェクトを送信するためにプロデューサーのsend()を使用します。アーキテクチャは、図プロデューサからわかるように、メッセージは第1のバッファに配置され、その後、別のスレッドを使用してサーバに送信されます。send()メソッドは、RecordMetadataが含まれているFutureオブジェクトを返しますが、我々は、戻り値を無視するので、メッセージが正常に送信されたかどうかを知ることは不可能です。あなたが結果を送信して気にしないのであれば、あなたは道を送信するためにこれを使用することができます。例えば、Twitterのメッセージのログレコード、以下の重要なアプリケーションのログを記録します。

私たちは、発生する可能性があり、サーバー側でメッセージやエラーを送信するときに発生するエラーを無視することができますが、送信する前に、メッセージ、プロデューサまたは他の可能な異常が起こります。これらの異常は、SerializationException(メッセージシーケンス障害の説明)、BufferExhaustedException又はTimeoutException(説明バッファが満杯である)であってもよく、またはInterruptExceptionは(説明の送信スレッドが中断されている)です。

メッセージの同期を送信

ProducerRecord <文字列、文字列>のレコード=  ProducerRecord <>( "CustomerCountry"、 "精密製品"、 "フランス" );
してみてください{ 
    producer.send(レコード)に.getを(); 
} キャッチ(例外e){ 
    e.printStack()。
}

ここで、producer.send()は最初の側はFutureオブジェクトを返し滞在した後、今後のオブジェクトのget()メソッドを呼び出すことはカフカへの応答を待ちます。サーバーがエラーを返した場合、取得()パーティ気分が例外をスローします。エラーが発生しなければ、我々はRecordMetadataオブジェクトを取得します、あなたはメッセージのオフセットを得るためにそれを使用することができます。すべてのエラーや、ブローカーとして、データを送信する前に、伝送中に発生したが、異常のメッセージを再送信するように返すことが許されていないか、または再送回数を超えた場合は、例外がスローされます。私たちは、単に異常をプリントアウトします。

カフカの生産者から返されたエラーを処理する方法

KafkaProducerは、一般的に2種類のエラーが発生する可能性があります。一つのクラスは、エラーメッセージを再送信することによって解決することができ、エラーを再試行です。たとえば、接続エラーのため、再び接続、「所有されていない(noleader)」を確立することにより解決することができますが、再選挙をすることができます解決するために、パーティションのリーダーとしてエラー。KafkaProducerは、いくつかの再試行後に問題を解決するためにまだ可能なら自動的に再試行するように構成することができ、アプリケーションが再試行例外を受け取ります。エラーのもう一つのタイプは、「ビッグニュース」の例外として、解決を再試行することにより、出てきません。このタイプのエラーのため、KafkaProducerは任意の再試行、直接スローをすることはありません。

非同期メッセージを送信します

メッセージは、アプリケーションとカフカクラスタ間で前後10msのに必要であると仮定する。各メッセージが送信された後、両方の応答を待つ場合は、送信メッセージ100は、1秒を要します。唯一の応答を待たずにメッセージを送信する場合は、その後、100件のメッセージを送信する時間がはるかに少ないが必要です。時間のほとんどは、我々は応答を待つ必要はありません - たとえは、カフカが返送されたトピック、パーティション情報、およびメッセージをターゲットとしますオフセットが、送信側のアプリケーションは必要ありません。しかし、送信が失敗したメッセージの顔に、私たちは、例外をスローし、エラーをログに記録し、以降の分析のためのメッセージ「エラーメッセージ」ファイルを書き込むためにする必要があります。

非同期例外でメッセージを送信するためには、生産者のコールバックサポートを処理することができます。次のメッセージは、非同期コールバックの例を使用して送信されます。

プロデューサーの設定

これまでのところ、我々はわずか数、必要な設定パラメータ--bootstrap.servers APIとシリアライザ生産者を紹介します。

プロデューサーは、ドキュメントカフカで説明されている多くの設定可能なパラメータがあり、それらのほとんどは、合理的なデフォルト値を持っているので、それらを変更する必要はありません。ただし、メモリ使用量、パフォーマンスと生産者のための信頼性が最大の影響でいくつかのパラメータがあり、我々はそれらをなります。

1.のACK

ACKのパラメータは、メッセージを受信して​​いる必要がありますどのように多くのパーティションのコピーを指定し、メッセージがプロデューサーを成功させるに思うだろう書かれています。

このパラメータは、メッセージの損失の可能性に大きな影響を与えます。このパラメータは、次のオプションがあります。
•のACKを= 0の場合、正常に書き込まれたメッセージの前に静かなプロデューサーは、サーバーからの応答を待ちません。これは、サーバーがメッセージを受信しない率いる問題、そして生産者は知らないだろうがある場合、メッセージは失われます、です。しかし、生産者は、サーバーからの応答を待つ必要がないよう、高いスループットを達成するように、最高速度をサポートすることができ、ネットワークにメッセージを送信することができます。

•のACK = 1の場合に限り、クラスタのリーダー・ノードがメッセージを受け取ると、プロデューサーは、サーバからの正常な応答を受信します。メッセージは、(新しいリーダーが選出されていない、そのような怒り崩壊リーダーノードとして)ヒットリーダーノードに到達していない場合は、プロデューサーにはエラーレスポンスを受信すると、データの損失を避けるために、生産者はメッセージを再送信します。ノードが新しいリーダーになるメッセージを受信しない場合は、メッセージが失われます。この時間は、同期または非同期送信、送信のスループットに依存します。あなたは、クライアントが応答を待つ聞かせている場合、サーバ(Futureオブジェクトのget()メソッドを呼び出すことで)送信され、明らかに遅延(ネットワーク上の往復伝送遅延)が増加します。クライアントは、非同期コールバックを使用している場合は、遅延の問題を緩和することができるが、それでもスループットは(サーバーの応答が受信される前に送信することができますどのように多くのメッセージ例えば、プロデューサー)が送信されたメッセージの数の制限によって影響を受けることになります。

•ACKを=すべての場合は、すべてのメッセージのレプリケーションに参加した場合にのみ、すべてのノードは、プロデューサーがサーバーから正常な応答を受信します、受け取りました。このモードは最も安全である、それは、サーバがクラッシュした場合であっても、複数のサーバーがメッセージを受信することを確実にすることができ、クラスタ全体がまだ実行することができます(第5章では、詳細を説明します)。しかし、その遅延=我々は複数のサーバーノードを待つ必要があるため、ACKの1より高いが、メッセージを受信します。

2. buffer.memory

このパラメータは、プロデューサのメモリバッファのサイズを設定するために使用され、そのメッセージバッファと、プロデューサは、サーバに送信されます。アプリケーションの速度がサーバーに送信されたメッセージを送信した場合、速度は十分なスペースの生産につながる超えました。今回は、send()メソッドの呼び出しがブロックされたり、例外をスローされるかは、(max.block.msは、バージョン0.9.0.0に置き換えられましたかblock.on.buffe.fullパラメータに依存し、スロー表明しました前の異常)いくつかの時間のためにブロックすることができます。

3. compression.type

メッセージが圧縮されていないデフォルトでは、。このパラメータは、メッセージ・ブローカが圧縮されるに送られる前に圧縮アルゴリズムを指定てきぱきと、GZIPまたはLZ4を設定することができます。臆病Googleが考案てきぱき圧縮アルゴリズムは、それがより少ないCPUを使用していたが、パフォーマンスおよびネットワーク帯域幅を懸念、あなたはこのアルゴリズムを使用することができる場合には、優れたパフォーマンスとかなりの圧縮率を提供することができます。gzip圧縮アルゴリズムは、通常より多くのCPUを取るが、より高い圧縮率を提供するので、ネットワーク帯域幅が制限されている場合は、このアルゴリズムを使用することができます。使用圧縮は、多くの場合、位置カフカへのメッセージ送信のボトルネックとなっているネットワークのオーバーヘッドの伝送およびストレージのオーバーヘッドを減らすことができます。

4.再試行

間違ったサーバーからの生産は、(例えば、リーダーを見つけることができないパーティションとして)一時的なエラーを受けている可能性があります。この場合、パラメータの値は、メッセージを再送信することができるリトライプロデューサの数を決定し、それがこの数に達した場合、生産者は、再試行を放棄し、エラーを返します。デフォルトでは、プロデューサは、各試行間1OOmsを待つが、この期間はretries.backoff.msパラメータによって変更することができます。カフカのクラスタよりも総再試行時間はのクラッシュから回復するように再設定し、再試行の回数とリトライ間隔、最初のテストの前のアドバイスは、(例えば、すべてのパーティションがどのくらいのリーダーを選出)どのくらいの時間ノードのクラッシュを復元します長い時間が、そうでないプロデューサーが早まってあきらめますし、再試行してください。しかし、いくつかのエラーは、一時的なエラーではありません再試行することにより、(例えば、「金利あまりにも静かな」エラーとして)対処するために怖がってはいけません。一般的には、プロデューサーが自動的に再試行されますので、コードのロジックに再試行できるエラーを処理する必要はありませんので。あなただけの状況や上限を超える再試行を再試行することができないエラーの数を処理する必要があります。

5. batch.size

複数のメッセージが同じパーティションに送信する必要がある場合には、生産者はバッチに入れます。このパラメータは、バイトの数(むしろメッセージ数より)が算出される使用可能なメモリのバッチサイズを指定します。バッチが満たされた場合には、バッチ内のすべてのメッセージが送信されます。しかし、ウェルはバッチ、半バッチキャプチャを送信する前に満たされるまで、生産者は必ずしも待機しません、とさえバッチは、1つのメッセージのみをも送信される可能性が高いが含まれています。バッチサイズが非常に大きく設定されている場合でもだから、それは遅延が発生することはありませんが、唯一のより多くのメモリを占有します。生産者はより頻繁にメッセージを送信する必要があるためしかし、小さすぎる設定されている場合、それはいくつかの追加のオーバーヘッドを追加します。

6. linger.ms

このパラメータには、追加のメッセージのバッチのバッチ添加時間を送信する前に待機するプロデューサーを指定します。KafkaProducer塗りつぶしまたは上限はバッチで送り出されたバッチに達しているlinger.ms。デフォルトでは、限り使用可能なスレッドがあるので、プロデューサーは、メッセージの唯一のバッチがある場合でも、メッセージを送信します。linger.msは、より多くの情報がバッチに添加されるように、生産者は、バッチを送信する前にしばらく待つように、番号0よりも大きくなるように設定します。これは遅延を増加させるだけでなく、スループットを向上させるであろう(これは一回限りの複数のメッセージを送信し、各メッセージのオーバーヘッドが小さくなる)が。

7. client.id

パラメータは、サーバがメッセージのソースを識別するために使用する、任意の文字列であってもよく、また、クォータ内のログに使用することができます。

8. max.in.flight.requests.per.connection

このパラメータは、サーバべき正午を受信する前に送信することができますどのように多くのメッセージプロデューサーを指定します。その値が高いほど、より多くのメモリを取るだろうが、また、スループットを向上させます。1メッセージは、リトライが発生しても、サーバーに書き込まれた順に送信されることを保証するためにそれを設定することができます。

9. timeout.ms、request.timeout.msとmetadata.fetch.timeout.ms

request.timeout.ms応答を返すようにデータを送信する際に指定した時間の生産者は生産者がメタデータを取得するためにサーバーを待つときmetadata.fetch.timeout.msは(そのようチーフターゲット・パーティションが誰であるかのように)戻り応答を指定し、サーバーを待ちます時間。タイムアウトが応答を待っている場合、プロデューサはデータの送信を再試行のいずれか、または(例外がスローまたはコールバックされる)エラーを返します。timeout.msは時間を確認戻りメッセージの同期コピーを待つためにブローカーを指定し、コンフィギュレーションが承認の11同期コピーが指定した時間内に受信されないと一致するかどうかを尋ねる、ブローカはエラーを返します。

10. max.block.ms

このパラメータは、プロデューサーを送信するための呼び出しでメタデータを取得するために、ブロッキング時間()メソッドまたはparttitionFor()を使用して指定します。場合は、送信バッファは、これらが屈筋側をブロックします、生産者、または利用できていないメタデータをキャッチされています。ブロッキング時間はmax.block.msに到達するときに、生産者はタイムアウト例外がスローされます。

11。max.request.size

このパラメータは、プロデューサが送信要求のサイズを制御します。それはまた、単一の要求内のすべてのメッセージの合計サイズを参照することができ、送信することができる単一のメッセージの最大を指すことができます。例えば、1メガバイトの値は、最大の単一メッセージは、次に1メガバイトに送信することができる、または生産バッチ内の単一の要求を送信することができると仮定すると1000件のメッセージを含むバッチは、各メッセージのサイズが1キロバイトです。さらに、メッセージの最大値は、ブローカーはまた、好ましくは、マッチの両側ように配置された独自の制限(message.max.bytes)を有し、プロデューサによって送信されたメッセージが拒否ブローカされないように受信されても​​よいです。

send.buffer.bytes和12. receive.buffer.bytes

これらのパラメータは、受信したデータパケットを送信するためのTCPソケットバッファサイズを指定します。彼らは-1、オペレーティングシステムのデフォルト値に設定されている場合。生産者又は消費者と異なるデータセンター内のブローカ場合、データセンター間のネットワークは、一般に比較的高遅延及び低帯域幅を有するので、これらの値を増加させるのに適切であり得ます。

ことを確実にするため
カフカがニュースを注文されているのと同じパーティションを保証することができます。プロデューサーは、特定の順序でメッセージを送信する場合、すなわち、ブローカはそのためのパーティションにそれらを書き込みます、消費者は同じ順番でそれらを読み込みます。いくつかのケースでは、順序が非常に重要です。リトライゼロ以外の整数ならば番号max.in.flight.requests.per.connectionが1より大きく設定しながら、その後、最初のメッセージは、バッチの失敗に書き込まれ、書き込みの第二のバッチされた場合成功は、ブローカーは最初のバッチを書くしようとします。この時点で最初のバッチはまた、成功した記述した場合、注文は2つのバッチを逆転しています。

シーンがいくつかのメッセージが順序付けられている必要とする場合、一般的には、そのメッセージを成功に書かれている非常に重要です、非常に重要である注文することは推奨されません。再試行が0に設定されている場合。Max.in.flight.requests.per.connection生産が最初のメッセージを送信しようとするように、ブローカに送信された他のメッセージが存在することになる、1に設定することができます。メッセージのみの事情のための厳格な要件の下でこれを行うので、しかし、これは真剣に、生産者のスループットに影響を与えます。

 

おすすめ

転載: www.cnblogs.com/weknow619/p/10941697.html