logstash kafka多台机器取数据,只有一个实例消费【logstash2.3.4】

本文描述了一种Logstash消费Kafka数据时的问题及解决方案。当多台Logstash服务机器配置相同的topic和groupId时,只有最后启动的一台机器能够消费数据。通过分析logstash的输入模块代码,发现在特定条件下会删除Zookeeper中消费者的记录,导致其他实例无法继续消费。通过禁用此行为可以解决该问题。

描述:首先kafka的partition数量为6,多台logstash服务机器的topic相同并且groupId也相同。当分别启动机器时,只有一台机器在消费kafka数据,并且总是最后启动的那台在消费。修改了zk时间等各种kafka配置均没有效果,最后不得不看ruby源码了。感觉kakfa的代码写的还是有点问题的。

首先介绍logstash的input-kafka模块的代码结构

kafka.rb -- logstash-2.3.4/vendor/bundle/jruby/1.9/gems/logstash-input-kafka-2.0.8/lib/logstash/inputs/
group.rb -- logstash-2.3.4/vendor/bundle/jruby/1.9/gems/jruby-kafka-1.5.0-java/lib/jruby-kafka

主要的代码逻辑集中在这两个ruby文件上,kafka.rb主要接收配置参数,并调用group.rb对kafka数据进行消费,这个过程是调用的kafka java api,大体流程于java代码类似。
仔细读下去会发现group.rb的代码有点问题:

  def run(a_num_threads, a_queue)
    begin
      if @reset_beginning == 'from-beginning'
        Java::kafka::utils::ZkUtils.maybeDeletePath(@zk_connect, "/consumers/#{@group_id}")
      end

      @consumer = Java::kafka::consumer::Consumer.createJavaConsumerConnector(create_consumer_config)
    rescue ZkException => e
      raise KafkaError.new(e), "Got ZkException: #{e}"
    end

    thread_value = a_num_threads.to_java Java::int
    streams = get_streams(thread_value)

    @executor = Executors.newFixedThreadPool(a_num_threads)
    @executor_submit = @executor.java_method(:submit, [Java::JavaLang::Runnable.java_class])

    thread_number = 0
    streams.each do |stream|
      @executor_submit.call(Kafka::Consumer.new(stream, thread_number, a_queue, @consumer_restart_on_error, @consumer_restart_sleep_ms))
      thread_number += 1
    end
    @running = true
  end

在定义的run方法中,

if @reset_beginning == 'from-beginning'
        Java::kafka::utils::ZkUtils.maybeDeletePath(@zk_connect, "/consumers/#{@group_id}")
      end

主要含义是删除zk目录下,该groupId的信息。就因为有这句话,原来logstash实例的消费信息就会被移除了,所以会出现上述现象(具体这样做的含义,因为时间原因没有过多的调研)

————–这里是解决方法———————
logstash-2.3.4/vendor/bundle/jruby/1.9/gems/jruby-kafka-1.5.0-java/lib/jruby-kafka 目录下,打开group.rb文件,找到代码片,用#注释掉即可

#if @reset_beginning == 'from-beginning'      #Java::kafka::utils::ZkUtils.maybeDeletePath(@zk_connect, "/consumers/#{@group_id}")
 #end
Logstash一个开源的数据收集引擎,可以从各种来源(如日志文件、数据库、消息队列等)收集、转换和发送数据Kafka一个分布式的流处理平台,用于高吞吐量的实时数据、传输和存储。 在Logstash中使用Kafka作为数据输入或输出的插件可以实现将数据Kafka消费或者将数据发送到Kafka中。 要使用LogstashKafka进行集成,首先需要安装LogstashKafka,并确保它们能够正常运行。然后,在Logstash的配置文件中配置Kafka插件,指定Kafka的相关参数(如主题、分区等),以及数据的格式转换和过滤规则。 例如,要从Kafka消费数据,可以使用Logstashkafka插件作为输入插件,并指定要消费的主题和分区。配置示例: ``` input { kafka { bootstrap_servers => "kafka_host:port" topics => ["topic1", "topic2"] group_id => "consumer_group_id" } } output { stdout { codec => json_lines } } ``` 上述配置中,Logstash将从指定的Kafka集群(bootstrap_servers)中消费topic1和topic2数据,并将其输出到标准输出(stdout)。 类似地,要将数据发送到Kafka,可以使用Logstashkafka插件作为输出插件,并指定要发送的主题和Kafka集群的配置。配置示例: ``` input { stdin { codec => json_lines } } output { kafka { bootstrap_servers => "kafka_host:port" topic_id => "topic_name" } } ``` 上述配置中,Logstash将从标准输入(stdin)中读数据,并将其发送到指定的Kafka集群的topic_name主题中。 需要注意的是,配置文件中的参数和配置选项可能因LogstashKafka的版本而略有差异,具体可参考官方文档或相关资源进行配置。
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值