[Kafka] Kafka(一):消息系统基本原理、Kafka初体验、Kafka基本架构

消息系统基本原理

消息系统的分类

基于Peer-to-Peer的消息系统

  • 一般基于pull或polling接受消息;
  • 发送到队列中的消息被一个而且仅仅一个接收者所接收,即使有多个接收者在同一个队列中侦听同一消息;
  • 即支持异步”即发即弃”的消息传送方式,也支持同步请求/应答传送方式;

如下图所示,生产者Producer1生产的消息发送到队列后只能被其中某一个consumer所消费:

这里写图片描述

基于发布/订阅的消息系统

  • 发布到一个主题的消息,可被多个订阅者所接收,主题可认为是消息的类型;
  • 发布/订阅可基于push消费数据,也可基于pull或polling消费数据;
  • 解耦能力比跑p2p模型更强;

如下图所示,消息发布者Pushlisher1生产消息并发送到topic,只要订阅了该主题的Subscriber都可接收到该消息:

这里写图片描述

消息系统的适用场景

  • 解耦: 各系统之间通过消息系统这个统一的接口交换数据,无需了解彼此的存在;
  • 冗余:部分消息系统具有消息持久化能力,可规避消息处理前丢失的风险;
  • 扩展:消息系统是统一的数据接口,各系统可独立扩展;
  • 峰值处理能力:消息系统可顶住峰值流量,业务系统可根据处理能力从消息系统中获取并处理对应量的请求;
  • 可恢复性:系统中部分组件失效并不会影响整个系统,它恢复后仍可从消息系统中获取并处理数据;
  • 异步通信:在不需要立即处理请求的场景下,可将请求放入消息系统,合适的时候再处理;

Kafka设计目标

  • 高吞吐率:在廉价的商用机器上单机可支持每秒100万条消息的读写;
  • 消息持久化:所有消息均被持久化到磁盘,无消息丢失,支持消息重放;
  • 完全分布式:Producer、Broker、Consumer均支持水平扩展;
  • 同时适应在线流处理和离线批处理

Kafka初体验

Kafka使用Scala语言开发,运行于JVM之上,因此我们首先安装Jdk,具体安装方法就不说了,从官网下载Kafka解压:

$ tar -zxvf kafka_2.11-1.1.0

进入到Kafka解压目录,首先启动Zookeeper服务,因为Kafka依赖于Zookeeper,如果需要后台启动Zookeeper则加上-daemon参数:

$ cd kafka_2.11-1.1.0/
$ bin/zookeeper-server-start.sh config/zookeeper.properties

出现如下信息表明Zookeeper启动成功:

[2018-07-06 08:55:57,637] INFO binding to port 0.0.0.0/0.0.0.0:2181 (org.apache.zookeeper.server.NIOServerCnxnFactory)

启动Broker服务,同样后台启动只需加上-daemon参数:

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

验证Zookeeper是否已经监听2181端口,可以看到Zookeeper不仅监听2181端口,还和Broker服务建立了链接:

peter@ubuntu:~/Study/Kafka/kafka_2.11-1.1.0$ lsof -i:2181
COMMAND  PID  USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
java    2862 peter   92u  IPv6  53459      0t0  TCP *:2181 (LISTEN)
java    2862 peter   93u  IPv6  53761      0t0  TCP localhost:2181->localhost:52102 (ESTABLISHED)
java    3150 peter  110u  IPv6  53760      0t0  TCP localhost:52102->localhost:2181 (ESTABLISHED)

验证Broker服务是否监听9092端口:

peter@ubuntu:~/Study/Kafka/kafka_2.11-1.1.0$ lsof -i:9092
COMMAND  PID  USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
java    3150 peter   97u  IPv6  52842      0t0  TCP *:9092 (LISTEN)
java    3150 peter  113u  IPv6  53762      0t0  TCP localhost:34792->ubuntu:9092 (ESTABLISHED)
java    3150 peter  114u  IPv6  53763      0t0  TCP ubuntu:9092->localhost:34792 (ESTABLISHED)

创建Topic,需要制定Zookeeper列表、Topic名称、Partitions数量等:

