Apache Kafka 消息中间件

Apache Kafka 消息中间件_第1张图片

1、概述

  • Kafka官方网站地址。
  • Kafka中文网站地址。
  • kafka官网上对 kafka 的定义:一个分布式发布-订阅消息传递系统。
  • 最初由LinkedIn公司开发,Linkedin于2010年贡献给了Apache基金会并成为顶级开源项目。
  • 据统计,有三分之一的世界财富500强企业正在使用Kafka,包括所有TOP10旅游公司,7家TOP10银行,8家TOP10保险公司,9家TOP10电信公司等等。LinkedIn、Microsoft和Netflix每天都用Kafka处理万亿级的信息。
  • Kafka是一个分布式的、分区的、多副本的、多订阅者,基于zookeeper协调的分布式消息系统。

2、常见消息中间件对比

Apache Kafka 消息中间件_第2张图片
Apache Kafka 消息中间件_第3张图片

3、特性

  • 可扩展性:kafka集群支持动态扩展;
  • 持久性、可靠性:消息被持久化到本地磁盘,并且支持数据备份防止丢失;
  • 容错性:允许集群中的节点失败(若分区副本数量为n,则允许n-1个节点失败);
  • 高并发:单机可支持数千个客户端同时读写;
  • 客户端状态维护:消息被处理的状态是在Consumer端维护,而不是由server端维护,当失败时能自动平衡;
  • 支持多种客户端语言:支持Java、.NET、PHP、Python等多种语言;
  • 高吞吐量、低延迟:单机每秒处理几十上百万的消息量。即使存储了很多TB的消息,它也保持稳定的性能和毫秒级的时延;

4、kafka吞吐量为什么这么高?

  • 1、顺序读写磁盘
  • Kafka是将消息持久化到本地磁盘中;
  • 不管是内存还是磁盘,快或慢的关键在于寻址方式;
  • 磁盘分为顺序读写与随机读写,内存一样也分为顺序读写与随机读写;
  • 基于磁盘的随机读写确实很慢,但基于磁盘的顺序读写性能却很高,一般而言要高出磁盘的随机读写三个数量级,一些情况下磁盘顺序读写性能甚至要高于内存随机读写。

Apache Kafka 消息中间件_第4张图片
Apache Kafka 消息中间件_第5张图片

  • 2、page cache
  • 为了优化读写性能,Kafka利用了操作系统本身的Page Cache,就是利用操作系统自身的内存而不是JVM空间内存;
  • 页高速缓冲存储器,简称页高缓;
  • page cache的大小为一页,通常为4K;
  • 在linux读写文件时,它用于缓存文件的逻辑内容,从而加快对磁盘上映像和数据的访问;
  • 从外存的一页到内存的一页的映射过程中,page cache与buffer cache、swap cache共同实现了高速缓存功能;

Apache Kafka 消息中间件_第6张图片

  • 当Producer和Consumer速率相差不大的情况下,Kafka几乎可以完全实现不落盘就完成信息的传输;
  • 下图表示的就是一种理想化的场景,如果Kafka producer的生产速率与
    consumer的消费速率相差不大,他们之间的lag相差很小,访问的是page
    cache中的同一个page。那么就能几乎只靠对broker page cache的读写来
    完成整个生产-消费过程,磁盘访问非常少;

Apache Kafka 消息中间件_第7张图片

  • 3、零拷贝
  • 零拷贝是指Kafka利用linux操作系统的 “zero-copy” 机制在消费端做的优化;
  • 消费端在消费数据时,数据从broker磁盘通过网络传输到消费端的整个过程,包含4次copy操作和2次系统上下文切换,而上下文切换是CPU密集型的工作,数据拷贝是I/O密集型的工作,性能非常低效;
  • 零拷贝就是将数据从page cache直接发送到Socket缓冲区,避免了系统上下文的切换,消除了从内核空间到用户空间的来回复制。从下图可以看出,"零拷贝"并不是说整个过程完全不发生拷贝,而是站在内核的角度来说的,避免了内核空间到用户空间的来回拷贝;

