kafka

【redis】

  1. Redis高性能:线程模型、数据结构、网络框架

  2. Redis 高可靠:主从复制、哨兵机制、持久化机制

  3. Redis 应用:分布式锁、缓存 【kafka】

  4. kafka架构

  5. Kafka高可靠:副本机制、数据一致性

  6. Kafka高性能原因

kafka

kafka架构

概念kafka是一个分布式、分区的、多副本的、多生产者、多订阅者,基于zookeeper协调的分布式日志系统。,常见可以用于web/nginx日志、访问日志,消息服务等等。

主要应用场景是:日志收集系统和消息系统。

kafka主要设计如下:

  1. 以时间复杂度o(1)的方式提供消息持久化能力,及时对TB级以上数据也能保证常数时间的访问性能。

  2. 高吞吐率。即使在非常廉价的商用机器上也能做到单机支持每秒100k条消息的传输。

  3. 支持kafka server 间的消息分区及分布式消费,同事保证每个partition内消息顺序传输

  4. 同时支持离线数据处理和实时数据处理。

  5. 支持在线水平扩展

 

Producer:生产者,负责将客户端生产的消息发送到 Kafka 中,可以支持消息的异步发送和批量发送; broker:服务代理节点,Kafka 集群中的一台服务器就是一个 broker,可以水平无限扩展,同一个 Topic 的消息可以分布在多个 broker 中; Consumer:消费者,通过连接到 Kafka 上来接收消息,用于相应的业务逻辑处理。 ZooKeeper:注册中间件 Consumer Group:消费者组,指的是多个消费者共同组成一个组来消费一个 Topic 中的消息。

有两种主要的消息传递模式:点对点传递模式、发布-订阅模式。⼤部分的消息系统选⽤发布-订阅模式。Kafka就 是⼀种发布-订阅模式。 对于消息中间件,消息分推拉两种模式。Kafka只有消息的拉取,没有推送,可以通过轮询实现消息的推送。

  1. Kafka在⼀个或多个可以跨越多个数据中⼼的服务器上作为集群运⾏。

  2. Kafka集群中按照主题分类管理,⼀个主题可以有多个分区,⼀个分区可以有多个副本分区。

  3. 每个记录由⼀个键,⼀个值和⼀个时间戳组成。 Kafka具有四个核⼼API:

  4. Producer API:允许应⽤程序将记录流发布到⼀个或多个Kafka主题。

  5. Consumer API:允许应⽤程序订阅⼀个或多个主题并处理为其⽣成的记录流。

  6. Streams API:允许应⽤程序充当流处理器,使⽤⼀个或多个主题的输⼊流,并⽣成⼀个或多个输出主题的 输出流,从⽽有效地将输⼊流转换为输出流。

  7. Connector API:允许构建和运⾏将Kafka主题连接到现有应⽤程序或数据系统的可重⽤⽣产者或使⽤者。例 如,关系数据库的连接器可能会捕获对表的所有更改。

Kafka优势

  1. ⾼吞吐量:单机每秒处理⼏⼗上百万的消息量。即使存储了许多TB的消息,它也保持稳定的性能。

  2. ⾼性能:单节点⽀持上千个客户端,并保证零停机和零数据丢失。

  3. 持久化数据存储:将消息持久化到磁盘。通过将数据持久化到硬盘以及replication防⽌数据丢失。

  4. 零拷⻉

  5. 顺序读,顺序写

  6. 利⽤Linux的⻚缓存

  7. 分布式系统,易于向外扩展。所有的Producer、Broker和Consumer都会有多个,均为分布式的。⽆需停机 即可扩展机器。多个Producer、Consumer可能是不同的应⽤。

  8. 可靠性 - Kafka是分布式,分区,复制和容错的。

  9. 客户端状态维护:消息被处理的状态是在Consumer端维护,⽽不是由server端维护。当失败时能⾃动平 衡。

  10. ⽀持online和offline的场景。

  11. ⽀持多种客户端语⾔。Kafka⽀持Java、.NET、PHP、Python等多种语⾔。

Kafka应⽤场景

