首页 > 其他分享 >大数据经典论文解读 - Kafka - 流批一体架构

大数据经典论文解读 - Kafka - 流批一体架构

时间:2023-04-09 21:57:15浏览次数:44  
标签:架构 Consumer Broker kafka 流批 日志 Kafka 数据

Kafka

  • 大数据系统架构是什么样?为什么需要Kafka这样的桥梁作为连接?
  • Kafka的系统设计与传统MQ有什么不同?
  • 如何实现分布式?如何动态添加 Broker并通知上下游?
  • 有了 Kafka 和 Storm 后如何搭建流式处理系统?如何处理故障带来地数据不准确?

Realtime Data Processing at Facebook 从应用层看大数据如何设计,不只考虑内部架构,还考虑外部使用者

Questioning the Lambda Architecture 关于Lambda架构思考

日志收集器

大数据的来源通常是业务系统产生的日志,最早用于广告和搜索业务。最早还不是流式处理,而是使用MapReduce进行处理。

早期可以通过将日志落地到服务器硬盘,定时分割新文件,使用cronjob定时上传到HDFS上。这样操作简单,但是数据上传前系统没有灾备,机器故障会导致日志丢失。如果不写入本地而是直接向HDFS写入,会导致负载过大。而且多个应用服务器是写入一个文件还是多个文件呢?如果写入一个文件,多个客户端在写入同一个文件时会在主副本上排队,引发竞争。如果写入多个文件,每个时间段产生日志文件数等于发起请求的机器数,会导致大量小文件,不利于存储和计算。

日志收集器 Scribe 和 Flume 就负责从各个应用服务器上收集日志,汇总到一个日志汇集(Log Aggregator)服务器中。多层嵌套可形成一个树状结构,最终只有几个日志汇集服务器向HDFS写入数据。此时不会有太多并发写,也能发挥HDFS顺序写的高吞吐优势。其不是实时上传,而是按照指定时间间隔上传。这样每分钟上传一次日志到HDFS,就可以每分钟运行一次MapReduce进行分析反馈

收集日志定时上传的做法有些问题:

  1. 隐式依赖:要分析最近5分钟的点击数据,那么要在HDFS上通过文件名分辨出
  2. 容错问题:为预防网络和硬件故障,在日志收集器每次上传数据时查看是否有上传一半的数据

所以需要一个MQ用于配合流式计算

Kafka 系统架构

kafka接受应用服务器发送的日志,下游可以对接HDFS或Storm之类的流式计算系统。此时kafka变成分布式MQ,典型的生产者消费者模型。

  • Producer:日志生产者,如应用服务器
  • Broker:实际Kafka的服务进程,为了容错和高可用,kafka是分布式的,每台服务器都有对应的Broker进程。所有的消息进行两种类型的分组
    • 业务分组:对应Topic概念。如将广告日志、搜索日志分开,两类的格式和用途都不同
    • 数据分区:对应Partition,实现分布式的高性能和高可用
      • 同一Topic日志平均分配到多台机器,确保并行处理,有助于水平拓展系统的处理能力
      • 实现容错,某个Broker出现故障,上游的Producer可将日志发送到其他Broker,确保系统仍能正常运作
  • Consumer:处理日志的。kafka支持多消费者
    • 一条消息可能不同程序都要读取,如上传到HDFS和Storm进行处理
    • 同一用途程序可能有多个并行消费者确保吞吐量

为区分不同的消费者,kafka将用途相同的程序称为一个Cousumer Group。

这视乎和一般MQ没区别

拉数据而不是推

原有的主动推送数据到下游的方案有个缺陷:MQ要维护下游是否成功处理消息的状态。传统MQ通过一个 message-id 唯一标识一条消息,当下游所有订阅者消费后才从内存删除。这也意味着下游处理完成前要一直存储着这些信息。

Kafka 采用不同思路:

  1. 所有Consumer来拉取数据,Consumer消费了哪些数据又其自己维护,kafka无需维护
  2. 采用简单的追加文件写的方式作为消息队列,kafka中没有唯一的message-id,也没有负责的数据结构。下游消费者只要维护此时处理到的日志在日志文件中的偏移量(offset)即可

