消息中间件 - 2.消息中间件Kafka架构简介

kafka简介

Apache Kafka 是一款开源的消息引擎系统,同时也是一个分布式流处理平台(Distributed Streaming Platform)。

  • 消息系统:Kafka 和传统的消息系统(也称作消息中间件)都具备系统解耦、冗余存储、流量削峰、缓冲、异步通信、扩展性、可恢复性等功能。与此同时,Kafka 还提供了大多数消息系统难以实现的消息顺序性保障及回溯消费的功能。
  • 存储系统:Kafka 把消息持久化到磁盘,相比于其他基于内存存储的系统而言,有效地降低了数据丢失的风险。也正是得益于Kafka 的消息持久化功能和多副本机制,我们可以把Kafka作为长期的数据存储系统来使用,只需要把对应的数据保留策略设置为“永久”或启用主题的日志压缩功能即可。
  • 流式处理平台:Kafka 不仅为每个流行的流式处理框架提供了可靠的数据来源,还提供了一个完整的流式处理类库,比如窗口、连接、变换和聚合等各类操作。

Kafka相关术语

  • 主题(Topic):主题是承载消息的逻辑容器,在实际使用中多用来区分具体的业务。
  • 分区(Partition):一个有序不变的消息序列。每个主题下可以有多个分区。
  • 消息位移(Offset):表示分区中每条消息的位置信息,是一个单调递增且不变的值。
  • 副本(Replica):Kafka 中同一条消息能够被拷贝到多个地方以提供数据冗余,这些地方就是所谓的副本。副本还分为领导者副本和追随者副本,各自有不同的角色划分。副本是在分区层级下的,即每个分区可配置多个副本实现高可用。
  • 服务代理节点(Broker):Broker可以简单地看作一个独立的Kafka服务节点或Kafka服务实例。一个或多个Broker组成了一个Kafka集群。
    在这里插入图片描述
  • 生产者(Producer):生产者,也就是发送消息的一方。生产者负责创建消息,然后将其投递到Kafka中。
  • 消费者(Consumer):消费者,也就是接收消息的一方。消费者连接到Kafka上并接收消息,进而进行相应的业务逻辑处理。
  • 消费者位移(Consumer Offset):表征消费者消费进度,每个消费者都有自己的消费者位移。
  • 消费者组(Consumer Group):多个消费者实例共同组成的一个组,同时消费多个分区以实现高吞吐。
  • 重平衡(Rebalance):消费者组内某个消费者实例挂掉后,其他消费者实例自动重新分配订阅主题分区的过程。Rebalance 是 Kafka 消费者端实现高可用的重要手段。
    在这里插入图片描述
  • AR(Assigned Replicas):分区中的所有副本。AR = ISR + OSR
  • ISR(In-Sync Replicas):所有与leader副本保持一定程度同步的副本(包括leader副本在内)。
  • OSR(Out-of-Sync Replicas):与leader副本同步滞后过多的副本(不包括leader副本)组成OSR(Out-of-Sync Replicas)
  • HW(High Watermark):俗称高水位,它标识了一个特定的消息偏移量(offset),消费者只能拉取到这个offset之前的消息。
  • LEO(Log End Offset):它标识当前日志文件中下一条待写入消息的offset。

Kafka整体架构

在这里插入图片描述

Kafka整体运行模式

在这里插入图片描述