⽇志收集:⼀个公司可以⽤Kafka可以收集各种服务的Log,通过Kafka以统⼀接⼝服务的⽅式开放给各种Consumer; 消息系统:解耦⽣产者和消费者、缓存消息等; ⽤户活动跟踪:Kafka经常被⽤来记录Web⽤户或者App⽤户的各种活动,如浏览⽹⻚、搜索、点击等活动,这些活动信息被各个服务器发布到Kafka的Topic中,然后消费者通过订阅这些Topic来做实时的监控分析,亦可保存到数据库; 运营指标:Kafka也经常⽤来记录运营监控数据。包括收集各种分布式应⽤的数据,⽣产各种操作的集中反馈,⽐如报警和报告;

流式处理:⽐如Spark Streaming和Storm。

基本架构

消息和批次

Kafka的数据单元称为消息。可以把消息看成是数据库⾥的⼀个“数据⾏”或⼀条“记录”。消息由字节数组组成。 消息有键,键也是⼀个字节数组。当消息以⼀种可控的⽅式写⼊不同的分区时,会⽤到键。 为了提⾼效率,消息被分批写⼊Kafka。批次就是⼀组消息,这些消息属于同⼀个主题和分区。 把消息分成批次可以减少⽹络开销。批次越⼤,单位时间内处理的消息就越多,单个消息的传输时间就越⻓。批 次数据会被压缩,这样可以提升数据的传输和存储能⼒,但是需要更多的计算处理。

模式

消息模式(schema)有许多可⽤的选项,以便于理解。如JSON和XML,但是它们缺乏强类型处理能⼒。Kafka的 许多开发者喜欢使⽤Apache Avro。Avro提供了⼀种紧凑的序列化格式,模式和消息体分开。当模式发⽣变化时,不 需要重新⽣成代码,它还⽀持强类型和模式进化,其版本既向前兼容,也向后兼容。 数据格式的⼀致性对Kafka很重要,因为它消除了消息读写操作之间的耦合性。

主题和分区

Kafka的消息通过主题进⾏分类。主题可⽐是数据库的表或者⽂件系统⾥的⽂件夹。主题可以被分为若⼲分区,⼀ 个主题通过分区分布于Kafka集群中,提供了横向扩展的能⼒。

⽣产者和消费者

⽣产者创建消息。消费者消费消息。 ⼀个消息被发布到⼀个特定的主题上。 ⽣产者在默认情况下把消息均衡地分布到主题的所有分区上:

  1. 直接指定消息的分区

  2. 根据消息的key散列取模得出分区

  3. 轮询指定分区。 消费者通过偏移量来区分已经读过的消息,从⽽消费消息。 消费者是消费组的⼀部分。消费组保证每个分区只能被⼀个消费者使⽤,避免重复消费。 broker和集群 ⼀个独⽴的Kafka服务器称为broker。broker接收来⾃⽣产者的消息,为消息设置偏移量,并提交消息到磁盘保 存。broker为消费者提供服务,对读取分区的请求做出响应,返回已经提交到磁盘上的消息。单个broker可以轻松处 理数千个分区以及每秒百万级的消息量。 每个集群都有⼀个broker是集群控制器(⾃动从集群的活跃成员中选举出来)。 控制器负责管理⼯作: 将分区分配给broker 监控broker 集群中⼀个分区属于⼀个broker,该broker称为分区⾸领。 ⼀个分区可以分配给多个broker,此时会发⽣分区复制。 分区的复制提供了消息冗余,⾼可⽤。副本分区不负责处理消息的读写。

Kafka高可靠:副本机制、数据一致性

下面从以下几个角度来介绍kafka如何保证数据的可靠性。

Producter 往 Broker 发送消息 Topic 分区副本 Leader 选举

  1. Producer 往 Broker 发送消息

    ack机制:Kafka 在 Producer 里面提供了消息确认机制。也就是说我们可以通过配置来决定有几个副本收到这条消息才算消息发送成功。

