Kafka集群搭建

Kafka 集群搭建
Kafka是一种高吞吐量的分布式发布订阅消息系统,它可以处理消费者规模的网站中的所有动作流数据。本篇文档主要介绍下kafka集群的搭建及使用,和个人在搭建kafka集群中碰到的问题和解决方案。
首先,需要准备的软件:
1、Kafka (http://kafka.apache.org/downloads
2、Zookeeper(搭建集群,kafka启动依赖zookeeper)
3、Kafka-manager 主要负责监控kafka的信息流量,以及消费的信息(https://github.com/yahoo/kafka-manager
Kafka集群是把状态保存在Zookeeper中的,首先要搭建Zookeeper集群。(搭建zookeeper集群的过程这边就不做介绍了)
软件环境
(3台服务器-我的测试)
192.168.181.90 server90
192.168.181.91 server91
192.168.181.92 server92
搭好zookeeper集群后的地址为:192.168.181.90:48881,192.168.181.91:48881,192.168.181.92:48881
Kafka集群搭建
1、软件环境
Linux 3台
已经搭建好的zookeeper集群
软件版本kafka_2.10-0.10.2.0
2、修改配置文件
进入到config目录 : cd /home/qcj/kafka_2.10-0.10.2.0/
主要关注:server.properties 这个文件即可,
修改配置文件(这里主要说明下需要修改的地方):
broker.id=0 每台服务器的broker.id都不能相同,三台分别为0,1,2
listeners=PLAINTEXT://192.168.181.90:9092(这里特别说明下,ip一定要配,不然consumer消费的时候可能会找不到地址),三台分别为192.168.181.90:9092,192.168.181.91:9092,192.168.181.92:9092
zookeeper.connect=192.168.181.90:48881,192.168.181.91:48881,192.168.181.92:48881
这些都改好后,就可以启动每台服务器上的kafka了。

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

在通过ps -ef|grep kafka 检查下kafka是否成功启动。
Ps:这里说明一下,如果不是第一次启动kafka,可能会报broker.id和meta.properties中的broker.id不匹配的错,只要修改/tmp/kafka/meta.properties中broker.id,改成跟server.properties中的相同即可。
3、创建topic
./kafka-topics.sh –create –zookeeper 192.168.181.90:48881,192.168.181.91:48881,192.168.181.92:48881 –replication-factor 3 –partitions 1 –topic cluster1
这里说明一下,eplication-factor要跟集群的台数保持一致。分区partitions根据自己的需求设定。
4、通过./kafka-topics.sh –describe –zookeeper 192.168.181.90:48881,192.168.181.91:48881,192.168.181.92:48881 –topic cluster1可以查看topic的状态。

至此,kafka集群搭建,和topic创建已经完成。

5、JAVA端producer和consumer的配置。
接下里的代码只做demo测试用,并无任何业务处理。
Producer端:

public class KafkaProcuderService2 {
    private static final Logger logger = LoggerFactory.getLogger(KafkaProcuderService2.class);

    private KafkaProducer<String, String> kafkaProducer =new KafkaProducer<>(getKafkaProps());





    public void sendSync(String key, String value) {

        ProducerRecord<String, String> record = new ProducerRecord<>("cluster1", key, value);
        try {
            RecordMetadata result = this.kafkaProducer.send(record).get();
        } catch (InterruptedException e) {
            logger.error("Catch InterruptedException: ", e);
        } catch (ExecutionException e) {
            logger.error("Catch ExecutionException: ", e);
        } catch (Exception e) {
            logger.error("Catch Exception: ", e);
        }
    }

    private Properties getKafkaProps() {
        Properties props = new Properties();
        props.put("bootstrap.servers", "192.168.181.90:9092,192.168.181.91:9092,192.168.181.92:9092");
//        props.put("client.id", "DemoProducer");
        props.put("key.serializer", "org.apache.kafka.common.serialization.StringSerializer");
        props.put("value.serializer", "org.apache.kafka.common.serialization.StringSerializer");

        return props;
    }

    public static void main(String[] args) throws InterruptedException {
        KafkaProcuderService2 kafkaProcuderService2 =  new KafkaProcuderService2();
        int i = 0;
        while(true){
            kafkaProcuderService2.sendSync("i",String.valueOf(i));
            Thread.sleep(2000);
            i++;
        }
    }
}

Consumer端:

public class KafkaConsumerService2 {

    private KafkaConsumer<String, String> consumer;


    private Properties getProps() {
        Properties props = new Properties();
        props.put(ConsumerConfig.BOOTSTRAP_SERVERS_CONFIG, "192.168.181.90:9092,192.168.181.91:9092,192.168.181.92:9092");
        props.put(ConsumerConfig.GROUP_ID_CONFIG, "test-consumer-group");
        props.put(ConsumerConfig.ENABLE_AUTO_COMMIT_CONFIG, "true");
        props.put(ConsumerConfig.AUTO_COMMIT_INTERVAL_MS_CONFIG, "1000");
        props.put(ConsumerConfig.SESSION_TIMEOUT_MS_CONFIG, "30000");
        props.put(ConsumerConfig.KEY_DESERIALIZER_CLASS_CONFIG, "org.apache.kafka.common.serialization.StringDeserializer");
        props.put(ConsumerConfig.VALUE_DESERIALIZER_CLASS_CONFIG, "org.apache.kafka.common.serialization.StringDeserializer");
        return props;
    }

    public void sub() {
        this.consumer = new KafkaConsumer<>(getProps());

        this.consumer.subscribe(Collections.singletonList("cluster1"));
        while(true) {
            try {
                ConsumerRecords<String, String> records = this.consumer.poll(1000);
                records.forEach(stringStringRecord -> {
                    String key = stringStringRecord.key();
                    String value = stringStringRecord.value();
                    System.out.println("key:"+key+"   value"+value);
                });
            } catch (Exception e) {

            }
        }
    }

    public static void main(String[] args) {
        KafkaConsumerService2 kafkaConsumerService2 = new KafkaConsumerService2();
        kafkaConsumerService2.sub();
    }
}

启动producer,和consumer就能看到消费者端在不停的接受生产者发出的消息,并且可以复制多份consumer模拟多个消费者。中断其中任意一台kafka的server,仍能正常消费。中断任意一个consumer,其余的consumer会接着几首消息。(这里说明一下,如果多个消费的group.id设为相同,则只要有一台有在接收消息,其余就等待。如果group.id不相同则全部接受同样的消息。具体根据需求自行配置)
6、遇到的问题和解决方案:
最严重的一个问题就是我们发现中断broker.id=0的kafka server后消费者就无法正常消费。在这个点上我们研究了很久,发现是因为之前kafka运行残留的一些配置信息导致的。然后针对该问题我们总结出了一种解决方案,实测可行,通过链接zookeeper。将上面的kafka配置全部清空。然后重启kafka就能正常消费了。
7、关于kafka-manager的使用:
下载,编绎
编绎,生成发布包: git clone https://github.com/yahoo/kafka-manager
下好后:
cd kafka-manager
sbt clean dist
生成的包会在kafka-manager/target/universal 下面。生成的包只需要Java环境就可以运行了,在部署的机器上不需要安装sbt。
(这一步可能需要比较长的时间)
部署
打好包好,在部署机器上解压,修改好配置文件,就可以运行了。
- 解压
unzip kafka-manager-1.0-SNAPSHOT.zip
修改conf/application.conf,把kafka-manager.zkhosts改为自己的zookeeper服务器地址
kafka-manager.zkhosts=”localhost:2181”
启动
cd kafka-manager-1.0-SNAPSHOT/bin
./kafka-manager -Dconfig.file=../conf/application.conf
查看帮助 和 后台运行:
./kafka-manager -h
nohup ./kafka-manager -Dconfig.file=../conf/application.conf >/dev/null 2>&1 &
默认http端口是9000,可以修改配置文件里的http.port的值,或者通过命令行参数传递:
./kafka-manager -Dhttp.port=9001
接着可以访问localhost(你部署的服务器):9000就可以访问manager页面了。下面是页面展示:

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值