カフカの紹介

序文

入門記事として、主に Kafka の概念、およびいくつかの基本的な操作と使用法を理解することを目的としています。

導入

公式は Kafka について比較的完全な紹介をしました: Kafka の中国語ドキュメント - ApacheCN

Kafka は分散型アウトフロー プラットフォームです。

ストリーム処理プラットフォームとして、次の 3 つの特徴があります。

  1. ストリーミング レコードを公開および購読できるようにします。この側面は、メッセージ キューやエンタープライズ メッセージング システムと似ています。
  2. ストリーミング レコードは保存できるため、耐障害性が向上します。
  3. ストリーミング レコードは、生成時に処理できます。

これは、次の 2 つの広いカテゴリのアプリケーションで使用できます。

  1. システムまたはアプリケーション間でデータを確実にフェッチするリアルタイム ストリーミング データ パイプラインを構築します。(メッセージキューに相当)
  2. これらのストリーミング データを変換したり影響を与えたりするリアルタイム ストリーミング アプリケーションを構築します。(つまり、kafka ストリーム トピックとトピックの間の内部変更によるストリーム処理)

コンセプトと説明

Kafka はクラスターとして 1 つ以上のサーバー上で実行できます。

Kafka はtopic保存されたデータを次のように分類します。

各レコードにはkey、 、 a value、および が含まれます。timestamp

Kafka の構造は次のとおりです。

構造

Kafka のプロデューサーとコンシューマーは、TCP プロトコルを通じて接続されます。

プロデューサー: プロデューサーは、アプリケーション、または送信される他のプログラムでもあり、メッセージtopicを に送信する責任がありますpartition

Consumer : Consumer、コンシューマ グループで表されます。コンシューマ グループはコンシューマとみなすことができます。コンシューマはトピックにサブスクライブします。その後、Kafka がコンシューマ グループにメッセージを送信します。このとき、コンシューマ グループはメッセージの負荷分散を行います。グループ内のすべてのコンシューマ インスタンスに均等に分散されます。

topic : トピック (データ トピック)、データ レコードが保存される場所、およびそれを通じてビジネス データを区別できます。トピックには 1 つ以上のコンシューマー サブスクリプションを含めることができます。

パーティション: パーティション。各トピックには 1 つ以上のパーティションがあり、パーティションは、指定されたパーティションとパーティション ルールに従って、トピックが受信したデータを異なるパーティションに分割します。コンシューマがトピック消費メッセージをサブスクライブするとき、パーティションを指定するかどうかを指定できます。指定しない場合、Kafka はポーリングを使用してすべてのパーティションのデータをコンシューマに送信します。もちろん、指定されたパーティションは、指定されたパーティションのメッセージのみを送信します。同じパーティション上のメッセージが順序付けされているという点も明らかです。

(公式 Web サイトの説明: トピックごとに、kafka クラスターはパーティション ログを維持します。各パーティションのデータは順番に並べられ、コミット ログ ファイルに継続的に追加されます。パーティション内の各レコードには ID 番号が割り当てられます。これは、オフセット (オフセット) とも呼ばれる順序を示します。つまり、消費者は、指定された場所から取得できるこのオフセットを通じてログを取得できます。

パーティションのストレージ容量はホストのファイル制限によって制限されますが、トピックには複数のパーティションを含めることができます。クラスターでは、トピックがクラスター ノード上にある場合、そのパーティションは他のノードのトピックにも同期されます。耐障害性を維持する)

replication : コピー、各パーティションにはリーダー、0 個以上のフォロワーがあり、リーダーは排他書き込みのみ、フォロワーはバックアップのみを行い、リーダーがダウンすると、残ったフォロワーの中からリーダーが選出されます。

注: トピックを作成するとき、レプリカの数はブローカーの数、つまり Kafka ノードの数より大きくすることはできません。これは、レプリカが他のノードと同期されるためであり、ノード データよりも大きい場合は、レプリカの数を増やすことはできません。作成されます。

