Kafka学习总结(一)初识Kafka

Kafka是最初由Linkedin公司开发,是一个分布式、分区的、多副本的、多订阅者,基于zookeeper协调的分布式日志系统(也可以当做MQ系统),常见可以用于web/nginx日志、访问日志,消息服务等等,Linkedin于2010年贡献给了Apache基金会并成为顶级开源项目。

1 简介

Kafka就是一款基于发布与订阅的梢息系统。它一般被称为 “分布式提交日志”或者“分布式流平台”。文件系统或数据库提交日志用来提供所有事务的持久记录 , 通过重放这些日志可以重建系统的状态。同样地, Kafka 的数据是按照 一定 顺序持久化保存的,可以按需读取 。 此外, Kafka 的数据分布在整个系统里,具备数据故 障保护和性能伸缩能力。

消息系统

一个消息系统负责将数据从一个应用传递到另外一个应用,应用只需关注于数据,无需关注数据在两个或多个应用间是如何传递的。消息系统的核心作用有三点:解耦,异步和并行

分布式消息传递基于可靠的消息队列,在客户端应用和消息系统之间异步传递消息。有两种主要的消息传递模式:点对点传递模式、发布-订阅模式。大部分的消息系统选用发布-订阅模式。Kafka就是一种发布-订阅模式。

点对点:

在点对点消息系统中,消息持久化到一个队列中。此时,将有一个或多个消费者消费队列中的数据。但是一条消息只能被消费一次。当一个消费者消费了队列中的某条数据之后,该条数据则从消息队列中删除。该模式即使有多个消费者同时消费数据,也能保证数据处理的顺序。

生产者发送一条消息到queue,只有一个消费者能收到。

发布/订阅:

在发布-订阅消息系统中,消息被持久化到一个topic中。与点对点消息系统不同的是,消费者可以订阅一个或多个topic,消费者可以消费该topic中所有的数据,同一条数据可以被多个消费者消费,数据被消费后不会立马删除。在发布-订阅消息系统中,消息的生产者称为发布者,消费者称为订阅者。

发布者发送到topic的消息,只有订阅了topic的订阅者才会收到消息。

1.1 kafka的介绍

kafka是一个分布式消息队列:生产者、消费者的功能。她提供了类似于JMS 的特性,但是设计实现上完全不同。

kafka的基本概念:

  • topic(主题) :Kafka根据topic对消息进行归类,发布到 Kafka集群的每条消息都需要指定一个topic
  • partition(分区) : 一个topic可以分为多个 partition,每个partition内部消息是有序 的
  • offset(偏移量) 标识分区每条记录的位置
  • broker : 消息中间件处理节点,一个Kafka节点就是 一个broker,一个或者多个Broker可以组 成一个Kafka集群
  • ConsumerGroup : 物理上的概念,一个topic可以分为多个 partition,每个partition内部消息是有序 的
  • Leader : 每个partition有多个副本,其中有且仅有一个作为Leader,Leader是当前负责数据的读写的partition。
  • Follower : Follower跟随Leader,所有写请求都通过Leader路由,数据变更会广播给所有Follower,Follower与Leader保持数据同步。如果Leader失效,则从Follower中选举出一个新的Leader。当Follower与Leader挂掉、卡住或者同步太慢,leader会把这个follower从“in sync replicas”(ISR)列表中删除,重新创建一个Follower。

kafka对消息保存时根据topic进行归类,发送消息者称为Producer,消息接受者称为Consumer,此外kafka集群有多个kafka实例组成,每个实例(server)成为broker。

无论是kafka集群,还是producer和consumer集群都依赖与zookeeper集群保存一些meta消息,来保证系统可用性。

producers通过网络将消息发送到Kafka集群,集群向消费者提供消息,如下图所示:

客户端和服务端通过TCP协议通信。Kafka提供了Java客户端,并且对多种语言都提供了支持。

kafka概念讲解

