从S4到Storm(一):当分布式遇上实时计算

news2026/3/24 10:21:11
你好我是程序员贵哥。到Spanner为止我们已经把大数据里关于数据存储和在线服务的重要论文解读完了。从这一讲开始我们就要开始讲解另一个重要的主题也就是大数据的流式处理。今天我们解读的第一篇论文来自一个曾经辉煌但是今天已经逐渐销声匿迹的公司Yahoo。这篇论文就是《S4:Distributed Stream Computing Platform》伴随着这篇论文的同样是一个开源系统Apache S4。和同样孵化自Yahoo的Hadoop不同S4虽然是最早发布的开源分布式流式数据处理系统但是在市场上最终却没有占有一席之地。不过学习S4的论文本身还是很有价值的。一方面你可以看到大数据流式处理的基础结构是怎么样的你会发现它和批处理的MapReduce是非常相似的另一方面它又会面临比批处理的MapReduce多得多的挑战和困难。那在学完这一讲之后你能有这样几点收获首先是对于大数据的流式计算问题的基本抽象也就是它在逻辑上应该是一个什么样的模型它想要解决的具体问题是什么。其次是S4这个系统的设计是怎么样的它是如何进行分布式计算的。最后是S4系统的缺陷有哪些以及有哪些问题S4干脆是回避了。这一点对于我们后面去认识Storm、Kafka这些系统的核心价值点非常关键。好了那接下来就请和我一起进入流式计算的世界吧。实时计算到底有多“实时”在MapReduce出现之后整个大数据处理领域就红火了起来Hadoop这样的开源项目也很快深入到各大互联网公司。一方面MapReduce帮我们解决了海量数据处理的问题但是另一方面我们常常又觉得MapReduce不太够用因为很多时候我们希望能够更加“实时”地处理数据。之所以我们希望能够“实时”进行数据处理是由于“效益”的原因。MapReduce一开始的主要的应用领域就是广告和搜索。通过MapReduce程序我们可以分析海量的用户搜索行为、广告点击行为来帮助我们优化搜索排序和广告展示。比如在广告领域最简单的一个优化的办法就是统计新广告的点击率点击率太低的广告我们不予展示把展示机会给别的广告就好了。在论文里Yahoo也举了这样一个例子通过在线统计点击率把低质量的广告过滤掉S4可以帮助他们再提升3%的点击率并且对广告收入没有任何影响。这个需求和我们通过MapReduce生成各种报表是一回事儿。唯一的一个差异在于**我们希望这个数据统计的反馈的时间能够尽量短一些也就是“实时一点”。**而这个差异就触到了MapReduce的痛点了。一般来说我们的MapReduce都是定时执行的比如每天运行一次生成一个报表或者频繁一点每小时运行一次计算上一个小时的点击率数据。但是这个获得反馈数据的频率还是太慢了。每小时运行一次MapReduce程序意味着我们的统计数据平均要晚上半个小时。而半个小时里低质量的广告或者搜索结果已经曝光了很多次了。举个例子现在无论是什么样的社会热点新闻很容易在微博热搜上出现。往往在新闻发生后的一两分钟就已经有大量的搜索出现在微博热搜里了。如果我们要等待半个小时才能统计到这些搜索那么热搜功能就可以说形同虚设了。所以我们希望能在尽可能短的时间内就得到这样的反馈数据。那么你可能要问了我们能不能直接更频繁地运行MapReduce程序呢比如每分钟运行一次是不是就解决这个问题了如果你仔细学习了之前的课程相信你自己也会意识到这样是行不通的。采用频繁运行MapReduce程序的办法我们至少会遇到两个问题。一个是大量的“额外开销”。我们之前讲过MapReduce的额外开销不小再小的任务也需要个十几秒到一分钟的运行时间。如果我们高频率每分钟运行MapReduce任务那么“额外开销”占的时间比重和硬件资源会非常高也很浪费。二个是我们不得不让输入文件变得极其“碎片化”。无论是GFS还是HDFS都是把文件变成一个个64MB大小的Block然后MapReduce通过分布式并行读取来进行快速分析。但是如果我们需要每分钟都处理数据那么对于输入的数据就要按照分钟进行分割。每分钟我们都需要有很多个文件分布到GFS/HDFS上不同的数据节点。这样我们的文件都会变得很小也就丧失了顺序读取大文件的性能优势。其实高频率地执行MapReduce还会有很多问题。而归根到底是这两点第一MapReduce是为“高吞吐量”而设计的一个系统。在整个系统设计理念里它没有考虑“低延时”这个需求。第二MapReduce的数据是一份“边界明确bounded”的数据。在进行数据处理之前要处理的数据已经存放在存储系统上了。而我们想要进行的实时数据统计想要处理的是一份“无边界unbounded”的数据会不断地有新数据流入进来永无停歇。所以我们需要一个全新的流式数据处理系统这也是S4这个系统的出发点。流式计算的逻辑模型我们先来看一看S4是怎么抽象我们的流式计算的。S4把所有的计算过程都变成了一个个处理元素Processing Element对象简称为PE对象。我这里特地加上了对象就是因为在实现上PE就是一个面向对象编程里面一个实际的对象。每一个PE对象都有四部分要素组成分别是PE本身的功能functionality这个体现为PE类里实现的业务逻辑函数以及为了这个类配置的各种参数PE能够处理的事件类型types of eventsPE能够处理的事件的键keyed attributePE处理的事件的键对应的值value。对于流式的数据处理就是由一个个PE组成的有向无环图DAG。有向无环图的起点是一些特殊的被称为无键PEKeyless PE的对象。这些对象的作用其实就是接收外部发送来的事件流这些外部发送过来的事件流其实就是一条条的消息。这些无键PE会解析对应的消息变成一个个事件。然后给每个事件打上三个信息分别是事件类型Event Type事件的Key事件的Value。然后可以把事件给发送出去。接着下游的其他PE对象会根据自己定义的事件类型和能处理的键来接收对应的消息并且处理这个消息。如果当前系统里没有对应的键的PE那么系统会创建一个新的PE对象。处理数据的PE对象可以选择处理完之后立刻发送一个新的事件出去也可以选择在对象内部来维护一个状态然后当处理了一定数量的消息之后或者过了一个固定的事件间隔之后把消息发送出去。最后在整个有向无环图的终点会有一系列的PE对象。这些对象会把最终的计算结果**发布Publish。**这个发布的频率也和其他PE发送消息的逻辑类似可以在每收到一个事件就发送也可以要求接收到一定数量的事件或者每隔一个特定的时间间隔发送。这么来描述可能整个过程有点过于抽象我们还是来一起看一看论文里图一的示例。这个例子是用来统计整个系统里出现得最多的K个单词也就是Top K它的整个DAG的结构是这样的首先在DAG的起始节点是一个QuoteSplitterPE这个PE也是一个无键PE。它负责接收外部发送来的句子然后分割成一个个单词接着会统计单词在句子里面出现的次数。然后这个PE会把每个单词的出现次数作为一个WordEvent发送出去。对应的Event的Key就是Word具体单词的这么一个组合Tuple。而对应的Event的值就是Count出现次数的这么一个组合Tuple。第二层里是一系列叫做WordCountPE的PE对象。它在系统里面申明我只接收WordEvent。然后每个不同的单词都会有一个对应的PE对象。所以可以想象整个系统中会有海量的PE对象。它的逻辑也很简单上游的PE会把相同单词的WordEvent都发送到同一个PE那么这个PE里就可以统计到这个单词出现的总的次数。每当收到一个事件这个单词的出现次数就会更新对应的它就会向下游发送一个UpdatedCountEvent也就是更新单词计数的事件。这个事件里对应的Key是SortN这样一个组合每一个PE对象里的N都是随机的但是固定不变的。这个组合是为了下一层的负载均衡我们可以自己去设定N这个参数N越大意味着下游的PE对象越多负载就会分配到更多不同的对象里去计算的。而对应的值则包括了对应的单词是什么以及对应的单词的出现次数。也就是((Word具体单词), (Count出现次数)) 这么一个组合。第三层里则是一系列叫做SortPE的对象。它的作用则是接收上游不同单词的出现次数然后在内部进行排序。最后输出自己内部排序的Top K再给到下游。本质上它相当于是所有单词的某一个分区的数据。这个分区包含了一部分单词的所有数据。我们前面设定了N是几我们就会有几个SortPE的对象。给到下游的事件叫做PartialTopkEvent看名字你就知道它包含的信息就是一个部分数据的Top K。所有SortPE的对象输出的消息的Key都是相同的因为为了获得全局的排序它们需要发送给同一个PE对象。在这里这个Key就被写死成了topk1234 这么一个组合。而Value则是K个单词出现次数的集合。而整个DAG的终点则是唯一的一个MergePE。它的作用就是接收PartialTopkEvent然后在内部进行一次归并选出全局的TopK。并且最终它还需要把对应的数据写入到外部其他的存储系统比如数据库里供其他的应用读取。S4这个把整个数据处理流程变成一个有向无环图的设计也是后续所有流式处理系统都采用的一个解决方案。所有的数据变成了事件流而开发人员只需要做两件事情第一是设计整个DAG应该是什么样子的。第二是实现这个当中每一个节点的业务逻辑代码。而开发人员不需要关心数据是在哪里被处理的。这些都由S4这个分布式系统自己来决定。师从MapReduce的设计理念其实S4的系统架构和我们之前看过的MapReduce这样的框架一脉相承。PE其实和Map/Reduce函数一样只是一个抽象的概念。不过S4的系统设计要更加激进一点那就是S4选择了一个无中心的完全对称的架构。S4和我们之前看过的所有系统都不一样没有所谓的Master节点。如果一定要说有一个中心化的地方的话S4依赖于Zookeeper也就是一个类似于Chubby这样的分布式锁系统。S4的所有服务器都会作为一个处理节点ProcessingNode简称PN注册在Zookeeper上。具体如何分配负载是由各个节点协商决定的而不是由一个中心化的Master统一分配。每一个处理节点都是相同的它由上下两部分组成。上面是实际的业务处理逻辑模块它通过Event Listener监听外部发送过来的消息转发给对应的PE对象。PE对象的所有输出结果都发送给Dispatcher让Dispatcher确定应该发送给哪些PE里。实际的消息发送会由Dispatcher交给Emitter对外发送出去。业务处理模块里只会确定对应的消息发送应该发送给哪一个逻辑上的PE实际具体发送到哪一台物理节点则是由下面的通信层模块来决定的。这个模块主要解决这样几个问题首先是具体的路由也就是Event要去的某一个逻辑PE到底在哪台物理服务器上是由通信层模块来找到并且发送出去的上层的业务处理流程不需要知道。其次是负载均衡不同的单词更新的频率可能不一样。所以不同的处理节点的负载也会不一样。当有一个新的单词出现的时候我们需要判断新的PE应该放到哪一个节点上去。然后就是底层的容错恢复机制了当有特定节点挂掉的时候我们需要在其他的节点上恢复原先这个节点被分配的PE。最后就是实际的传输协议S4是一个“插件式”的架构也就是底层的传输协议也是可以切换的。S4既支持通过TCP发送消息确保消息能够发送成功也支持通过UDP发送消息来支持更大的吞吐量。你可以看到这个其实和我们看MapReduce的框架是类似的开发人员的关注点只需要在PE这个纯粹的业务逻辑层面。至于计算在哪一台服务器上发生各个节点之间是怎么通信的开发人员完全不需要关心。稍显“过时”的伸缩和容错能力不过看到这里相信你也会有一些疑问。以单词计数为例看起来一个S4在线上的有向无环图就需要有海量的对象这个数量级可能是数万乃至数十万。而不像之前我们看过的MapReduce那样只需要有少数Map和Reduce就好了。没错S4的设计其实还有粗糙也还有着很多的问题。首先就是这里的海量对象的问题。由于每一个处理数据的Key都要是一个对象系统里就会有海量的对象。而一个Key如果只出现一次之后再也不出现了也要占用内存。S4对此的解决办法是给Key设定TTL定期清理掉不需要的Key。其次是S4里没有时间窗口的概念。在我们进行实时数据处理的时候我们需要统计的常常是“过去一分钟的热搜”或者“过去一小时的热搜”这样有一个时间范围的数据。但是在S4的设计里我们并没有地方可以设定这个时间窗口。所以类似的需求需要我们自己在PE的代码里面去维护或者实现一下子大大增加了开发的难度和复杂度。第三是S4的容错处理非常简单。S4能够做到的容错其实就是某一个计算节点挂掉了我们重新再起一个计算节点承担它的工作。但是原先节点里所有PE维护的状态信息就都丢失了。我们既不知道目前的统计信息是什么也不知道目前处理到哪些事件了。Yahoo给出的答案是退回到离线批处理计算的数据上但是这个显然就不满足流式处理一开始的需求了。只能算是个聊胜于无的方案。最后一个问题则是S4虽然是一个分布式系统但是并不支持真正的动态扩容。在一开始论文的假设部分就假设了运行中的集群不会增加或者减少节点。这样带来的问题就是当负载快速上升的时候S4的策略是随机丢弃一些数据本质上是对数据进行了采样而不是能够通过简单增加硬件来解决问题。不过不管怎么说S4还是让大数据的的流式处理迈出了第一步。而这些S4并没有回答好的问题也会为接下来的流式数据处理系统的兴旺拉开了帷幕。小结好了对于S4的论文我们到这里也就解读完了。我们看到随着大数据的价值深入人心MapReduce这样定期定时进行数据处理的方式逐渐难以满足业务需求。于是大数据的流式计算登上了历史舞台。Yahoo通过S4系统进行低延时的“实时”数据处理。整个系统的设计理念类似于MapReduce开发人员只需要实现Processing Element这样的业务处理逻辑而不需要关心“分布式”是怎么运行的。整个框架会完成数据的分发、计算节点的调度以及容错之后的恢复。通过S4Yahoo能够及时地获取广告和搜索数据的反馈以及进行在线的A/B测试。整个S4内部的设计也将业务逻辑层和网络协议、数据路由、负载均衡等拆分开来做成了一个可插拔Pluggable的系统架构。在整个的流式数据处理框架里S4采用了一个典型的Actor模式。整个数据处理的流程可以被画成一个有向无环图图里的每一个点都是一个处理元素每一条边都是一条消息传递的路径而每一个处理元素都会被托管在某一个处理节点里。处理元素负责实现业务逻辑并且可以保存计算结果在内存。同时S4支持你定时地将对应的结果发布到外部的存储系统里使得计算结果对外可用。但是S4的设计显然也是很粗糙的。S4采用了一个完全对称、没有中心节点的分布式架构虽然看起来这个解决了“单点故障”问题但是也因此放弃了动态扩容而只能在大量流量进入的时候选择服务降级的解决方案。而在业务层面S4的容错也只是考虑“计算节点”层面的容错。容错只是将挂掉的节点能够在其他的硬件上重新运行起来但是已经处理的历史数据都已经丢失了。而对于节点之间的数据传输S4也没有作出全链路的传输保障。这些问题也是后面的Storm、Kafka、Flink这些系统出现的出发点。而S4自己却在2014年就从Apache孵化的项目中“退役retried”了。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2435007.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