ブローカー:kafkaサービス

クラスター: クラスターの下には、常に 1 つのノードがノードとして存在しleader、0 個以上のノードがありfollwersleaderそのノードだけがすべての読み取りおよび書き込みリクエストを処理し、他のノードはleaderデータ同期を達成するために受動的です。これらのleaderノードがダウンしている場合、そのうちの 1 つがダウンします。follwers新たに選出されますleader

メッセージ システム: 他のメッセージ システム モード (および 2 つのモジュール) と比較して队列发布-订阅kafka のキュー モードでは、コンシューマは Redis のようなコンシューマ グループです。キュー モードではコンシューマは 1 つしか持つことができず、消費はなくなります。モード、他のミドルウェアもマルチサブスクライブ モード、kafka サブスクリプションはトピック用であり、すべてのコンシューマ グループ内のコンシューマ インスタンスの数はパーティションの数を超えることはできません。

ストリーム処理: Kafka にはストリーム処理の機能があり、トピックからデータを継続的に取得してデータ処理を行い、データの集約、結合などの複雑な処理を行ってトピックに書き込むことができます

インストール

正式なアドレス: Kafka 中国語ドキュメント-ApacheCN

公式ダウンロード アドレス、ダウンロードは非常に高速です。

起動

方法 1

Kafka はクラスター管理に Zookeeper を使用するため、Zookeeper サーバーが必要です。Kafka は直接使用できる Zookeeper を提供します。

./bin/zookeeper-server-start.sh -daemon config/zoeeper.properties

Zookeeper とは少し異なり、kafka スクリプトは起動スクリプト、Zookeeper はコマンド ラインです。

カフカを開始します

./bin/kafka-server-start.sh -daemon config/server.properties

方法 2

Kafka に付属の Zookeeper を使用する代わりに、前に構築した Zookeeper クラスターを使用します。

vi config/server.properties

/動物園の飼育員

#Zookeeper クラスターのアドレスに設定を変更します

Zookeeper.connect=ローカルホスト:2181,ローカルホスト:2182,ローカルホスト:2183

起動

./bin/zkServer.sh 起動zoo.cfg

./bin/zkServer.sh 起動zoo2.cfg

./bin/zkServer.sh 起動zoo3.cfg

./bin/kafka-server-start.sh config/server.properties

構成

設定項目の説明: Kafka 中国語ドキュメント - ApacheCN

コマンド操作

Kafka には多くのコマンドが用意されており、これらのコマンドを使用してトピックを作成し、メッセージを送信し、メッセージを消費します。

画像-20230103221311638

トピックを作成する

./bin/kafka-topics.sh --zookeeper localhost:2181 --create --topic test_topic --partitions 3 --replication-factor 3

–zookeeper: ズーキーパーのアドレスを指定します。

–partitions: トピックフラグメントの数

–replication-factor: レプリケーション係数、書き込まれるデータコピーの数を制御します。この値はブローカーの数以下です。ここではスタンドアロンなので、ここでは 1 です。

トピックリストを見る

./bin/kafka-topics.sh --list --zookeeper localhost:2181

メッセージを送信する (プロデューサーを開始する)

#長い接続

./bin/kafka-console-Producer.sh --broker-list 192.168.17.128:9092 --topic test_topic

クライアントは成功を示すメッセージを受け取ります

メッセージを消費する (コンシューマを開始する)

#長い接続

./bin/kafka-console-consumer.sh --bootstrap-server 192.168.17.128:9092 --topic test_topic

プロデューサークライアントで小さなメッセージを送信します。ここで受信できれば、すでに成功しています。

トピック情報のクエリ

./bin/kafka-topics.sh --describe --zookeeper localhost:2181 --topic test_topic

画像-20230211143956872

この概念については上で説明しましたが、ここでも触れておきます。

**topic:** トピック名。3 つのパーティションと 3 つのディストリビューションが指定されているため、ここには 3 つのデータがあります。