线上部署方案

  1. 操作系统的选择
    在 Linux 部署 Kafka 能够享受到零拷贝技术所带来的快速数据传输特性。

  2. 磁盘选择:SSD、机械磁盘、磁盘阵列RAID。
    Kafka对磁盘的读写方式是顺序读写操作,一定程度上规避了机械磁盘最大的劣势,即随机读写操作慢。所以SSD对于Kafka的性能影响并没有想象中的大。

    机械磁盘物美价廉,但其易损坏而造成的可靠性差等缺陷,又由 Kafka 在软件层面提供机制来保证数据的持久化能力,所以使用机械磁盘较划算。

    使用磁盘阵列(RAID)的主要优势在于提供冗余的磁盘存储空间和磁盘的负载均衡。但是Kafka自身已通过分区副本冗余机制以及日志多目录【磁盘故障自动转移】来提供高可靠性,并在一定程度上实现了磁盘的负载均衡机制,所以磁盘阵列的优势在Kafka中并不明显。

    所以追求性价比的以不搭建 RAID,使用普通磁盘组成存储空间即可。另外使用机械磁盘完全能够胜任 Kafka 线上环境。

    此外需要注意的是,Kafka是按分区为单位实现消息的存储。因此如果创建的Topic过多导致在同一台Broker上的分区副本数量过多,就可能导致Kafka无法使用到磁盘顺序写的优势,最终导致性能下降。

  3. 磁盘容量的规划
    Kafka 需要将消息保存磁盘上,消息保存一段时间后会被自动删除。要规划磁盘的容量就需要预估几个关键因素。

    1. 每天的消息数(1亿)
    2. 单条消息的大小(1KB)
    3. 消息压缩比例(0.75)
    4. 预留空间(10%)
    5. 消息保留天数(14天)
    6. 副本数(2)。

    磁盘容量=1亿 * 1KB * 0.75 * 14 * (1+10%) * 2=2.3T

  4. 带宽资源以及服务器节点数量的规划
    对于 Kafka 这种通过网络大量进行数据传输的框架而言,带宽特别容易成为瓶颈。要规划带宽的资源就需要预估几个关键因素。

    1. 每小时待处理的数据量(1TB)
    2. 服务器最大带宽(1Gbps)
    3. 服务器分配给Kafka的带宽资源率(70%)
    4. Kafka处理数据实际可占用的带宽资源利用率(30%)
    5. 副本数(2)。

    节点数=1TB / 1小时 / [(1Gb/8 * 70% * 30%)=26MB] * 2=22台

集群参数关键配置

  1. broker端

    • broker.id:指定Kafka集群中broker的唯一标识,默认值-1。如果没有设置,会自动生成。
      通过配置多个目录挂载到不同的物理磁盘,可以提升Kafka的读写性能,并且在某块磁盘故障时,自动实现故障转移,提升高可用性,这也是kafka存储舍弃磁盘阵列(RAID)方案的基础。
    • listeners:监听器。指明broker监听(内网)客户端连接的地址列表。<协议名称,主机名,端口号>。协议支持:PLAINTEXT、SSL、TLS、自定义。主机名代表一个网卡地址。
    • advertised.listeners:和 listeners 相比多了个 advertised。Advertised 的含义表示宣称的、公布的,即这组监听器是 Broker 用于对外(公网)发布的。

    监听器中的主机名最好全部使用主机名(一般一个主机名会绑定到一个网卡用于集群内部通信),而非IP地址。即 Broker 端和 Client 端应用配置中全部填写主机名。如果IP地址则表示只接受某个网卡发过来的数据。listeners用于内部通信,advertised.listeners用于公网下的通信

    • auto.create.topics.enable:(推荐false)是否允许自动创建 Topic。
    • unclean.leader.election.enable:(推荐false)是否允许 Unclean Leader 选举。所谓Unclean Leader选举就是当所有ISR的副本都出现故障了,是否允许OSR中的副本进行选举。如果设置为true,则可能会使用OSR中的副本选举成为Leader,从而导致数据丢失。当然设置为false在一定程度上会降低高可用性。
    • auto.leader.rebalance.enable:(推荐false)是否允许定期进行 Leader 重选举。Leader 重选举表示kafka在经过一些时间后,满足某些条件时则会触发所有主题中Leader的重新选举,在生产环境下这种Leader冲选举可能并不会产生任何收益,但是却会严重影响性能。
    • log.dir:指定保存日志数据的目录。只能配置单个值。
    • log.dirs:指定保存日志数据的目录,可以配置多个值以‘,’分割。默认不配置使用log.dir的值。
    • log.retention.{hour|minutes|ms}: 消息数据的保留时长。优先级:ms>minutes>hour
    • log.retention.bytes: (默认值-1表示不限制)Broker 为消息保存的总磁盘容量大小。
    • message.max.bytes:(默认的 1000012,不到1MB,可根据消息的大小进行设置,注意批量问题,可设置一个较大的值)控制 Broker 能够接收的最大消息大小。
  2. zookeeper

    • zookeeper.connect:以hostname:port的形式指定ZooKeeper连接字符串,可以配置多个值以‘,’分割。并且可以在最后面增加/chroot/path指定kafka在zk的数据根目录,一般通过此方式让多个kafka集群使用同一个zk集群。
  3. Topic级别(覆盖全局的broker参数)

    • retention.ms:(默认值7天)Topic 消息被保存的时长。
    • retention.bytes:(默认值-1表示不限制)Broker为Topic 消息的保存的总磁盘容量大小。
  4. JVM参数

    • JVM版本:建议使用Java8及以上
    • 堆大小:设置为6GB,通过环境变量KAFKA_HEAP_OPTS指定
    • 垃圾收集器:CPU充裕推荐使用CMS收集器(-XX:+UseCurrentMarkSweepGC),否则使用吞吐量收集器(-XX:+UseParallelGC)。通过环境变量KAFKA_JVM_PERFORMANCE_OPTS指定 GC 参数。
  5. 操作系统参数

    • 文件描述符限制:建议设置为一个超大的值,避免 Too many open files 错误。
    • Swappiness:可以设置为0表示不开启swap空间。但是设置为较小的值,可以在内存耗尽的时候观测到性能急剧下降,在一定程度上避免进程被操作系统的OOM killer立刻杀掉,从而给出一定的缓冲时间进行处理。
    • Page Cache刷盘时间:kafka总是先将消息写入到操作系统的Page Cache缓存中,交由操作真正将页缓存上的数据写入到磁盘,默认刷盘时间是5秒。可以合理提高刷盘的时间间隔,因为kafka自身可以通过多副本的冗余机制确保数据不丢失。