SpringBoot-17-MyBatis动态SQL标签之常用标签

文章目录 1 代码1.1 实体User.java1.2 接口UserMapper.java1.3 映射UserMapper.xml1.3.1 标签if1.3.2 标签if和where1.3.3 标签choose和when和otherwise1.4 UserController.java2 常用动态SQL标签2.1 标签set2.1.1 UserMapper.java2.1.2 UserMapper.xml2.1.3 UserController.ja…

wordpress后台更新后 前端没变化的解决方法

使用siteground主机的wordpress网站,会出现更新了网站内容和修改了php模板文件、js文件、css文件、图片文件后,网站没有变化的情况。 不熟悉siteground主机的新手,遇到这个问题,就很抓狂,明明是哪都没操作错误&#x…

网络编程(Modbus进阶)

思维导图 Modbus RTU(先学一点理论) 概念 Modbus RTU 是工业自动化领域 最广泛应用的串行通信协议,由 Modicon 公司(现施耐德电气)于 1979 年推出。它以 高效率、强健性、易实现的特点成为工业控制系统的通信标准。 包…

UE5 学习系列(二)用户操作界面及介绍

这篇博客是 UE5 学习系列博客的第二篇,在第一篇的基础上展开这篇内容。博客参考的 B 站视频资料和第一篇的链接如下: 【Note】:如果你已经完成安装等操作,可以只执行第一篇博客中 2. 新建一个空白游戏项目 章节操作,重…