**パーティション: **パーティション。現在のパーティションがどのノード上にあるかを示します。各トピックには 1 つ以上のパーティションがあり、各パーティションに格納されるデータは異なります (トピック上のデータは均等に分散されます)。

**リーダーとレプリカ: **レプリカ情報。災害復旧機能を確保するために、各パーティション データは指定された数のコピーをバックアップします。各パーティションにはリーダーがあり、0 個以上のフォロワーがあり、リーダーは単独の書き込みのみを行い、フォロワーのみが実行されます。バックアップを実行すると、パーティションのリーダーがダウンすると、上の図に示すように、残りのフォロワーがリーダーを選出しますReplicas: 1,2,3

画像-20230211152324585

リーダー 1 がオフラインになると、残りの 2 と 3 がそのうちの 1 人をリーダーとして選出します。

ここにLeaderパーティション コピーのマスター ノードがあり、すべての読み取りと書き込みを担当し、Replicasディストリビューションが配置されている場所の情報になります。

次に、kafka ノードを強制終了します。

画像-20230211144054008

1人を削除し、新しいリーダーを選出することに成功した

画像-20230211144146960

知らせ:

  1. 前述したように、レプリカの数はKafkaのノード数を超えることはできず、ここではノード数は足りていますが、運用過程の不可抗力により、異常が発生したノードをクラスタが積極的に削除してしまいました。
  2. このコマンドはトピック情報を表示でき、Kafka でクラスターの状態を確認するコマンドとしても使用されます。Kafka には同様のコマンドがないため、zkServer.sh statusこのコマンドを使用してパーティションがオフラインかどうかを確認できます。

トピックを削除する

これは次のようserver.propertiesに設定する必要があります。delete.topic.enable=trueそうしないと、このトピックは削除済みとしてマークされるだけで、削除されません。

./bin/kafka-topics.sh --delete --zookeeper localhost:2181 --topic test_topic

画像-20230206222944176

集まる

kafka の公式 Web サイトに構成例が掲載されているので、それに従って構成を追加していきます クラスターの構成は 3 か所のみです 1 台のサーバーにデプロイしているため、他のサービスを区別する必要があります

  • ログ.ディレクトリ
  • ブローカー.id
  • リスナー (ここでのアドレス構成 IP に注意してください)

Zookeeper の簡単な構成例

# ZooKeeper服务地址
zookeeper.connect=localhost:2181,localhost:2182,localhost:2183
# topic分区日志数
num.partitions=8
# 自动创建topic的默认副本数
default.replication.factor=3
# 自动创建topic
auto.create.topics.enable=false
# 指定写入成功的副本数,当写入数据的副本数达不到这个值,则会报错
min.insync.replicas=2
delete.topic.enable=true

# 集群配置
# 日志保存目录
log.dir=./log1
# broker服务ID
broker.id=1
# 监听地址
listeners=PLAINTEXT://192.168.17.128:9092

クラスターのステータスが成功したかどうかを確認します。

./bin/kafka-topics.sh --describe --zookeeper localhost:2181 --topic test_topic

シャットダウン

シャットダウンと失敗は異なります。通常のシャットダウンでは、Kafka が実行されます。

  1. すべてのログをディスクに同期します。これにより、再起動時の回復ログ プロセスが回避され、起動速度が向上します。
  2. リーダーがシャットダウンされると、リーダー上のパーティションが他のレプリカに移行され、リーダーの切り替えが高速化されます。

