Kafka 集群安装部署及应用场景


Kafka 是一款分布式消息发布和订阅系统,具有高性能、高吞吐量的特点而被广泛应用与大数据传输场景。

通过kafka可以实现日志收集、行为跟踪、消息的通信。

当produce 生产者发送数据到 broker上的topic 时,会通过 zk的 watcher事件通知给监听的consumer ,此时consumer 可以主动去pull 拉去broker 的消息,这块跟其他mq是不同的。

kafka支持分区(partition),在集群环境下我们通过将消息进行分区来减少此磁盘的压力。

消息分发策略 :默认的消息分发策略是基于key 的hash一致性,当producer 生产消息到broker上时,会根据分发策略存储到不同的分区上。

分区分配策略:默认是范围分区是基于partition进行排序,当多个consumer 同时去消费topic时,会根据分区分配策略去选择对应的partition 进行消费,来减少服务器上的压力。

当真正消费消息,如果增加或减少consumer 或者partition 发生了变化,此时会重新进行分区分配策略,即rebanlance 。在进行Rebalance时,kafka会通过coordinator 来进行管理consumer 下group,当第一个consumer进行启动时,会去跟kafka server 确认coordinator,kafka server会选择broker节点最小的作为coordinator,之后所有的consumer会跟coordinator 进行通信。

应用场景

由于 kafka 具有较好的吞吐量、内置分区、冗余及容错性的优点(可以每秒处理几十万消息),让 kafka 成为了一个很好的大规模消息处理应用的解决方案。在企业级应用上,主要会应用于以下几个方面

  • 行为跟踪:kafka 可以用于跟踪用户浏览页面、搜索及其他行为。通过发布-订阅模式实时记录到对应的topic 中,通过后端大数据平台接入处理分析,并做更进一步的实时处理和监控
  • 日志收集:日志聚合表示从服务器上收集日志文件,然后放到一个集中的平台(文件服务器)进行处理。在实际应用开发中,我们应用程序的log 都会输出到本地的磁盘上,排查问题的话通过linux 命令来搞定,如果应用程序组成了负载均衡集群,并且集群的机器有几十台以上,那么想通过日志快速定位到问题,就是很麻烦的事情了。所以一般都会做一个日志统一收集平台管理log 日志用来快速查询重要应用的问题。所以很多公司的套路都是把应用日志几种到kafka 上,然后分别导入到es 和hdfs 上,用来做实时检索分析和离线统计数据备份等。而另一方面,kafka 本身又提供了很好的api 来集成日志并且做日志收集在这里插入图片描述

Kafka 本身架构

kafka 集群包含若干个 Producer(可以是应用节点产生的消息,也可以是通过Flume 收集日志产生的事件),若干个Broker(kafka 支持水平扩展)、若干个ConsumerGroup,以及一个zookeeper 集群。

kafka 通过zookeeper 管理集群配置及服务协同。Producer 使用push 模式将消息发布到broker,consumer 通过监听使用pull 模式从broker 订阅并消费消息。多个broker 协同工作,producer 和consumer 部署在各个业务逻辑中。三者通过zookeeper 管理协调请求和转发。这样就组成了一个高性能的分布式消息发布和订阅系统。

有一个细节是和其他 mq 中间件不同的点,producer 发送消息到broker的过程是push,而consumer 从broker 消费消息的过程是pull,主动去拉数据。而不是broker 把数据主动发送给consumer

在这里插入图片描述

Kafka 安装部署

安装

wget https://archive.apache.org/dist/kafka/1.1.0/kafka_2.11-1.1.0.tgz
tar -zxvf kafka_2.11-1.1.0.tgz 

启动、停止 kafka