IDEA运行Tomcat出现乱码问题解决汇总

最近正值期末周,有很多同学在写期末Java web作业时,运行tomcat出现乱码问题,经过多次解决与研究,我做了如下整理: 原因: IDEA本身编码与tomcat的编码与Windows编码不同导致,Windows 系统控制台…

利用最小二乘法找圆心和半径

#include <iostream> #include <vector> #include <cmath> #include <Eigen/Dense> // 需安装Eigen库用于矩阵运算 // 定义点结构 struct Point { double x, y; Point(double x_, double y_) : x(x_), y(y_) {} }; // 最小二乘法求圆心和半径 …

使用docker在3台服务器上搭建基于redis 6.x的一主两从三台均是哨兵模式

一、环境及版本说明 如果服务器已经安装了docker,则忽略此步骤,如果没有安装,则可以按照一下方式安装: 1. 在线安装(有互联网环境): 请看我这篇文章 传送阵>> 点我查看 2. 离线安装(内网环境):请看我这篇文章 传送阵>> 点我查看 说明&#xff1a;假设每台服务器已…

XML Group端口详解

在XML数据映射过程中&#xff0c;经常需要对数据进行分组聚合操作。例如&#xff0c;当处理包含多个物料明细的XML文件时&#xff0c;可能需要将相同物料号的明细归为一组&#xff0c;或对相同物料号的数量进行求和计算。传统实现方式通常需要编写脚本代码&#xff0c;增加了开…

LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器的上位机配置操作说明

LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器专为工业环境精心打造&#xff0c;完美适配AGV和无人叉车。同时&#xff0c;集成以太网与语音合成技术&#xff0c;为各类高级系统&#xff08;如MES、调度系统、库位管理、立库等&#xff09;提供高效便捷的语音交互体验。 L…

(LeetCode 每日一题) 3442. 奇偶频次间的最大差值 I (哈希、字符串)

题目&#xff1a;3442. 奇偶频次间的最大差值 I 思路 &#xff1a;哈希&#xff0c;时间复杂度0(n)。 用哈希表来记录每个字符串中字符的分布情况&#xff0c;哈希表这里用数组即可实现。 C版本&#xff1a; class Solution { public:int maxDifference(string s) {int a[26]…

【大模型RAG】拍照搜题技术架构速览:三层管道、两级检索、兜底大模型

摘要 拍照搜题系统采用“三层管道&#xff08;多模态 OCR → 语义检索 → 答案渲染&#xff09;、两级检索&#xff08;倒排 BM25 向量 HNSW&#xff09;并以大语言模型兜底”的整体框架&#xff1a; 多模态 OCR 层 将题目图片经过超分、去噪、倾斜校正后&#xff0c;分别用…

【Axure高保真原型】引导弹窗