使用

  1. まずサーバーのファイアウォールのポートが開いていることを確認してください

    firewall-cmd --add-port=9200/tcp --permanent
    
  2. Kafka にはログバックの依存関係が必要です

     <dependency>
                <groupId>org.apache.kafka</groupId>
                <artifactId>kafka-clients</artifactId>
                <version>2.8.0</version>
            </dependency>
            <dependency>
                <groupId>com.fasterxml.jackson.core</groupId>
                <artifactId>jackson-databind</artifactId>
                <version>2.13.1</version>
            </dependency>
            <dependency>
                <groupId>org.slf4j</groupId>
                <artifactId>slf4j-api</artifactId>
                <version>1.7.33</version>
            </dependency>
            <dependency>
                <groupId>ch.qos.logback</groupId>
                <artifactId>logback-core</artifactId>
                <version>1.2.10</version>
            </dependency>
            <dependency>
                <groupId>ch.qos.logback</groupId>
                <artifactId>logback-classic</artifactId>
                <version>1.2.10</version>
            </dependency>
            <dependency>
                <groupId>ch.qos.logback</groupId>
                <artifactId>logback-access</artifactId>
                <version>1.2.3</version>
            </dependency>
    

    ログバック.xml

    <!-- 级别从高到低 OFF 、 FATAL 、 ERROR 、 WARN 、 INFO 、 DEBUG 、 TRACE 、 ALL -->
    <!-- 日志输出规则 根据当前ROOT 级别,日志输出时,级别高于root默认的级别时 会输出 -->
    <!-- 以下 每个配置的 filter 是过滤掉输出文件里面,会出现高级别文件,依然出现低级别的日志信息,通过filter 过滤只记录本级别的日志 -->
    <!-- scan 当此属性设置为true时,配置文件如果发生改变,将会被重新加载,默认值为true。 -->
    <!-- scanPeriod 设置监测配置文件是否有修改的时间间隔,如果没有给出时间单位,默认单位是毫秒。当scan为true时,此属性生效。默认的时间间隔为1分钟。 -->
    <!-- debug 当此属性设置为true时,将打印出logback内部日志信息,实时查看logback运行状态。默认值为false。 -->
    <configuration scan="true" scanPeriod="60 seconds" debug="false">
        <!-- 动态日志级别 -->
        <jmxConfigurator />
        <!-- 定义日志文件 输出位置 -->
        <!-- <property name="log_dir" value="C:/test" />-->
        <property name="log_dir" value="./logs" />
        <!-- 日志最大的历史 30天 -->
        <property name="maxHistory" value="30" />
    
        <!-- ConsoleAppender 控制台输出日志 -->
        <appender name="console" class="ch.qos.logback.core.ConsoleAppender">
            <encoder>
                <pattern>
                    <!-- 设置日志输出格式 -->
                    %d{yyyy-MM-dd HH:mm:ss.SSS} %-5level %logger - %msg%n
                </pattern>
            </encoder>
        </appender>
    
        <!-- ERROR级别日志 -->
        <!-- 滚动记录文件,先将日志记录到指定文件,当符合某个条件时,将日志记录到其他文件 RollingFileAppender -->
        <appender name="ERROR" class="ch.qos.logback.core.rolling.RollingFileAppender">
            <!-- 过滤器,只记录WARN级别的日志 -->
            <!-- 果日志级别等于配置级别,过滤器会根据onMath 和 onMismatch接收或拒绝日志。 -->
            <filter class="ch.qos.logback.classic.filter.LevelFilter">
                <!-- 设置过滤级别 -->
                <level>ERROR</level>
                <!-- 用于配置符合过滤条件的操作 -->
                <onMatch>ACCEPT</onMatch>
                <!-- 用于配置不符合过滤条件的操作 -->
                <onMismatch>DENY</onMismatch>
            </filter>
            <!-- 最常用的滚动策略,它根据时间来制定滚动策略.既负责滚动也负责出发滚动 -->
            <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
                <!--日志输出位置 可相对、和绝对路径 -->
                <fileNamePattern>
                    ${log_dir}/error/%d{yyyy-MM-dd}/error-log.log
                </fileNamePattern>
                <!-- 可选节点,控制保留的归档文件的最大数量,超出数量就删除旧文件假设设置每个月滚动,且<maxHistory>是6, 则只保存最近6个月的文件,删除之前的旧文件。注意,删除旧文件是,那些为了归档而创建的目录也会被删除 -->
                <maxHistory>${maxHistory}</maxHistory>
            </rollingPolicy>
            <encoder>
                <pattern>
                    <!-- 设置日志输出格式 -->
                    %d{yyyy-MM-dd HH:mm:ss.SSS} %-5level %logger - %msg%n
                </pattern>
            </encoder>
        </appender>
    
        <!-- WARN级别日志 appender -->
        <appender name="WARN" class="ch.qos.logback.core.rolling.RollingFileAppender">
            <!-- 过滤器,只记录WARN级别的日志 -->
            <!-- 果日志级别等于配置级别,过滤器会根据onMath 和 onMismatch接收或拒绝日志。 -->
            <filter class="ch.qos.logback.classic.filter.LevelFilter">
                <!-- 设置过滤级别 -->
                <level>WARN</level>
                <!-- 用于配置符合过滤条件的操作 -->
                <onMatch>ACCEPT</onMatch>
                <!-- 用于配置不符合过滤条件的操作 -->
                <onMismatch>DENY</onMismatch>
            </filter>
            <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
                <!--日志输出位置 可相对、和绝对路径 -->
                <fileNamePattern>${log_dir}/warn/%d{yyyy-MM-dd}/warn-log.log</fileNamePattern>
                <maxHistory>${maxHistory}</maxHistory>
            </rollingPolicy>
            <encoder>
                <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} %-5level %logger - %msg%n</pattern>
            </encoder>
        </appender>
    
        <!-- INFO级别日志 appender -->
        <appender name="INFO" class="ch.qos.logback.core.rolling.RollingFileAppender">
            <filter class="ch.qos.logback.classic.filter.LevelFilter">
                <level>INFO</level>
                <onMatch>ACCEPT</onMatch>
                <onMismatch>DENY</onMismatch>
            </filter>
            <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
                <fileNamePattern>${log_dir}/info/%d{yyyy-MM-dd}/info-log.log</fileNamePattern>
                <maxHistory>${maxHistory}</maxHistory>
            </rollingPolicy>
            <encoder>
                <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} %-5level %logger - %msg%n</pattern>
            </encoder>
        </appender>
    
        <!-- DEBUG级别日志 appender -->
        <appender name="DEBUG" class="ch.qos.logback.core.rolling.RollingFileAppender">
            <filter class="ch.qos.logback.classic.filter.LevelFilter">
                <level>DEBUG</level>
                <onMatch>ACCEPT</onMatch>
                <onMismatch>DENY</onMismatch>
            </filter>
            <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
                <fileNamePattern>${log_dir}/debug/%d{yyyy-MM-dd}/debug-log.log</fileNamePattern>
                <maxHistory>${maxHistory}</maxHistory>
            </rollingPolicy>
            <encoder>
                <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} %-5level %logger - %msg%n</pattern>
            </encoder>
        </appender>
    
        <!-- TRACE级别日志 appender -->
        <appender name="TRACE" class="ch.qos.logback.core.rolling.RollingFileAppender">
            <filter class="ch.qos.logback.classic.filter.LevelFilter">
                <level>TRACE</level>
                <onMatch>ACCEPT</onMatch>
                <onMismatch>DENY</onMismatch>
            </filter>
            <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
                <fileNamePattern>${log_dir}/trace/%d{yyyy-MM-dd}/trace-log.log</fileNamePattern>
                <maxHistory>${maxHistory}</maxHistory>
            </rollingPolicy>
            <encoder>
                <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} %-5level %logger - %msg%n</pattern>
            </encoder>
        </appender>
    
        <!-- root级别 DEBUG -->
        <root>
            <!-- 打印debug级别日志及以上级别日志 -->
            <level value="info" />
            <!-- 控制台输出 -->
            <appender-ref ref="console" />
            <!-- 文件输出 -->
            <appender-ref ref="ERROR" />
            <appender-ref ref="INFO" />
            <appender-ref ref="WARN" />
            <appender-ref ref="DEBUG" />
            <appender-ref ref="TRACE" />
        </root>
    </configuration>
    
    