让我们首先深入理解Kafka提出一个高层次的抽象概念-Topic。 可以理解Topic是一个类别的名称,同类消息发送到同一个Topic下面。对于每一个Topic,下面可以有多个分区 (Partition)日志文件:

Partition是一个有序的message序列,这些message按顺序添加到一个叫做commit log的文件中。每个partition中的 消息都有一个唯一的编号,称之为offset,用来唯一标示某个分区中的message。
提示:每个partition,都对应一个commit log文件。一个partition中的message的offset都是唯一的,但是不同的
partition中的message的offset可能是相同的。

可以这么来理解Topic,Partition和Broker
一个topic,代表逻辑上的一个业务数据集,比如按数据库里不同表的数据操作消息区分放入不同topic,订单相关操作消 息放入订单topic,用户相关操作消息放入用户topic,对于大型网站来说,后端数据都是海量的,订单消息很可能是非常 巨量的,比如有几百个G甚至达到TB级别,如果把这么多数据都放在一台机器上可定会有容量限制问题,那么就可以在 topic内部划分多个partition来分片存储数据,不同的partition可以位于不同的机器上,每台机器上都运行一个Kafka的 进程Broker。

kafka集群,在配置的时间范围内,维护所有的由producer生成的消息,而不管这些消息有没有被消费。例如日志保留( log retention )时间被设置为2天。kafka会维护最近2天生产的所有消息,而2天前的消息会被丢弃。kafka的性能与保留 的数据量的大小没有关系,因此保存大量的数据(日志信息)不会有什么影响。

每个consumer是基于自己在commit log中的消费进度(offset)来进行工作的。在kafka中,消费offset由consumer自 己来维护;一般情况下我们按照顺序逐条消费commit log中的消息,当然我可以通过指定offset来重复消费某些消息, 或者跳过某些消息。 这意味kafka中的consumer对集群的影响是非常小的,添加一个或者减少一个consumer,对于集群或者其他consumer 来说,都是没有影响的,因为每个consumer维护各自的offset。所以说kafka集群是无状态的,性能不会因为 consumer数量受太多影响。kafka还将很多关键信息记录在zookeeper里,保证自己的无状态,从而在水平扩容时非常方便。

Producers
生产者将消息发送到topic中去,同时负责选择将message发送到topic的哪一个partition中。通过round­robin做简单的 负载均衡。也可以根据消息中的某一个关键字来进行区分。通常第二种方式使用的更多。

Consumers
传统的消息传递模式有2种:队列( queue) 和(publish-subscribe)
queue模式:多个consumer从服务器中读取数据,消息只会到达一个consumer。
publish-subscribe模式:消息会被广播给所有的consumer。

Kafka基于这2种模式提供了一种consumer的抽象概念:consumer group
queue模式:所有的consumer都位于同一个consumer group 下。
publish-subscribe模式:所有的consumer都有着自己唯一的consumer group。

上图说明:由2个broker组成的kafka集群,总共有4个partition(P0-P3)。这个集群由2个Consumer Group, A有2个 consumer instances ,B有四个。
通常一个topic会有几个consumer group,每个consumer group都是一个逻辑上的订阅者( logical
subscriber )。每个consumer group由多个consumer instance组成,从而达到可扩展和容灾的功能。

一个partition同一个时刻在一个consumer group中只有一个consumer instance在消费,从而保证顺序。 consumer group中的consumer instance的数量不能比一个Topic中的partition的数量多,否则,多出来的 consumer消费不到消息。

Kafka可以很好的保证有序性

传统的队列在服务器上保存有序的消息,如果多个consumers同时从这个服务器消费消息,服务器就会以消息存储的顺序向consumer分发消息。虽然服务器按顺序发布消息,但是消息是被异步的分发到各consumer上,所以当消息到达时可能已经失去了原来的顺序,这意味着并发消费将导致顺序错乱。为了避免故障,这样的消息系统通常使用“专用consumer”的概念,其实就是只允许一个消费者消费消息,当然这就意味着失去了并发性。