今天和大家中分享引导弹窗的原型模板&#xff0c;载入页面后&#xff0c;会显示引导弹窗&#xff0c;适用于引导用户使用页面&#xff0c;点击完成后&#xff0c;会显示下一个引导弹窗&#xff0c;直至最后一个引导弹窗完成后进入首页。具体效果可以点击下方视频观看或打开下方…

接口测试中缓存处理策略

在接口测试中&#xff0c;缓存处理策略是一个关键环节&#xff0c;直接影响测试结果的准确性和可靠性。合理的缓存处理策略能够确保测试环境的一致性&#xff0c;避免因缓存数据导致的测试偏差。以下是接口测试中常见的缓存处理策略及其详细说明&#xff1a; 一、缓存处理的核…

龙虎榜——20250610

上证指数放量收阴线&#xff0c;个股多数下跌&#xff0c;盘中受消息影响大幅波动。 深证指数放量收阴线形成顶分型&#xff0c;指数短线有调整的需求&#xff0c;大概需要一两天。 2025年6月10日龙虎榜行业方向分析 1. 金融科技 代表标的&#xff1a;御银股份、雄帝科技 驱动…

观成科技:隐蔽隧道工具Ligolo-ng加密流量分析

1.工具介绍 Ligolo-ng是一款由go编写的高效隧道工具&#xff0c;该工具基于TUN接口实现其功能&#xff0c;利用反向TCP/TLS连接建立一条隐蔽的通信信道&#xff0c;支持使用Let’s Encrypt自动生成证书。Ligolo-ng的通信隐蔽性体现在其支持多种连接方式&#xff0c;适应复杂网…