エラーを報告する

  1. 接続エラー
org.apache.kafka.common.network.Selector - [Consumer clientId=con, groupId=con-group] Connection with /192.168.17.128 disconnected
java.net.ConnectException: Connection refused: no further information

org.apache.kafka.clients.NetworkClient - [Consumer clientId=con, groupId=con-group] Connection to node -1 (/192.168.17.128:9092) could not be established. Broker may not be available.

最も可能性の高い理由は、listeners設定で IP が設定されていないことです。最初に変更してみてください。IP の設定がないため、ここにいます。最後に、変更され、その後、コンシューマのエラーはなくなりましたlisteners=PLAINTEXT://192.168.17.128:9092

  1. 次はプロデューサーのエラーです。
Error while fetching metadata with correlation id 53 : {
    
    test_topic=UNKNOWN_TOPIC_OR_PARTITION}

未知の話題のようですが、公式サイトはデフォルトでTRUEになっていると思います。

画像-20230110221509106

最終的な構成では、別の文が追加されauto.create.topics.enable=true、完全な構成は次のようになります。

# ZooKeeper服务地址
zookeeper.connect=localhost:2181,localhost:2182,localhost:2183
# topic分区日志数
num.partitions=2
# 自动创建topic的默认副本数
default.replication.factor=3
# 自动创建topic
auto.create.topics.enable=false
# 指定写入成功的副本数,当写入数据的副本数达不到这个值,则会报错
min.insync.replicas=2
# 设置自动创建topic
auto.create.topics.enable=true
delete.topic.enable=true