此外还有些限制,一个consumer总是顺序地消费来自一个特定分区(Partition)的消息,一个Partiton是kafka里并行处理的最小单位。也就是一个Partition的数据只会被一个consumer处理

Producer的生成消息和Consumer的消费消息都变成了简单的顺序的文件读写

单个 Partition 的读写实现

每个Topic会有多个Partition分布到不同的机器,一个机器可能又多个Partition,一个Partition是一个逻辑上的日志文件。Partition日志文件通过实现成一组大小基本相同的Segment文件,如1GB大小。每当有新消息发来时,Broker将消息追加到最后那个Segment文件。考虑到性能,可自定义将文件刷新到硬盘的条件。

Broker维护一个简单索引,就是通过一个虚拟偏移量,指向一个具体的Segment文件。那么Consumer要消费数据时根据本地维护的已处理完成偏移量在索引中查找Segment文件再读取。

优秀的 Linux 文件系统

kafka使用本地文件系统承担MQ持久化功能,没有自己实现缓存,而是使用了Linux页缓存(Page Cache)。Kafka写的数据都在Page Cache,且因为流式计算时读写都有很强的时间局部性,Broker刚写入就会被读取,所以大量数据都会命中缓存。kafka使用 mmap 写数据。

同时避免了两个内存缓存的问题:

  1. JVM的GC开销
  2. 缓存冷启动问题。Broker挂掉重启,此时内存没有任何数据,这时读取数据性能比已长时间运行、内存缓存了很多数据的系统性能差很多

这2点会导致系统性能抖动,直接使用Page Cache使得在JVM内除了业务代码没有其他开销

除了利用文件系统,kafka 还用了 sendfile API,通过DMA直接将数据传到网络,省去了从内核态到用户态再到内核态的复制。

小结

kafka比日志收集器和一般MQ好是因为对业务需求假设不同:

  • Kafka假设处理海量日志,可容忍丢失,更注重系统整体的吞吐量、可拓展性、错误恢复能力。
  • 传统MQ关注小数据量下是否每条消息都被业务系统处理完成,比如业务交易,每条都要确认,但整体吞吐量不大
  • 日志收集器关系的是日志收集,不考虑高吞吐传输日志和下游的处理

kafka考虑:实时传输数据 + 实时处理数据

kafka在设计时,不仅简单地只从系统内部思考设计,还考虑全链路地数据流程有哪些需求

分布式实现

Kafka没有master节点,使用zookeeper。没启动一个Broker就注册到 ZooKeeper 上,注册信息是Broker的主机名和端口。还记录Topic和Partition。zookeeper类似Chubby,都是分布式锁。每个Kafka的Broker将自己信息像一个文件样写在一个zookeeper目录下。

此外zookeeper还提供了一个监听-通知机制。Producer只要监听Brokers目录就知道有哪些Broker,Producer也可不关心zookeeper,而是直接发送给负载均衡。

高可用机制

0.8版本后支持了多副本的高可用:

  1. 每个分区都有多个副本,类似GFS默认3个
  2. 副本中有一个leader,其余为 follower。Producer只要写入leader,leader将数据同步到本地日志文件
  3. 每个follower都从leader拉取最新数据,一旦拉到后就像leader发送ACK
  4. 可自定义多少个follower成功拉取后Producer才写入成功,通过在发送消息里指定acks字段决定,为0无需写入磁盘就算成功,为2则需要1个leader和1个follower都写入磁盘才算成功。acks参数可调节可用性和性能

负载均衡机制

消费数据的逻辑较复杂,主要因为动态增减Broker和Consumer。Consumer一样注册到zookeeper上,同一个Consumer Group下一个Partition只会被一个Consumer消费,这个Partition和Consumer的映射关系也被记录到zookeeper里,也被称为“所有权注册表”。

consumer不断处理partition数据,其处理到的offset位置页记录到zookeeper上。这样即使consumer挂掉,其他consumer来接手也知道从哪开始。