定义 Producer 时通过 acks 参数指定(在 0.8.2.X 版本之前是通过 request.required.acks 参数设置的。

acks=0:生产者不会等待任何来自服务器的响应。 很明显,生产者对服务器无感,最易造成数据丢失。 acks=1(默认值):只要集群的Leader节点收到消息,生产者就会收到一个来自服务器的成功响应。 leader接受到消息后,响应生产者后,数据还未同步到其他follower,leader宕掉了,重新选举出新的leader,那么就会导致该条消息丢失。 acks=-1:只有当所有参与复制的节点全部都收到消息时,生产者才会收到一个来自服务器的成功响应。 这种模式是最安全的,可以保证不止一个服务器收到消息,就算有服务器发生崩溃,整个集群依然可以运行 。延时比acks=1更高,因为要等待不止一个服务器节点接收消息。 另外:Producer 发送消息还可以选择同步(默认,通过 producer.type=sync 配置) 或者异步(producer.type=async)模式。如果设置成异步,虽然会极大的提高消息发送的性能,但是这样会增加丢失数据的风险。如果需要确保消息的可靠性,必须将 producer.type 设置为 sync。

  1. Topic 分区副本 (数据的冗余备份)

    在 Kafka 0.8.0 之前,Kafka 是没有副本的概念的,那时候人们只会用 Kafka 存储一些不重要的数据,因为没有副本,数据很可能会丢失。为了保证数据的可靠性,Kafka 从 0.8.0 版本开始引入了分区副本。

每个分区可以人为的配置几个副本(比如创建主题的时候指定 replication-factor,也可以在 Broker 级别进行配置 default.replication.factor),一般会设置为3。

Kafka 可以保证单个分区里的事件是有序的,分区可以在线(可用),也可以离线(不可用)。在众多的分区副本里面有一个副本是 Leader,其余的副本是 follower,所有的读写操作都是经过 Leader 进行的,同时 follower 会定期地去 leader 上复制数据。当 Leader 挂掉之后,其中一个 follower 会重新成为新的 Leader。通过分区副本,引入了数据冗余,同时也提供了 Kafka 的数据可靠性。

Kafka 的分区多副本架构是 Kafka 可靠性保证的核心,把消息写入多个副本可以使 Kafka 在发生崩溃时仍能保证消息的持久性。

  1. Leader选举(选取ISR表中follower)

    在介绍 Leader 选举之前,让我们先来了解一下 ISR(in-sync replicas)列表。每个分区的 leader 会维护一个 ISR 列表,ISR 列表里面就是 follower 副本的 Borker 编号,只有“跟得上” Leader 的 follower 副本才能加入到 ISR 里面,这个是通过 replica.lag.time.max.ms 参数配置的。只有 ISR 里的成员才有被选为 leader 的可能。

所以当 Leader 挂掉了,而且 unclean.leader.election.enable=false 的情况下,Kafka 会从 ISR 列表中选择第一个 follower 作为新的 Leader,因为这个分区拥有最新的已经 committed 的消息。通过这个可以保证已经 committed 的消息的数据可靠性。

因此,为了保证数据的可靠性,我们最少需要配置一下几个参数:

producer 级别:acks=all(或者 request.required.acks=-1),同时发生模式为同步 producer.type=sync topic 级别:设置 replication.factor>=3,并且 min.insync.replicas>=2; broker 级别:关闭不完全的 Leader 选举,即 unclean.leader.election.enable=false; 即 ack机制设置为所有follower均收到消息才响应;(producer)发生模式设置为同步; 副本数设置大于等于3,最小同步数设置为2;关闭不完全的Leader选举。

数据一致性(木桶原理)

kafka是通过HW(High Water Mark) 机制来保证数据的一致性。

 

(1)follower故障

follower发生故障后会被临时踢出ISR,待该follower恢复后,follower会读取本地磁盘记录的上次的HW,并将log文件高于HW的部分截取掉,从HW开始向leader进行同步。等该follower的LEO大于等于该Partition的HW,即follower追上leader之后,就可以重新加入ISR了。

(2)leader故障

leader发生故障之后,会从ISR中选出一个新的leader,之后,为保证多个副本之间的数据一致性,其余的follower会先将各自的log文件高于HW的部分截掉,然后从新的leader同步数据。

Exactly Once语义

对于某些比较重要的消息,我们需要保证exactly once语义,即保证每条消息被发送且仅被发送一次。

idempotent + at least once = exactly once

在0.11版本之后,Kafka引入了幂等性机制(idempotent),配合acks = -1时的at least once语义,实现了producer到broker的exactly once语义。

idempotent + at least once = exactly once 1 使用时,只需将enable.idempotence属性设置为true,kafka自动将acks属性设为-1。

原文链接:kafka基础学习(五):kafka如何保证数据可靠性和数据一致性_F道人的博客-CSDN博客_kafka数据一致性原理

Kafka高性能原因

分区

生产者往Kafka发送消息时必须指定发往哪个主题,消费者需要订阅某个主题才能进行消费。一个主题下的分区可以分布在集群的不同broker上面,也就是说,一个主题可以横跨多个broker。这样的话,生产者在指定主题(可以指定也可以不指定分区)发送消息的时候,Kafka会将消息分发至不同的分区,如果这些分区不在同一个broker上,就相当于并发的写入多台broker,性能自然要比写入单台broker要高。对于消费者,Kafka引入了消费组(Consumer Group)的概念,每个消费者都有一个对应的消费组。一个分区只能被一个消费组中的一个消费者消费,但是可以被不同消费组中的另一个消费者消费。可以在一个消费组里起多个消费者,每个消费者消费一个分区,这样就提高了消费者的性能。需要注意的是,消费组里的消费者个数如果多于分区数的话,那些多出来的消费者就会处于空闲状态,所以一个消费组里的消费者个数跟分区数相等就好了。下图展示了消费者组与分区的关系。

 

分区的设计使得Kafka消息的读写性能可以突破单台broker的I/O性能瓶颈,可以在创建主题的时候指定分区数,也可以在主题创建完成之后去修改分区数,通过增加分区数可以实现水平扩展,但是要注意,分区数也不是越多越好,一般达到某一个阈值之后,再增加分区数性能反而会下降,具体阈值需要对Kafka集群进行压测才能确定。

日志分段存储

为了防止日志(Log)过大,Kafka引入了日志分段(LogSegment)的概念,将日志切分成多个日志分段。在磁盘上,日志是一个目录,每个日志分段对应于日志目录下的日志文件、偏移量索引文件、时间戳索引文件(可能还有其他文件)。 ??向日志中追加消息是顺序写入的,只有最后一个日志分段才能执行写入操作,之前所有的日志分段都不能写入数据。 ??为了便于检索,每个日志分段都有两个索引文件:偏移量索引文件和时间戳索引文件。每个日志分段都有一个基准偏移量baseOffset,用来表示当前日志分段中第一条消息的offset。偏移量索引文件和时间戳索引文件是以稀疏索引的方式构造的,偏移量索引文件中的偏移量和时间戳索引文件中的时间戳都是严格单调递增的。查询指定偏移量(或时间戳)时,使用二分查找快速定位到偏移量(或时间戳)的位置。可见Kafka中对消息的查找速度还是非常快的。

消息顺序追加

Kafka是通过文件追加的方式来写入消息的,只能在日志文件的最后追加新的消息,并且不允许修改已经写入的消息,这种方式就是顺序写磁盘,而顺序写磁盘的速度是非常快的。

页缓存

页缓存是操作系统实现的一种主要的磁盘缓存,以此用来减少对磁盘I/O的操作。具体来说,就是把磁盘中的数据缓存到内存中,把对磁盘的访问变为对内存的访问。 Kafka中大量使用了页缓存,消息都是先被写入页缓存,再由操作系统负责具体的刷盘任务(Kafka中也提供了同步刷盘和间断性强制算盘的功能)。

零拷贝

零拷贝技术是一种避免CPU将数据从一块存储拷贝到另一块存储的技术。Kafka使用零拷贝技术将数据直接从磁盘复制到网卡设备缓冲区中,而不需要经过应用程序的转发。 ??通常应用程序将磁盘上的数据传送至网卡需要经过4步:

  1. 调用read(),将数据从磁盘复制到内核模式的缓冲区;

  1. CPU会将数据从内核模式复制到用户模式下的缓冲区;

  2. 调用write(),将数据从用户模式下复制到内核模式下的Socket缓冲区;

  3. 将数据从内核模式的Socket缓冲区复制到网卡设备。

    上面的步骤中,第2、3步将数据从内核模式经过用户模式再绕回内核模式,浪费了两次复制过程。采用零拷贝技术,Kafka可以直接请求内核把磁盘中的数据复制到Socket缓冲区,而不用再经过用户模式。

原文链接:Kafka高性能原因 | 码农家园

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值