#集群配置
# 日志保存目录
log.dir=./log1
# broker服务ID
broker.id=1
# 监听地址
listeners=PLAINTEXT://192.168.17.128:9092

その後は普通です

ワンクリック起動スクリプトを取得します。

/data/kafka/kafka_2.11-1.0.0/bin/kafka-server-start.sh -daemon /data/kafka/kafka_2.11-1.0.0/config/server.properties

/data/kafka/kafka_2.11-1.0.0/bin/kafka-server-start.sh -daemon /data/kafka/kafka_2.11-1.0.0/config/server2.properties

/data/kafka/kafka_2.11-1.0.0/bin/kafka-server-start.sh -daemon /data/kafka/kafka_2.11-1.0.0/config/server3.properties

sleep 3

echo 'kafka启动完成'

Java接続例

消費者コード:

シェルコマンドのパラメータに対応する、いくつかの必要な設定を次に示します。

bootstrap.servers - Kafka サーバーのアドレス

client.id - クライアントID

key.deserializer - キーデシリアライザーの構成

value.deserializer - 値の逆シリアル化構成

group.id - コンシューマ グループ ID

auto.offset.reset - offset方式

    public static void consumer() {
    
    
        Properties properties = new Properties();
        // 必填参数
        // kafka服务地址
        properties.put(ConsumerConfig.BOOTSTRAP_SERVERS_CONFIG, IP);
        // 客户端消费者ID
        properties.put(ConsumerConfig.CLIENT_ID_CONFIG, "con");
        // key序列化器
        properties.put(ConsumerConfig.KEY_DESERIALIZER_CLASS_CONFIG, StringDeserializer.class.getName());
        // value序列化器
        properties.put(ConsumerConfig.VALUE_DESERIALIZER_CLASS_CONFIG, StringDeserializer.class.getName());
        // 消费者组ID,如果需要重新读取,可以切换groupId为新的ID就可以了,然后设置自动提交为true
        properties.put(ConsumerConfig.GROUP_ID_CONFIG, "con-group");
            // 消费偏移量
        // earliest:分区中有offset时,从offset位置消费,没有从头消费
        // latest:分区中有offset时,从offset位置下佛,没有时,消费新产生的
        // none:分区有offset时,从offset后开始消费,如果有一个分区缺少已提交的offset时,抛异常
        properties.put(ConsumerConfig.AUTO_OFFSET_RESET_CONFIG, "earliest");

        // 回话超时时间
        properties.put(ConsumerConfig.SESSION_TIMEOUT_MS_CONFIG, 6000);
        // 心跳间隔
        properties.put(ConsumerConfig.HEARTBEAT_INTERVAL_MS_CONFIG, "2000");
        // 自动提交间隔
        properties.put(ConsumerConfig.AUTO_COMMIT_INTERVAL_MS_CONFIG, "1000");
        // 每次拉取的最大数据量
        properties.put(ConsumerConfig.MAX_POLL_RECORDS_CONFIG, 2);
        // 如果需要重复消费,可以设置自动提交为FALSE,这样每次拉取都是从之前的offset开始拉取
        properties.put(ConsumerConfig.ENABLE_AUTO_COMMIT_CONFIG, false);
    

        new Thread(() -> {
    
    
            while (true) {
    
    
                try(KafkaConsumer<String, Object> con = new KafkaConsumer<>(properties);){
    
    
                    con.subscribe(Collections.singleton(TOPIC));
                    ConsumerRecords<String, Object> poll = con.poll(Duration.ofSeconds(5000));
                    for (ConsumerRecord<String, Object> record : poll) {
    
    
                        System.out.println("topic:" + record.topic() + ",offset:" + record.offset() + ",数据:" + record.value().toString());
                    }
                }
            }
        }).start();
    }