在这方面Kafka做的更好,通过分区的概念,Kafka可以在多个consumer组并发的情况下提供较好的有序性和负载均衡。将每个分区分只分发给一个consumer组,这样一个分区就只被这个组的一个consumer消费,就可以顺序的消费这个分区的消息。因为有多个分区,依然可以在多个consumer组之间进行负载均衡。注意consumer组的数量不能多于分区的数量,也就是有多少分区就允许多少并发消费。

Kafka只能保证一个分区之内消息的有序性,在不同的分区之间是不可以的,这已经可以满足大部分应用的需求。如果需要topic中所有消息的有序性,那就只能让这个topic只有一个分区,当然也就只有一个consumer组消费它。

1.2 kafka的应用场景

  1. 日志收集:一个公司可以用Kafka可以收集各种服务的log,通过kafka以统一接口服务的方式开放给各种consumer,例如hadoop、Hbase、Solr等。
  2. 消息系统:解耦和生产者和消费者、缓存消息等。
  3. 用户活动跟踪:Kafka经常被用来记录web用户或者app用户的各种活动,如浏览网页、搜索、点击等活动,这些活动信息被各个服务器发布到kafka的topic中,然后订阅者通过订阅这些topic来做实时的监控分析,或者装载到hadoop、数据仓库中做离线分析和挖掘。
  4. 运营指标:Kafka也经常用来记录运营监控数据。包括收集各种分布式应用的数据,生产各种操作的集中反馈,比如报警和报告。
  5. 流式处理:比如spark streaming和storm
  6. 事件源

1.3 kafka的特性

  1. 高吞吐量、低延迟:kafka每秒可以处理几十万条消息,它的延迟最低只有几毫秒,每个topic可以分多个partition, consumer group 对partition进行consume操作。
  2. 可扩展性:kafka集群支持热扩展
  3. 持久性、可靠性:消息被持久化到本地磁盘,并且支持数据备份防止数据丢失
  4. 容错性:允许集群中节点失败(若副本数量为n,则允许n-1个节点失败)
  5. 高并发:支持数千个客户端同时读写

2 安装

在正式安装kafka之前,一定要保证计算机的Java环境和zookeeper已经安装

2.1 java安装

之前有过介绍,注意需要安装java 1.8及以上版本,可以参考链接

2.2 zookeeper的安装

现在的kafka都自带了zookeeper,如果本地调试使用直接用自带的就可以了(kafka自带的zookeeper搭建集群),但是如果需要建集群还是单独搭建zookeeper的比较好,如果选择使用自带的可以跳过下面步骤

  1. 下载
    官网中下载zookeeper-3.4.13.tar
    tar -zxvf zookeeper-3.4.13.tar
    cd zookeeper-3.4.13/conf
    mv zoo_sample.cfg zoo.cfg //更改默认配置文件名称

  2. 启动Server
    cd zookeeper-3.4.13/bin
    ./zkServer.sh start //启动

2.3 安装kafka

  1. 官网下载kafka:
    https://www.apache.org/dyn/closer.cgi?path=/kafka/2.5.0/kafka_2.12-2.5.0.tgz

  2. 启动zookeeper的服务

    bin/zookeeper-server-start.sh config/zookeeper.properties
    
  3. 启动kafka的服务
    另起一个窗口,进入解压目录,输入:

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

到这里,kafka应该基本上就安装完成了

我最开始的时候尝试过使用brew install kafka语句来安装kafka,结果一直报错,最终就用了直接在官网上下载的方法,目前看上去这种方法是非常简单快捷的


参考文献:
Kafka史上最详细原理总结上 孤街酒客H
Kafka学习之路(一)Kafka的简介
kafka的基本概念介绍

1000

GS

北京 | php攻城狮

创作 35 粉丝 2

fighting