铭豹扩展坞 USB转网口 突然无法识别解决方法

当 USB 转网口扩展坞在一台笔记本上无法识别,但在其他电脑上正常工作时,问题通常出在笔记本自身或其与扩展坞的兼容性上。以下是系统化的定位思路和排查步骤,帮助你快速找到故障原因: 背景: 一个M-pard(铭豹)扩展坞的网卡突然无法识别了,扩展出来的三个USB接口正常。…

未来机器人的大脑:如何用神经网络模拟器实现更智能的决策?

编辑&#xff1a;陈萍萍的公主一点人工一点智能 未来机器人的大脑&#xff1a;如何用神经网络模拟器实现更智能的决策&#xff1f;RWM通过双自回归机制有效解决了复合误差、部分可观测性和随机动力学等关键挑战&#xff0c;在不依赖领域特定归纳偏见的条件下实现了卓越的预测准…

Linux应用开发之网络套接字编程(实例篇)

服务端与客户端单连接 服务端代码 #include <sys/socket.h> #include <sys/types.h> #include <netinet/in.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <arpa/inet.h> #include <pthread.h> …

华为云AI开发平台ModelArts

华为云ModelArts&#xff1a;重塑AI开发流程的“智能引擎”与“创新加速器”&#xff01; 在人工智能浪潮席卷全球的2025年&#xff0c;企业拥抱AI的意愿空前高涨&#xff0c;但技术门槛高、流程复杂、资源投入巨大的现实&#xff0c;却让许多创新构想止步于实验室。数据科学家…

深度学习在微纳光子学中的应用

深度学习在微纳光子学中的主要应用方向 深度学习与微纳光子学的结合主要集中在以下几个方向&#xff1a; 逆向设计 通过神经网络快速预测微纳结构的光学响应&#xff0c;替代传统耗时的数值模拟方法。例如设计超表面、光子晶体等结构。 特征提取与优化 从复杂的光学数据中自…