Apache Kafka 消息中间件_第8张图片

  • 4、分区分段
  • Kafka的设计非常符合分布式系统分区分桶的设计思想;
  • message是按topic分类存储的,topic中的数据又是按照一个个的partition即分区存储到不同broker节点;
  • 每个partition对应了操作系统上的一个文件夹,partition实际上又是按照segment分段存储的;
  • 通过这种分区分段的设计,Kafka的message消息实际上是分布式存储在一个个小的segment中的,每次文件操作也是直接操作的segment;
  • 为了进一步的查询优化,Kafka又默认为分段后的数据文件建立了索引文件,就是文件系统上的.index文件;
  • 这种分区分段+索引的设计,不仅提升了数据读取的效率,同时也提高了数据操作的并行度;
  • 总之,Kafka采用顺序读写、Page Cache、零拷贝以及分区分段等这些设计,再加上在索引方面做的优化,另外Kafka数据读写也是批量的而不是单条的,使得Kafka具有了高性能、高吞吐、低延时的特点。

5、应用场景

  • 日志收集:可以用Kafka收集各种服务的log,通过kafka以统一接口开放给各种消费端;
  • 消息系统:在分布式或者大数据开发中通常使用消息队列进行缓冲、系统间解耦和削峰填谷等业务场景;
  • 用户活动跟踪:用来记录web用户或者APP用户的各种活动,如网页搜索、搜索、点击,用户数据收集然后进行用户行为分析;
  • 运营指标:Kafka也经常用来记录运营监控数据,包括收集各种分布式应用的数据,生产各种操作的集中反馈,比如报警和报告;
  • 流式处理:类似Flink、spark streaming和storm等

6、基础概念

  • Broker:Kafka节点,一个独立的Kafka 服务器被称为broker,是Kafka集群的组成部分;
  • Topic:一类消息,消息存放的目录即主题,例如page view日志、click日志等都可以以topic的形式存在,Kafka集群能够同时负责多个topic的分发;
  • massage: Kafka中最基本的传递对象,可以把消息看成是数据库里的一个“数据行”或一条“记录”,消息由字节数组组成;
  • Partition:topic物理上的分组,一个topic可以分为多个partition,每个partition是一个有序的队列,Kafka 通过分区来实现数据冗余和伸缩性;
  • Segment:多个大小相等的segment file (段)组成了一个partition,每个partition 就相当于一个巨型的文件,里面由多个大小相等的segment file小文件组成,但是每个segment file 的消息数量并不一定相等,这种设计方便旧的segment file 快速删除;
  • Replicas:kafka 使用主题来组织数据,每个主题被分为若干个分区,每个分区可以指定多个副本;
  • Producer : 生产者,发送消息到指定的topic下,消息再根据分配规则append到某个partition的末尾;
  • Consumer : 消费者,订阅topic并消费message, consumer作为一个线程来消费;
  • Consumer Group:消费者组,一个Consumer Group包含多个consumer,并行消费message,同一topic的一条消息只能被同一个consumer group内的一个consumer消费,但多个consumer group可同时消费这一消息,即消费原则遵循组间共享,组内均分;
  • Offset:偏移量,在kafka 中offset 是partition 中消息序列号,可以认为是这个消息的唯一标识;
  • Leader:每个partition有多个副本,其中有且仅有一个作为leader,leader会负责所有的客户端读写操作;
  • Follower:follower不对外提供服务,只与leader保持数据同步,如果leader失效,则选举一个follower来充当新的leader。当follower与leader挂掉、卡住或者同步太慢,leader会把这个follower从ISR列表中删除,重新创建一个follower;
  • AR:分区中的所有副本统称为AR(Assigned Repllicas),AR=ISR+OSR;
  • ISR:所有与leader副本保持一定程度同步的副本(包括Leader)组成ISR(In-Sync Replicas),ISR集合是AR集合中的一个子集;
  • OSR:与leader副本同步滞后过多的副本(不包括leader)组成OSR(Out-Sync Relipcas);
  • Ack机制:指的是producer的消息发送确认机制(0,1,-1);
  • Rebalance:重平衡,consumer group内某个消费者挂掉后,其他消费者自动重新分配订阅主题分区的过程,是 Kafka 消费者端实现高可用的重要手段。如下图Consumer Group A中的C2挂掉,C1会接收P1和P2,以达到重新平衡。同样的,当有新消费者加入consumer group,也会触发重平衡操作;
    Apache Kafka 消息中间件_第9张图片