Kafka的高性能

就消息中间件而言,所谓性能一般指的是吞吐量延迟这两个指标。所谓吞吐量即单位时间内可接收请求的最大数量;所谓延迟即每个请求从接受到返回所需要的最大时间。

  1. 集群架构
    Kafka的集群架构具有高扩展性和高可用性。Kafka的Broker可以在多台服务器上运行,并且它们之间可以进行负载均衡。这种架构使得Kafka可以处理大量的数据,同时保证数据的可用性和稳定性。

  2. 顺序写磁盘
    Kafka使用顺序写磁盘来存储和处理消息。与传统的数据库系统不同,Kafka不需要频繁地在磁盘上执行随机读写操作。通过利用磁盘的顺序写入特性,Kafka可以大量减少磁盘IO,提高磁盘利用率,同时还可以减少写操作的延迟。

  3. 页缓存 PageCache
    Kafka 中大量使用了操作系统的页缓存机制,所有的消息首先被写入到页缓存中,由操作系统负责具体的刷盘任务。备注:kafka中消息的可靠性由副本机制来解决而不应该修改kafka中的刷盘机制来解决。

  4. 零拷贝
    Kafka支持使用零拷贝技术来减少内存拷贝和CPU开销。在这种技术下,数据可以在不经过内存拷贝的情况下直接在网络协议栈和文件系统之间进行传输。这样可以大大减少CPU的开销,提高Kafka的性能。

  5. 批量接受和发送
    Kafka使用批量发送来提高性能。在消息发送方面,Kafka支持将多条消息一次性发送到Broker,而非逐条发送。在消息消费方面,Kafka支持将多条消息一次性批量读取,而非逐条读取。这样可以大大减少网络开销和IO操作,提高Kafka吞吐量和性能。

  6. 压缩
    Kafka支持使用压缩技术对消息进行压缩,以减少网络带宽和磁盘存储成本。支持的压缩类型包括Gzip、Snappy和LZ4等。压缩的消息在Broker端解压缩后再进行存储,这样既可以减少磁盘占用,又可以提高Kafka的性能。

综上所述,Kafka在高性能方面的原因主要包括其集群架构、顺序写磁盘、批量发送、零拷贝和压缩等技术实现。这些技术的优化使得Kafka具有高吞吐量、低延迟、高可扩展性和高可靠性等优势。

Kafka为什么不利用分区副本机制支持读写分离

  1. 读写分离的收益点(负载均衡)
    主写从读可以让从节点去分担主节点的负载压力,预防主节点负载过重而从节点却空闲的情况发生。
  2. 读写分离的缺点(数据延迟、不一致)
    数据从主节点转到从节点必然会有一个延时的时间窗口,这个时间窗口会导致主从节点之间的数据不一致。(网络→主节点内存→主节点磁盘→网络→从节点内存→从节点磁盘)
  3. kafka的架构
    kakfa使用多分区的模式,将其部署在多台broker上,从而实现了负载均衡。尽管某些时候可能leader故障切换导致broker的负载不均衡,但是kafka本身提供了分区再均衡以及优先副本选举来达到leader副本的均衡。

因此从读写分离的收益点去分析,kafka本身已经通过分区的机制实现了负载均衡,而不需要引入读写分离。从本质上而言,读写分离也只是由于设计上的缺陷而形成的补充设计或权宜之计。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值