一旦Broker或Consumer增减,kafka就做一次“再平衡(Rebalance)”,就是把分区重新按照consumer的数量进行分配,确保下游负载平均。采用平均分配。有X个分区和Y个consumer,kafka算出N=X/Y,然后将0~N-1分区给第一个consumer,N~2N-1给第二个Consumer。因为Offset保存在Zookeeper,新的consumer知道从哪开始。

kafka和storm都是“至少一次”。通过更新zookeeper上offset确认消息处理成功,如果Consumer出现故障,要从上一个offset重新开始处理,这无法避免重复处理消息。如要避免,需在消息体内通过message-id字段和其他去重机制实现。

顺序保障机制

有些限制:

  • kafka很难提供对单条信息的事务。zookeeper上保存的是最新处理完的消息的offset,而不是message-id与是否被消费的状态的映射,所以只能按消息在Partition中偏移量顺序处理
  • 没有严格顺序定义。多个Broker间,后来的消息可能被先处理

对于统计广告点击等场景这都不重要,业务间异步通信适合使用传统的MQ

数据处理 - 流批一体

流式计算还有几个问题:

  1. 只能保障“At Least Once”的数据处理模式,批处理下做到“Exactly Once”。批处理结果是准确的,流式计算结果是有误差的。
  2. 批处理程序容易修改,流式处理程序不容易

重写一个流式计算程序不难,难的是如何不影响线上程序运行情况下进行发布。根据新的需求生成过去30天数据的新报表,此时可以重放过去30天日志数据。如果存在HDFS,需要拉取数据在发送;使用kafka数据都在本地磁盘,仍需重放日志。重放要花费很多时间、或短时间内消耗大量计算资源。

最常发生的变更是解决分析程序中的bug,这时输入数据和输出结构不会变化,但需要反复修改数据处理程序并反复运行。这对批处理压力不大,但对流式计算会有大量重放日子的工作量。

Lambda 架构

先将数据处理流抽象成 View = Query(Data) 这样一个函数。 

  • Master Data:原始日志
  • Query:批处理或流式处理
  • View:基于特定查询的视图

程序有bug只需重写Query,需求有变只要重写View。对于用户只要暴露View即可。这时,可通过Storm进行实时计算尽快获得分析结果;同时定时运行MapReduce程序获得更准确的数据结果。用户看到的是同一个视图,只是先看到的是不精确的结果,后看到修正过的结果。外部用户只要通过SQL直接查询服务层即可。

演变为Twitter的SummingBird

Kappa 架构

Lambda架构的缺点:什么都要两遍

  1. 所有视图在实时计算层计算一次,在批处理层计算一次。即使没有修改程序也要付出双倍计算资源
  2. 批处理和流处理底层框架不同,代码要两套,要双倍开发资源

通过日志收集器收集日志落地到HDFS上,一但想重放日志,就要把日志从HDFS分片拉到不同服务器,再搭建日志收集器集群重放日志。

有了kafka后重放日志简单了,因为所有日志都在kafka集群本地硬盘上。重放日志也就是重置offset。

Kappa 架构去掉了 Lambda 架构的批处理层,再实时处理层支持了多个视图版本。如果要对Query修改,先多部署一个新版本的代码,对其进行日志重放,在服务层生成新的视图结果。日志重放完成前,外部用户查询仍得到旧程序产生结果,一旦新程序赶上进度就停止旧版本的实时处理层代码。

Kappa架构提出后大数据进入“流批一体”阶段

小结

kafka 没有 master,Broker也不维持状态。Broker 的状态信息和 Consumer 处理数据的偏移offset都记录在zookeeper上。

数据分区平均顺序分配给Consumer,通过ZooKeeper里的“所有权注册表”记录下来。

Lambda 将数据处理流程分为批处理层、实时处理层、服务层,抽象为 View=Query(Data)

Kappa 架构利用kafka把日志放在Broker本地硬盘特性,提出放弃批处理转而提供多版本实时处理层程序。这也是之后大数据技术的进化方向

标签:架构,Consumer,Broker,kafka,流批,日志,Kafka,数据
From: https://www.cnblogs.com/zhh567/p/17301143.html