Apache Kafka 消息中间件_第10张图片

7、架构原理

Apache Kafka 消息中间件_第11张图片

  • 一个典型的kafka集群中包含若干producer,若干broker(Kafka支持水平扩展,一般broker数量越多,集群吞吐率越高),若干consumer group,以及一个zookeeper集群。kafka通过zookeeper协调管理kafka集群,选举分区leader,以及在consumer group发生变化时进行rebalance。
  • 对于传统的MQ而言,已经被消费的消息会从队列中删除,但在Kafka中被消费的消息也不会立马删除,在kafka的配置文件中定义了数据的保存时间,当文件到设定的保存时间时才会删除。
  • Kafka读取消息的时间复杂度为O(1),与文件大小无关,所以删除过期文件与提高Kafka性能并没有关系,选择怎样的删除策略应该考虑磁盘以及具体的需求。

8、SpringBoot集成kafka

  • 修改Kafka配置(公网访问需要把IP改为公网IP)
advertised.listeners=PLAINTEXT://110.110.110.110:9092

Apache Kafka 消息中间件_第12张图片

  • pom依赖

    org.springframework.kafka
    spring-kafka

  • application.propertise配置
spring:
  kafka:
    bootstrap-servers: 110.110.110.110:9092
    producer:
      acks: 1
      retries: 0
      key-serializer: org.apache.kafka.common.serialization.StringSerializer
      value-serializer: org.apache.kafka.common.serialization.StringSerializer
    consumer:
      group-id: wlf
      enable-auto-commit: true
      auto-offset-reset: latest
      auto-commit-interval: 100
      key-deserializer: org.apache.kafka.common.serialization.StringDeserializer
      value-deserializer: org.apache.kafka.common.serialization.StringDeserializer
  • KafkaProducer生产者
package com.cloudansys.api;

import com.cloudansys.constant.Const;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.kafka.core.KafkaTemplate;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;

/**
 * @author wlf
 * @since 2022/6/12
 */
@Slf4j
@RestController
public class TestProduce {

    @Resource
    private KafkaTemplate<String, Object> kafkaTemplate;

    @ApiOperation(value = "生产消息")
    @ApiImplicitParam(
            value = "消息",
            name = "msg",
            required = true
    )
    @PostMapping("/kafka/produce")
    public void sendMessage1(@RequestParam(value = "msg") String msg) {
        log.info("msg:{}", msg);
        kafkaTemplate.send(Const.TOPIC, msg);
    }

}

  • KafkaConsumer消费者
package com.cloudansys.config;

import com.cloudansys.constant.Const;
import lombok.extern.slf4j.Slf4j;
import org.apache.kafka.clients.consumer.ConsumerRecord;
import org.springframework.kafka.annotation.KafkaListener;
import org.springframework.stereotype.Component;

/**
 * @author wlf
 * @since 2022/6/12
 */
@Slf4j
@Component
public class TestConsume {

    @KafkaListener(topics = {Const.TOPIC})
    public void consume(ConsumerRecord<?, ?> record) {
        // 打印出消费的哪个topic、partition的信息,以及消息内容
        System.out.println("topic=" + record.topic());
        System.out.println("partition=" + record.partition());
        System.out.println("record=" + record.value());
    }

}

9、监控工具

主流的三种kafka监控工具:

  • Kafka Manager【CMAK】:偏向Kafka集群管理,对Kafka实时生产和消费消息是通过JMX实现的。
  • Kafka Web Conslole:监控功能较为全面,可以预览消息,监控Offset、Lag等信息,但存在bug,不建议在生产环境中使用;
  • KafkaOffsetMonitor:程序以一个jar包的形式运行,部署较为方便,但只有监控功能,不过使用起来也较为安全。

Apache Kafka 消息中间件_第13张图片

Apache Kafka 消息中间件_第14张图片

Apache Kafka 消息中间件_第15张图片

Apache Kafka 消息中间件_第16张图片

你可能感兴趣的:(Java,大数据,kafka,apache,java,springboot,消息中间件)