【官方文档】Fluentd 输入输出插件(kafka)

文章目录

    • 1. 安装
    • 2. 要求
    • 3. 使用
      • 3.1. 公共参数
        • 3.1.1. SSL 认证
        • 3.1.2. SASL 认证
      • 3.2. 输入插件(@type 'kafka')
      • 3.3. 输入插件(@type 'kafka_group',支持 kafka group)
      • 3.4. 输入插件(@type 'rdkafka_group',支持 kafka consumer groups,使用 rdkafka-ruby)
      • 3.5. 输出插件
        • 3.5.1. 负载均衡
        • 3.5.2. 头信息
      • 3.6. 缓冲输出插件
      • 3.7. 无缓冲输出插件
      • 3.8. 基于 rdkafka 的输出插件
    • 4. 常见问题

插件 GitHub 地址: fluent-plugin-kafka

参考博文地址:Fluentd-kafka插件用法详解


一个既可以消费 Kafka 也可以向 Kafka 中生产数据的 Fluentd 插件。

1. 安装

将这一行添加到你的应用程序的 Gemfile 中:

gem 'fluent-plugin-kafka'

然后执行:

$ bundle

或者自己安装:

$ gem install fluent-plugin-kafka --no-document

如果需要使用 zookeeper 相关参数,还需要安装 zookeeper gem。zookeeper gem 包含本地扩展,所以需要开发工具,例如 ruby-devel,gcc,make 等。

2. 要求

  • Ruby 2.1 或者更高的版本。
  • 输入插件适用于 kafka v0.9 或更高版本。
  • 输出插件适用于 kafka v0.8 或更高版本。

3. 使用

3.1. 公共参数

3.1.1. SSL 认证

  • ssl_ca_cert
  • ssl_client_cert
  • ssl_client_cert_key
  • ssl_ca_certs_from_system

设置路径为 SSL 相关文件。有关详细信息,请参阅使用 SSL 的加密和身份验证。

3.1.2. SASL 认证

with GSSAPI

  • principal
  • keytab

Set principal and path to keytab for SASL/GSSAPI authentication. See Authentication using SASL for more details.

with Plain/SCRAM

  • username
  • password
  • scram_mechanism
  • sasl_over_ssl

Set username, password, scram_mechanism and sasl_over_ssl for SASL/Plain or Scram authentication. See Authentication using SASL for more details.

3.2. 输入插件(@type ‘kafka’)

插件以“单消费者”模式订阅 kafka 消息。单消费者模式是指:每个 kafka 输入插件独立地订阅 kafka 消息。

这种模式可以满足极简单的应用场景。其缺点为:

  • 如果有多个单消费者进程同时订阅相同的 topic,进程之间无法协调如何分配不同的分区。
  • 如果多个单消费者进程中某个进程挂掉,其他进程无法从该进程原先订阅位置进行恢复。

单消费者模式下,kafka 输入插件配置说明如下:

<source>
  # 插件类型 kafka
  @type kafka
  
  # 逗号分隔的 broker 列表,每个 broker 需要指定 ip 和端口
  brokers <broker1_host>:<broker1_port>,<broker2_host>:<broker2_port>,..
  # 逗号分隔的 topic 列表
  topics <listening topics(separate with comma',')>
  # 输入消息的格式,有 text、json、ltsv、msgpack 等几种,默认 json
  format <input text type (text|json|ltsv|msgpack)> :default => json
  # 可选,消息格式为 text 时,指定消息的 key,默认是 message
  message_key <key (Optional, for text format only, default is message)>
  # tag 增加前缀
  add_prefix <tag prefix (Optional)>
  # tag 增加后缀
  add_suffix <tag suffix (Optional)>

  # 还可以使用 zookeeper 管理 topic 偏移量
  offset_zookeeper    <zookeer node list (>:<zookeeper1_port>,<zookeeper2_host>:<zookeeper2_port>,..)>
  offset_zk_root_node <offset path in zookeeper> default => '/fluent-plugin-kafka'

  # ruby-kafka 消费者选项
  max_bytes     (integer) :default => nil (Use default of ruby-kafka)
  max_wait_time (integer) :default => nil (Use default of ruby-kafka)
  min_bytes     (integer) :default => nil (Use default of ruby-kafka)
source>

支持从指定的偏移量开始处理特定 topic。