相关文章

  • K8S架构原理详解
    Kubernetes是什么,为什么上手这么难? Kubernetes是一个基于容器技术的分布式集群管理系统。它是谷歌在大规模应用容器技术方面数十年经验的实际成果。因此,支持大规模的集群管理承载着非常多的组件,分布式本身的复杂度非常高。 Kubernetes到底有什么? 接下来我们一步步来看看K......
  • kafka怎么实现高可用性
    Kafka是一个分布式的消息系统,为了保证高可用性,需要采取以下措施:集群架构:Kafka通过分布式的方式来实现高可用性。一个Kafka集群通常包含多个Broker,每个Broker负责存储一部分的数据副本,这样即使某个Broker出现故障,其他Broker也可以继续工作。数据冗余:Kafka通过数......
  • Taro架构构析(1):多端框架分析,Taro WePY uni-app对比
    多端框架分类全包型这类框架最大的特点就是从底层的渲染引擎、布局引擎,到中层的DSL,再到上层的框架全部由自己开发,代表框架是 Qt和Flutter。这类框架优点非常明显:性能(的上限)高;各平台渲染结果一致。缺点也非常明显:需要完全重新学习DSL(QML/Dart),以及难以适配中国特色的端:小程序......
  • Weex原理及架构剖析
    早期H5和Hybrid方案的本质是,利用客户端App的内置浏览器(也就是webview)功能,通过开发前端的H5页面满足跨平台需求。比如PhoneGapcordovaionic……该方案提升开发效率,同时也满足了跨端的需求。但有一个问题就是,前端H5的性能和客户端的性能相差甚远。Facebook推出ReactNative关于......
  • Docker架构
    概念理解镜像(image):Docker将应用程序及其所需的依赖、函数库、环境、配置等文件打包在一起,称为镜像。容器(Container):镜像中的应用程序运行后形成的进程就是容器,只是Docker会给容器做隔离,对外不可见。架构Docker是一个CS架构的程序,由两部分组成:服务端(server):Docker守护......
  • ReactJS到React-Native,架构原理概述
    React是一个纯JS的UI库,只能干HTML/CSS/JS提供的Web服务(新的H5API不一定支持), React-Native厉害在于它能打通JS和NativeCode,让JS能够调用丰富的原生接口,充分发挥硬件的能力,实现非常复杂的效果,同时能保证效率和跨平台性。在一定程度上,ReactNative和NodeJS有异曲同工之妙......
  • 云计算的三种模式IaaS/PaaS/SaaS/BaaS对比:SaaS架构设计分析
    SaaS——软件即服务(SoftwareasaService)的出现改变了传统使用软件转变为使用服务。SaaS与传统软件的最大区别是,前者按年付费租用服务,后者一次买断。这貌似只是“报价方式”的区别,实际上这是一个根本性的变化,这带来的是对服务模式、销售模式、公司价值等多维度的根本影响。传......
  • internet域名架构的实现
    环境根域:192.168.3.109com服务器:192.168.3.110hxg.com服务器主:192.168.3.108​ 从:192.168.3.107apache主机(www.hxg.com):192.168.3.104转发服务器:192.168.3.101本地DNS服务器:192.168.3.102测试客户端:192.168.3.103配置www.hxg.com主机安装apache$y......
  • [MAUI 项目实战] 手势控制音乐播放器(一): 概述与架构
    这是一篇系列博文。请关注我,学习更多.NETMAUI开发知识![MAUI项目实战]手势控制音乐播放器(一):概述与架构[MAUI项目实战]手势控制音乐播放器(二):手势交互[MAUI项目实战]手势控制音乐播放器(三):动画[MAUI项目实战]手势控制音乐播放器(四):圆形进度条在之前的博文中提到这个......
  • js异步——浅谈Chrome浏览器架构
    前言在讲述事件循环和消息队列之前,需要了解JS的单线程执行机制,JS的执行是从上到下依次执行的,这些便是同步任务,而异步操作类似于系统中断,即当前进程外部的实体(主线程之外的、宿主环境提供的、特殊的线程,如IO线程(HTTP请求)和定时器线程等)可以触发代码执行,然后在异步任务完毕后,执......