启动 kafka 时需要安装并启动 zookeeper ,(如果没有搭建 zookeeper 环境,可以直接运行 kafka 内嵌的 zookeeper 或者 参考 zookeeper 服务安装

启动 zookeeper 和 kafka

cd /guaoran/zookeeper/zookeeper-3.4.10/bin/
sh zkServer.sh start
cd /guaoran/kafka/kafka_2.11-1.1.0/bin
sh kafka-server-start.sh -daemon ./../config/server.properties

停止 kafka

sh kafka-server-stop.sh 

kafka 基本操作

安装集群环境

修改server.properties 文件

# 修改对应的服务器 节点 三台 分别是 0,1,2 类似zookeeper 的myid
broker.id=0
# 监听修改成本机ip ,ifconfig的ip地址
listeners=PLAINTEXT://192.168.45.135:9092
## 对外的ip地址
advertised.listeners=PLAINTEXT://192.168.45.135:9092
# advertised.host.name=192.168.45.135
# advertised.port=9092
# 修改 kafka 日志 目录,可以采用默认,不过会丢失
log.dirs=/guaoran/kafka/logs
# 配置zookeeper 的集群地址
zookeeper.connect=192.168.45.131:2181,192.168.45.134:2181,192.168.45.135:2181

Kafka Java API 的使用

生产者消息发送

/**
 * @author : guaoran
 * @Description : <br/>
 *  生产者消息发送
 * @date :2018/11/9 16:00
 */
public class KafkaProducerDemo extends Thread {
    private final static String CONNECT_URL =
            "192.168.45.131:9092,192.168.45.134:9092,192.168.45.135:9092";
    private final KafkaProducer<Integer,String> producer;
    private final boolean isAysnc;
    private final String topic;
    public KafkaProducerDemo(String topic,boolean isAysnc){
        this.isAysnc = isAysnc;
        this.topic = topic;
        Properties properties = new Properties();
        //连接地址
        properties.put(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG,CONNECT_URL);
        properties.put(ProducerConfig.CLIENT_ID_CONFIG,"KafkaProducerDemo");
        // producer 发送消息到 broker 上以后的确认值
        // 0 :表示 producer 不需要等待 broker 的消息确认,如果server 宕机 ,数据会丢失
        // 1 :表示 producer 只需要获得 kafka 集群中的 leader 节点确认即可
        // all(-1) :表示 producer 需要ISR中所有的Replica接受确认,速度较慢,安全性最高,如果只有一个Replica时,并不能一定能避免数据丢失。
        properties.put(ProducerConfig.ACKS_CONFIG,"-1");
        properties.put(ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG,
                "org.apache.kafka.common.serialization.IntegerSerializer");
        properties.put(ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG,
                "org.apache.kafka.common.serialization.StringSerializer");

        /*
           batch.size
           生产者发送多个消息到broker上的同一个分区时,为了减少网络请求带来的性能开销,通过批量的方式来提交消息,
           可以通过这个参数来控制批量提交的字节数大小,默认是16kb,意味着当一批消息大小达到指定的 batch.size 时会统一发送。

           linger.ms
            producer 默认会把两次发送时间间隔内收集到的所有 request 进行一次聚合,然后再发送,以提高吞吐量。
            而linger.ms 就是为每次发送到broker 的请求增加一些 delay,以此来聚合更多的message请求。

           batch.size 和 linger.ms 这两个参数是 kafka 的性能优化的关键参数,如果两个都配置,只要满足其中一个要求,就会发送消息到broker

           max.request.size
            设置请求的数据的最大字节数,为了防止发生较大的数据包影响到吞吐量,默认是1MB
         */
        producer = new KafkaProducer<Integer, String>(properties);


    }

    @Override
    public void run() {
        int num = 0;
        while(num<50){
            String message = "message_"+num;
            System.out.println("begin...send..."+message);
            if(isAysnc){//异步发送
                producer.send(new ProducerRecord<Integer, String>(topic,message),new Callback(){
                    @Override
                    public void onCompletion(RecordMetadata recordMetadata, Exception e) {
                        if(recordMetadata != null){
                            System.out.println("async-offset:"+recordMetadata.offset()+
                                    "->partition:"+recordMetadata.partition());
                        }
                    }
                });
            }else{//同步发送
                try {
                    RecordMetadata recordMetadata = producer.send(new ProducerRecord<Integer, String>(topic,message)).get();
                    System.out.println("sync-offset:"+recordMetadata.offset()+
                            "->partition:"+recordMetadata.partition());
                } catch (InterruptedException e) {
                    e.printStackTrace();
                } catch (ExecutionException e) {
                    e.printStackTrace();
                }
            }
            num++;
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    public static void main(String[] args) {
        new KafkaProducerDemo("test",false).start();
    }
}

消费者消费消息

/**
 * @author : guaoran
 * @Description : <br/>
 *  消费端消息接受
 * @date :2018/11/9 16:00
 */
public class  KafkaConsumerDemo extends Thread {
    private final static String CONNECT_URL =
            "192.168.45.131:9092,192.168.45.134:9092,192.168.45.135:9092";
    private final KafkaConsumer<Integer,String> consumer;
    public KafkaConsumerDemo(String topic){
        Properties properties = new Properties();
        properties.put(ConsumerConfig.BOOTSTRAP_SERVERS_CONFIG,CONNECT_URL);
        //分组id
        properties.put(ConsumerConfig.GROUP_ID_CONFIG,"KafkaConsumerDemo1");
        // enable.auto.commit 消费者消费消息以后自动提交,只有当消息提交以后,该消息才不会被再次接收到
        // 还可以配合 auto.commit.interval.ms 控制自动提交的频率。
        properties.put(ConsumerConfig.ENABLE_AUTO_COMMIT_CONFIG,"true");
        properties.put(ConsumerConfig.KEY_DESERIALIZER_CLASS_CONFIG,
                "org.apache.kafka.common.serialization.IntegerDeserializer");
        properties.put(ConsumerConfig.VALUE_DESERIALIZER_CLASS_CONFIG,
                "org.apache.kafka.common.serialization.StringDeserializer");
        //auto.offset.reset
        //这个参数是针对新的 groupid中的消费者而言的,当有新的groupid的消费者来消费指定的topic时,对于该参数的配置,会有不同的语义
        // 当 kafka 没有初始偏移量或服务器上当前偏移量不再存在时
        // latest:自动将偏移重置为最新偏移
        // earliest:自动将偏移量重置为最早的偏移量
        // none:如果没有找到消费者组的先前偏移,则向用户抛出异常
        properties.put(ConsumerConfig.AUTO_OFFSET_RESET_CONFIG,"earliest");

        /*
           max.poll.records
            此设置限制每次调用poll 返回的消息数,这样可以更容易的预测每次 poll 间隔要处理的最大值,通过调整此值,可以减少poll 间隔

         */
        consumer = new KafkaConsumer<Integer, String>(properties);
        consumer.subscribe(Collections.singletonList(topic));
    }

    @Override
    public void run() {
        while(true){
            ConsumerRecords<Integer,String> consumerRecords = consumer.poll(1000);
            for (ConsumerRecord r :consumerRecords) {
                System.out.println("consumer...receive.."+r.value());
            }
        }
    }

    public static void main(String[] args) {
        new KafkaConsumerDemo("test").start();
    }
}
  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值