<source>
  @type kafka

  brokers <broker1_host>:<broker1_port>,<broker2_host>:<broker2_port>,..
  format <input text type (text|json|ltsv|msgpack)>
  <topic>
    topic     <listening topic>
    partition <listening partition: default=0>
    offset    <listening start offset: default=-1>
  topic>
  <topic>
    topic     <listening topic>
    partition <listening partition: default=0>
    offset    <listening start offset: default=-1>
  topic>
source>

更多关于 ruby-kafka 的详细文档,请参见 ruby-kafka README。

消费 topic 名称用于事件 tag。因此,当目标 topic 名称为app_event时,tag 为app_event。如果要修改 tag,请使用add_prefixadd_suffix参数。使用add_prefix kafka,tag 就是kafka.app_event

3.3. 输入插件(@type ‘kafka_group’,支持 kafka group)

插件以“消费者组”模式订阅 kafka 消息。消费者组模式解决了单消费者模式存在的几个缺点,可以同时启动多个 Fluentd 进程协同工作。

配置说明如下:

<source>
  # 插件类型 kafka_group
  @type kafka_group
  
  # 逗号分隔的 broker 列表,每个 broker 需要指定 ip 和端口
  brokers <broker1_host>:<broker1_port>,<broker2_host>:<broker2_port>,..
  # 设定消费者组名称,必须设置
  consumer_group <consumer group name, must set>
  # 逗号分隔的 topic 列表
  topics <listening topics(separate with comma',')>
  # 输入消息的格式,有 text、json、ltsv、msgpack 等几种,默认 json
  format <input text type (text|json|ltsv|msgpack)> :default => json
  # 可选,消息格式为 text 时,指定消息的 key,默认是 message
  message_key <key (Optional, for text format only, default is message)>
  # 可选,如果指定,则设置 kafka 的 message key 为该 key
  kafka_mesasge_key <key (Optional, If specified, set kafka's message key to this key)>
  # 如果为 true,添加 kafka 的消息头到记录中
  add_headers <If true, add kafka's message headers to record>
  # tag 增加前缀
  add_prefix <tag prefix (Optional)>
  # tag 增加后缀
  add_suffix <tag suffix (Optional)>
  # 当 BuffereQueueLimitError 发生时等待 retry_emit_limit 秒。默认值是nil,这意味着等待直到 BufferQueueLimitError 被解决
  retry_emit_limit <Wait retry_emit_limit x 1s when BuffereQueueLimitError happens. The default is nil and it means waiting until BufferQueueLimitError is resolved>
  # 弃用。使用'time_source record'代替。如果为 true,则将事件时间替换为所取记录的'time'字段的内容。
  use_record_time (Deprecated. Use 'time_source record' instead.) <If true, replace event time with contents of 'time' field of fetched record>
  # 指定日志事件中时间戳来源,可取 now、kafka 和 record,默认为 now
  time_source <source for message timestamp (now|kafka|record)> :default => now
  # 当时间源为 record 时,设置时间格式以提取其中的时间戳,当 use_record_time 选项被使用时可用
  time_format <string (Optional when use_record_time is used)>

  # ruby-kafka 消费者 options
  max_bytes               (integer) :default => 1048576
  max_wait_time           (integer) :default => nil (Use default of ruby-kafka)
  min_bytes               (integer) :default => nil (Use default of ruby-kafka)
  # 设置 offset 提交时间间隔,默认10秒
  offset_commit_interval  (integer) :default => nil (Use default of ruby-kafka)
  # 插件可批量处理消息后再提交一次 offset,此参数用于设置批量处理的消息数。默认为 0,不采用批量提交机制。
  offset_commit_threshold (integer) :default => nil (Use default of ruby-kafka)
  fetcher_max_queue_size  (integer) :default => nil (Use default of ruby-kafka)
  # true 表示从头开始消费 topic。false 表示只消费新消息。默认为 true。
  start_from_beginning    (bool)    :default => true
source>

更多关于 ruby-kafka 的详细文档,请参见 ruby-kafka README。

topic从 v0.13.1 开始支持正则表达式模式。如果你想使用正则表达式模式,使用/pattern//foo.*/这样。

消费 topic 名称用于事件 tag。因此,当目标 topic 名称为app_event时,tag 为app_event。如果要修改 tag,请使用add_prefixadd_suffix参数。使用add_prefix kafka,tag 就是kafka.app_event

3.4. 输入插件(@type ‘rdkafka_group’,支持 kafka consumer groups,使用 rdkafka-ruby)

in_rdkafka_group 消费者还没有在高的生产负载下进行测试。使用它的风险自负!

随着基于 rdkafka-ruby 的输入插件的引入,我们希望能够支持 2.1 版本以上的 Kafka broker,在这个版本中我们看到了使用基于 ruby-kafka 的 @kafka_group输入类型时的兼容性问题。rdkafka-ruby 库包装了高性能的、可以生产的 librdkafka C 库。

<source>
  @type rdkafka_group
  topics <listening topics(separate with comma',')>
  format <input text type (text|json|ltsv|msgpack)> :default => json
  message_key <key (Optional, for text format only, default is message)>
  kafka_mesasge_key <key (Optional, If specified, set kafka's message key to this key)>
  add_headers <If true, add kafka's message headers to record>
  add_prefix <tag prefix (Optional)>
  add_suffix <tag suffix (Optional)>
  retry_emit_limit <Wait retry_emit_limit x 1s when BuffereQueueLimitError happens. The default is nil and it means waiting until BufferQueueLimitError is resolved>
  use_record_time (Deprecated. Use 'time_source record' instead.) <If true, replace event time with contents of 'time' field of fetched record>
  time_source <source for message timestamp (now|kafka|record)> :default => now
  time_format <string (Optional when use_record_time is used)>

  # kafka 消费者 options
  max_wait_time_ms 500
  max_batch_size 10000
  kafka_configs {
    "bootstrap.servers": "brokers <broker1_host>:<broker1_port>,<broker2_host>:<broker2_port>",
    "group.id": "<consumer group name>"
  }
source>

更多关于 ruby-kafka 的详细文档,请参见 ruby-kafka README。

消费 topic 名称用于事件 tag。因此,当目标 topic 名称为app_event时,tag 为app_event。如果要修改 tag,请使用add_prefixadd_suffix参数。使用add_prefix kafka,tag 就是kafka.app_event

3.5. 输出插件

用于向 kafka 发布消息。

这个kafka2插件适用于 fluentd v1 或更高版本。这个插件使用ruby-kafka生成器来写数据。如果ruby-kafka不适合你的 kafka 环境,请检查rdkafka2插件。未来将使用out_kafka替代kafka2

<match app.**>
  # 插件类型 kafka2
  @type kafka2

  # 逗号分隔的 broker 列表,每个 broker 需要指定 ip 和端口 
  brokers               <broker1_host>:<broker1_port>,<broker2_host>:<broker2_port>,.. # Set brokers directly
  # 设置目的 topic 取自日志记录中的哪个字段
  topic_key             (string) :default => 'topic'
  partition_key         (string) :default => 'partition'
  partition_key_key     (string) :default => 'partition_key'
  message_key_key       (string) :default => 'message_key'
  # 默认 topic,若未设置 topic_key,则 topic 取此处的值
  default_topic         (string) :default => nil
  default_partition_key (string) :default => nil
  default_message_key   (string) :default => nil
  exclude_topic_key     (bool)   :default => false
  exclude_partition_key (bool)   :default => false
  exclude_partition     (bool)   :default => false
  exclude_message_key   (bool)   :default => false
  get_kafka_client_log  (bool)   :default => false
  headers               (hash)   :default => {}
  headers_from_record   (hash)   :default => {}
  use_default_for_unknown_topic (bool) :default => false
  # 默认为 false,丢弃 Kafka::DeliveryFailed 引发的记录
  discard_kafka_delivery_failed (bool) :default => false (No discard)

  # 设置输出消息格式,支持 json、ltsv、msgpack或其他输出插件,默认是 json
  <format>
    @type (json|ltsv|msgpack|attr:<record name>|<formatter name>) :default => json
  format>

  # Optional. See https://docs.fluentd.org/v/1.0/configuration/inject-section
  <inject>
    tag_key tag
    time_key time
  inject>

  # 有关缓冲区的相关参数,请参阅 fluentd 文档: https://docs.fluentd.org/v/1.0/configuration/buffer-section
  # 缓冲区块 key 应该与 topic_key 相同。如果在记录中没有找到 value,则使用default_topic。
  <buffer topic>
    flush_interval 10s
  buffer>

  # ruby-kafka 生产者 options
  idempotent        (bool)    :default => false
  sasl_over_ssl     (bool)    :default => true
  # 默认值 1 ,向 leader 重试发送消息的次数。
  max_send_retries  (integer) :default => 1
  # 设置每个请求的 ack 数,可设置 1、2 这样的小的数字以提高性能,-1 表示不进行确认,默认为 -1
  required_acks     (integer) :default => -1
  # 默认为 nil,生产者等待 ack 的时间。单位为秒。
  ack_timeout       (integer) :default => nil (Use default of ruby-kafka)
  # 设置输出消息的压缩方式,生产者用来压缩消息的编解码器。支持 gzip 和 snappy。默认是 nil,没有压缩
  compression_codec (string)  :default => nil (No compression. Depends on ruby-kafka: https://github.com/zendesk/ruby-kafka#compression)
match>

比如:topic_key 为日志中的 category 字段,如果某条消息中该字段的值为 app,那么该条消息会被发布到 kafka 中名称为 app 的 topic 中。

需要注意的是,在插件的缓存配置中也需要设置该参数的取值。

topic_key category
<buffer category> # topic_key should be included in buffer chunk key
  # ...
buffer>

如果你设置了 topic_key 为 category,那么在 配置中也需要以此作为 chunk 的类型值。


中的使用 fluentd 的 formatter 插件。参见 formatter article。

ruby-kafka 有时会返回 Kafka::DeliveryFailed 错误,没有良好的信息。在这种情况下,get_kafka_client_log 对于识别错误原因很有用。ruby-kafka 的日志被路由到 fluentd 日志,所以你可以在 fluentd 日志中看到 ruby-kafka 的日志。

支持 ruby-kafka 的生产者选项。

  • max_send_retries : 默认值 1 ,向 leader 重试发送消息的次数。
  • required_acks :默认值 1,每个请求所需的 ack 数。如果需要刷新性能,请设置较低的值,例如1、2。
  • ack_timeout :默认为 nil,生产者等待 ack 的时间。单位为秒。
  • compression_codec :默认为 nil,生产者用来压缩消息的编解码器。
  • max_send_limit_bytes :默认为 nil,发送消息的最大字节大小,以避免MessageSizeTooLarge。例如,如果您设置了 1000000(message.max.bytes 在 kafka)。超过 1000000 字节的消息将被丢弃。
  • discard_kafka_delivery_failed :默认为 false,丢弃Kafka::DeliveryFailed引发的记录。
  • monitoring_list :默认为[],用于监控的 library。支持 statsd 和 datadog。如果您想了解监控的详细信息,请参见 https://github.com/zendesk/ruby-kafka#monitoring

参见 Kafka::Client 获取更多关于 ruby-kafka 的详细文档。

这个插件也支持压缩编解码器“snappy”。在使用 snappy 压缩之前安装 snappy 模块。

$ gem install snappy --no-document

snappy gem 使用本地扩展,所以你需要安装几个包之前。在 Ubuntu 上,需要开发包和 snappy 库。

$ sudo apt-get install build-essential autoconf automake libtool libsnappy-dev

在 CentOS 7 上安装也是必要的。

$ sudo yum install gcc autoconf automake libtool snappy-devel

这个插件也支持压缩编解码“lz4”。在使用 lz4 压缩之前,请安装 extlz4 模块。

$ gem install extlz4 --no-document

这个插件也支持压缩编解码器“zstd”。在使用 zstd 压缩之前先安装 zstd-ruby 模块。

$ gem install zstd-ruby --no-document

3.5.1. 负载均衡

默认情况下,发布的消息会被随机分配到 kafka topic 的一个分区。输出插件支持通过设置default_partition_keypartition_key_key的方式将消息分配到特定的分区中。具有相同partition值的消息会被分配到同一个分区。

default_partition_key partition_key_key 消息负载均衡方式
未设置 不存在 所有消息被随机分配到一个分区
已设置 不存在 所有消息都分配到特定的分区
未设置 已存在 含有partition_key_key字段的消息被分配到该字段指定的分区;其他消息随机分配一个分区
已设置 已存在 含有partition_key_key字段的消息被分配到该字段指定的分区;其他消息分配到default_partition_key指定的分区

如果消息中存在 key 名为 message_key_key,则该插件将 message_key_key 的值发布给 kafka,并且可以被消费者读取。通过在配置文件中设置 default_message_key,将为所有消息分配相同的消息键。如果 message_key_key 存在且未显式设置 partition_key_key,则 message_key_key 将用于分区。

3.5.2. 头信息

可以在 Kafka 消息上设置头信息。这只适用于 kafka2 和 rdkafka2 输出插件。

格式为key1:value1,key2:value2。例如:

<match app.**>
  @type kafka2
  [...]
  headers some_header_name:some_header_value
<match>

您可以基于 fluentd 记录字段的值设置头信息。例如,假设一条 fluentd 记录:

{"source": { "ip": "127.0.0.1" }, "payload": "hello world" }

下面的 fluentd 配置:

<match app.**>
  @type kafka2
  [...]
  headers_from_record source_ip:$.source.ip
<match>

Kafka 消息的头信息是source_ip=12.7.0.0.1

配置格式为 jsonpath。详情见 https://docs.fluentd.org/plugin-helper-overview/api-plugin-helper-record_accessor。

3.6. 缓冲输出插件

这个插件使用 ruby-kafka 生成器来写数据。这个插件是为 v0.12。如果使用 v1,请参见 kafka2。对 fluentd v0.12 的支持已经结束。kafka_buffered将会是kafka2的别名,并且会在将来被移除。

<match app.**>
  @type kafka_buffered

  # Brokers: you can choose either brokers or zookeeper. If you are not familiar with zookeeper, use brokers parameters.
  brokers             <broker1_host>:<broker1_port>,<broker2_host>:<broker2_port>,.. # Set brokers directly
  zookeeper           <zookeeper_host>:<zookeeper_port> # Set brokers via Zookeeper
  zookeeper_path      <broker path in zookeeper> :default => /brokers/ids # Set path in zookeeper for kafka

  topic_key             (string) :default => 'topic'
  partition_key         (string) :default => 'partition'
  partition_key_key     (string) :default => 'partition_key'
  message_key_key       (string) :default => 'message_key'
  default_topic         (string) :default => nil
  default_partition_key (string) :default => nil
  default_message_key   (string) :default => nil
  exclude_topic_key     (bool)   :default => false
  exclude_partition_key (bool)   :default => false
  exclude_partition     (bool)   :default => false
  exclude_message_key   (bool)   :default => false
  output_data_type      (json|ltsv|msgpack|attr:<record name>|<formatter name>) :default => json
  output_include_tag    (bool) :default => false
  output_include_time   (bool) :default => false
  exclude_topic_key     (bool) :default => false
  exclude_partition_key (bool) :default => false
  get_kafka_client_log  (bool) :default => false

  # See fluentd document for buffer related parameters: https://docs.fluentd.org/v/0.12/buffer

  # ruby-kafka producer options
  idempotent                   (bool)    :default => false
  sasl_over_ssl                (bool)    :default => true
  max_send_retries             (integer) :default => 1
  required_acks                (integer) :default => -1
  ack_timeout                  (integer) :default => nil (Use default of ruby-kafka)
  compression_codec            (string)  :default => nil (No compression. Depends on ruby-kafka: https://github.com/zendesk/ruby-kafka#compression)
  kafka_agg_max_bytes          (integer) :default => 4096
  kafka_agg_max_messages       (integer) :default => nil (No limit)
  max_send_limit_bytes         (integer) :default => nil (No drop)
  discard_kafka_delivery_failed   (bool) :default => false (No discard)
  monitoring_list              (array)   :default => []
match>

kafka_buffered有两个附加参数:

  • kafka_agg_max_bytes :默认值 4096,要包含在一次批处理传输中的消息总大小的最大值。
  • kafka_agg_max_messages :默认值 nil,在一次批处理传输中包含的最大消息数。

3.7. 无缓冲输出插件

这个插件使用 ruby-kafka 生产者来写数据。考虑到性能和可靠性,使用 kafka_bufferd 输出代替。这主要用于测试。

<match app.**>
  @type kafka

  # Brokers: you can choose either brokers or zookeeper.
  brokers        <broker1_host>:<broker1_port>,<broker2_host>:<broker2_port>,.. # Set brokers directly
  zookeeper      <zookeeper_host>:<zookeeper_port> # Set brokers via Zookeeper
  zookeeper_path <broker path in zookeeper> :default => /brokers/ids # Set path in zookeeper for kafka

  default_topic         (string) :default => nil
  default_partition_key (string) :default => nil
  default_message_key   (string) :default => nil
  output_data_type      (json|ltsv|msgpack|attr:<record name>|<formatter name>) :default => json
  output_include_tag    (bool) :default => false
  output_include_time   (bool) :default => false
  exclude_topic_key     (bool) :default => false
  exclude_partition_key (bool) :default => false

  # ruby-kafka producer options
  max_send_retries    (integer) :default => 1
  required_acks       (integer) :default => -1
  ack_timeout         (integer) :default => nil (Use default of ruby-kafka)
  compression_codec   (string)  :default => nil (No compression. Depends on ruby-kafka: https://github.com/zendesk/ruby-kafka#compression)
  max_buffer_size     (integer) :default => nil (Use default of ruby-kafka)
  max_buffer_bytesize (integer) :default => nil (Use default of ruby-kafka)
match>

该插件还支持 ruby-kafka 相关参数。参阅缓冲输出插件部分。

3.8. 基于 rdkafka 的输出插件

这个插件在 kafka 客户端使用 rdkafka 而不是 ruby-kafka。需要安装 rdkafka gem。

# rdkafka is C extension library. Need to install development tools like ruby-devel, gcc and etc
# for v0.12 or later
$ gem install rdkafka --no-document
# for v0.11 or earlier
$ gem install rdkafka -v 0.6.0 --no-document

rdkafka2 适用于 fluentd v1.0 或更高版本。

<match app.**>
  @type rdkafka2

  brokers <broker1_host>:<broker1_port>,<broker2_host>:<broker2_port>,.. # Set brokers directly

  topic_key             (string) :default => 'topic'
  default_topic         (string) :default => nil
  partition_key         (string) :default => 'partition'
  partition_key_key     (string) :default => 'partition_key'
  message_key_key       (string) :default => 'message_key'
  default_topic         (string) :default => nil
  default_partition_key (string) :default => nil
  default_message_key   (string) :default => nil
  exclude_topic_key     (bool) :default => false
  exclude_partition_key (bool) :default => false
  discard_kafka_delivery_failed (bool) :default => false (No discard)

  # same with kafka2
  headers               (hash) :default => {}
  headers_from_record   (hash) :default => {}

  <format>
    @type (json|ltsv|msgpack|attr:<record name>|<formatter name>) :default => json
  format>

  # Optional. See https://docs.fluentd.org/v/1.0/configuration/inject-section
  <inject>
    tag_key tag
    time_key time
  inject>

  # See fluentd document for buffer section parameters: https://docs.fluentd.org/v/1.0/configuration/buffer-section
  # Buffer chunk key should be same with topic_key. If value is not found in the record, default_topic is used.
  <buffer topic>
    flush_interval 10s
  buffer>

  # You can set any rdkafka configuration via this parameter: https://github.com/edenhill/librdkafka/blob/master/CONFIGURATION.md
  rdkafka_options {
    "log_level" : 7
  }

  # rdkafka2 specific parameters

  # share kafka producer between flush threads. This is mainly for reducing kafka operations like kerberos
  share_producer (bool) :default => false
  # Timeout for polling message wait. If 0, no wait.
  rdkafka_delivery_handle_poll_timeout (integer) :default => 30
  # If the record size is larger than this value, such records are ignored. Default is no limit
  max_send_limit_bytes (integer) :default => nil
match>

如果使用 v0.12,请使用rdkafka

<match kafka.**>
  @type rdkafka

  default_topic kafka
  flush_interval 1s
  output_data_type json

  rdkafka_options {
    "log_level" : 7
  }
match>

4. 常见问题

为什么 fluent-plugin-kafka 不能发送数据到我们的 kafka 集群?

通常是由于插件使用的 ruby-kafka 和 kafka 集群版本不匹配导致的。更多细节请参见:https://github.com/zendesk/ruby-kafka#compatibility。

解决办法有两个:

  • 升级 kafka 集群到最新版本,最新版更快更健壮。
  • 降级 ruby-kafka 或 fluent-plugin-kafka 以适配当前使用的旧的 kafka。

你可能感兴趣的:(Fluentd,fluentd,kafka)