プロデューサーコード:

も必須パラメータです

ブートストラップ.サーバー

クライアントID

key.deserializer - キーのシリアル番号の設定

value.deserializer - 値のシリアル番号の設定

public static void producer() {
    
    
        Properties properties = new Properties();
        // 必要条件
        properties.put(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG, IP);
        properties.put(ProducerConfig.CLIENT_ID_CONFIG, "pro");
        properties.put(ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG, StringSerializer.class.getName());
        properties.put(ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG, StringSerializer.class.getName());
        KafkaProducer<String, String> pro = new KafkaProducer<>(properties);

        new Thread(() ->{
    
    
            while (true) {
    
    
                try {
    
    
                    TimeUnit.SECONDS.sleep(3);
                } catch (InterruptedException e) {
    
    
                    throw new RuntimeException(e);
                }
                Future<RecordMetadata> result = pro.send(new ProducerRecord<>(TOPIC, "1","dddd"), (meta, error) -> {
    
    
                    if (error != null) {
    
    
                        error.printStackTrace();
                        return;
                    }
                    System.out.println("发送回调:" + meta.toString());
                });
                System.out.println("发送的结果:" + result );
            }
        }).start();

    }

述べる:

  1. Kafka はビッグ データをコンシューマ グループに自動的にグループ化します。同時に、max.poll.records(ConsumerConfig.MAX_POLL_RECORDS_CONFIG)毎回取得されるデータの量を制御するようにクライアントに設定することもできます。

    コンシューマ グループを通じてプルされるため、複数のクライアントが同じ groupId を設定して同じトピックにサブスクライブできます。

  2. データを順序立てて消費する必要がある場合は、プロデューサのメッセージがパーティションに送信されるようにすることも必要です。また、Kafka のパーティション メカニズムを順番に消費するために使用できます。

  3. すべてのデータを取得する必要がある場合は、groupId とバッチ内のデータ量を設定し、自動的に true、k に送信できます。

        // 消费者组ID,如果需要重新读取,可以切换groupId为新的ID就可以了,然后设置自动提交为true
        properties.put(ConsumerConfig.GROUP_ID_CONFIG, "con-group");
        // 每次拉取的最大数据量
        properties.put(ConsumerConfig.MAX_POLL_RECORDS_CONFIG, 2000);
        // 如果需要重复消费,可以设置自动提交为FALSE,这样每次拉取都是从之前的offset开始拉取
        properties.put(ConsumerConfig.ENABLE_AUTO_COMMIT_CONFIG, true);
        // 消费偏移量

おすすめ

転載: blog.csdn.net/qq_28911061/article/details/128985197