$ bin/kafka-topics.sh --zookeeper localhost:2181 --create --topic test1 --partitions 3 --replication-factor 1

验证Topic是否创建成功:

$ bin/kafka-topics.sh --zookeeper localhost:2181 --describe --topic test1

显示如下结果:

Topic:test1 PartitionCount:3    ReplicationFactor:1 Configs:
    Topic: test1    Partition: 0    Leader: 0   Replicas: 0 Isr: 0
    Topic: test1    Partition: 1    Leader: 0   Replicas: 0 Isr: 0
    Topic: test1    Partition: 2    Leader: 0   Replicas: 0 Isr: 0

启动Kafka提供的Consumer命令行工具:

$ bin/kafka-console-consumer.sh --bootstrap-server localhost:9092 --topic test1

启动Kafka提供的Producer命令行工具:

$ bin/kafka-console-producer.sh --broker-list localhost:9092 --topic test1

Kafka架构

Kafka的整体架构图如下图所示:

这里写图片描述

Kafka由四个主要主要部分组成:Producer生产数据并push到Broker;Broker接收Producer发送过来的消息并将消息持久化,然后提供若干个Topic供Consumer订阅,Broker作为Kafka的Server是由若干台机器组成的集群;Consumer从Kafka订阅和获取消息,获取消息的形式为pull,这样Consumer只需要根据自身的消费能力从Broker获取适量的消息,可防止需要瞬间处理大量的消息,实现对抗峰值流量的的能力,同时Broker也不需要感知Consumer的存在,简化了Broker的设计;Zookeeper负责协调Broker集群,Consumer可以从Zookeeper集群获取Broker集群的元数据信息,从图中可以看出Producer并没有使用Zookeeper来获取Broker集群的元数据,这是因为我们在使用Producer的SDK的时候需要我们自己制定若干台Broker节点的信息,Producer只要成功连接了其中一台Broker机器,即可获取整个Broker集群的信息。

Producer刷新Broker集群元数据信息有两种方式:一、当Producer向某一台Broker机器发送消息失败的时候,则该机器上运行的Broker服务可能宕掉了,这是会触发Producer刷新本地缓存的Broker元数据信息;二、Producer定期的刷新本地缓存的Broker集群元数据信息,其中刷新周期可以通过Producer的配置参数做配置。

其中Broker和Zookeeper作为服务运行,而Producer和Consumer是Kafka提供的SDK,我们可以通过Producer的SDK向Broker发送消息,通过Consumer的SDK从Kafka获取消息。

Topic & Partition

Topic:

  • 顾名思义,消息的主题,可认为Kafka使用Topic对消息进行分类;
  • Topic是逻辑上的概念,隶属同一个Topic的消息可分布在一个或多个Broker节点上;
  • 一个Topic包含一个或多个Partition;
  • 每条消息属于仅且属于一个Topic;
  • 当Producer发布消息时,必须指定将该消息发布到哪一个Topic;
  • 当Consumer订阅消息时,也必须指定订阅哪个Topic的消息;

如下图所示:

这里写图片描述

Broker1、Broker2和Broker3组成了Broker集群,该集群内有两个Topic,Topic1有六个Partition,Topic2有三个Partition,每个Topic具有的Partition数量并不完全一样,默认情况下Kafka会让Partition均匀的分配在各个Broker机器上,从而让整个Broker集群的负载更加均衡。

Partition

  • Partition是一个物理的概念,不考虑备份的情况下同一个Topic下的一个Partition只分布于一台Broker机器上;
  • 一个Partition物理上对应一个文件夹,等下我们实验的时候可以验证这一点;
  • 一个Partiton包含多个Segment(Segment对用户透明);
  • 一个Segment对应一个文件,Kafka会将记录写入到这些文件当中;
  • Segment由一个个不可变的记录组成;
  • 记录只会append到Segment上,不会被单独删除或修改;
  • 清除记录时,直接删除一个或多个Segment,即直接删除Segment对应的文件,这样类似于关系型数据库中直接drop table数据来更加高效的清除过期记录;

这里写图片描述

猜你喜欢

转载自blog.csdn.net/zkp_java/article/details/80934840