第 1 题
为什么在选择大数据方案前,必须先写出「不引入分布式方案会发生什么」?
尚未检查本题。
查看答案与评价要点
参考答案:因为分布式方案的收益只有在单机方案确实失效时才成立。写清楚失效形式(查询超时、存储不足、无法满足时效目标)才能确定要优化的维度;写不出来,通常说明引入分布式栈只会增加运维负担而不解决实际约束。
评价要点:指出收益以单机方案失效为前提;给出至少两种具体失效形式;提到运维成本作为代价
浏览器未允许保存进度;当前为只读学习模式。
第 5 周 · 初阶
掌握数据处理核心框架
周目标:掌握大数据处理核心框架,理解批处理与流处理范式
课程成果:CO2 CO8
已学习 0 / 7 天
Day 29
建议时长:75 分钟
本日 CO:CO1 CO2 CO8
大数据不是「数据很多」,而是单机的存储、计算或时效性其中之一被突破后,必须改用分布式方案的一类工程问题。判断是否需要它,要看具体数字:数据总量与增长速度、单次查询要扫描多少、结果需要多快可用、有多少并发。Lambda 架构用批处理层保证最终正确、用速度层提供近实时结果、用服务层合并两者,代价是同一套业务逻辑要维护两份实现;Kappa 架构用单一流式管道加重放来消除这份重复,代价是对流处理框架和消息保留期的要求更高。先算清数字再选架构,否则容易为了「上大数据」而引入不必要的运维负担。
6 分钟 · MP3 · 双主持人讲解
把「大数据」当成一个门槛值是常见误解。真正有意义的判断来自四组数字:数据总量与日增量决定存储方案,单次查询要扫描的数据量决定是否需要并行计算,结果从产生到可用的延迟目标决定批处理还是流处理,并发查询数决定服务层的形态。一个每天新增几十万行、查询只涉及最近七天的场景,用单机数据库加合适的索引往往比引入一套分布式栈更划算,运维负担也小得多。
当确实需要分布式时,代价必须一并计入:集群本身需要人维护,作业失败需要排查,数据倾斜会让「加机器」失效,跨节点的数据移动成为新的瓶颈。因此设计文档里应当写清楚「不引入分布式方案时会发生什么」——是查询超时、存储放不下,还是无法满足时效要求。写不出这一句,通常说明还没到需要它的时候。
Lambda 架构把同一份数据同时送入两条路径:批处理层周期性地重算全量结果,保证正确与可回溯;速度层对增量数据做近实时处理,弥补批处理的延迟;服务层把两者的结果合并后对外提供查询。它的优点是批处理层可以修正速度层的近似与错误,缺点是同一套业务逻辑要在两种计算范式中各实现一遍,两份实现容易随时间产生偏差,而偏差往往在对数时才被发现。
Kappa 架构主张只保留流式管道:需要重算时,把消息系统中保留的历史事件重新播放一遍即可。它消除了双份实现,但对基础设施提出了更强的要求——消息系统必须保留足够长的历史,流处理框架必须支持有状态计算与精确的重放语义,作业升级时的状态迁移也要能处理。选择哪一种,取决于团队更怕维护成本还是更怕重放复杂度,这个判断应当写进文档而不是默认。
为一个具体业务场景画出 Lambda 架构图,逐层标注数据来源、处理方式、延迟目标与一致性承诺,并说明改用 Kappa 架构后哪些部分会消失、哪些成本会上升。
为什么在选择大数据方案前,必须先写出「不引入分布式方案会发生什么」?
尚未检查本题。
参考答案:因为分布式方案的收益只有在单机方案确实失效时才成立。写清楚失效形式(查询超时、存储不足、无法满足时效目标)才能确定要优化的维度;写不出来,通常说明引入分布式栈只会增加运维负担而不解决实际约束。
评价要点:指出收益以单机方案失效为前提;给出至少两种具体失效形式;提到运维成本作为代价
Lambda 架构中「同一套业务逻辑实现两遍」为什么是主要风险?
尚未检查本题。
参考答案:批处理层与速度层使用不同的计算范式,同一段口径需要分别实现;随着需求变更,两份实现容易产生偏差,而偏差通常只有在对数或用户投诉时才暴露。因此需要专门的对账机制和口径评审,Kappa 架构正是为消除这份重复而提出的。
评价要点:指出两种范式导致两份实现;说明偏差难以及时发现;提出对账或改用单一管道
尚未完成自测。
在教师给出的场景数字上完成 Lambda 三层图,并口述每层的延迟目标。
自选场景完成数字估算、Lambda 图与 Kappa 改造分析。
为批速两层设计一份对账方案:对账指标、对账周期、允许偏差范围与超限后的处理流程。
学习状态:未学习
Day 30
建议时长:75 分钟
本日 CO:CO1 CO2 CO8
Hadoop 提供了分布式存储与调度的基本范式,理解它是理解后来所有框架的基础。HDFS 把大文件切成固定大小的块分散存储并保留多个副本,NameNode 保存目录树与块位置的元数据,DataNode 保存实际数据;这个设计对「一次写入、多次读取的大文件」友好,对海量小文件则很不友好,因为每个文件都要占用 NameNode 内存。MapReduce 把计算拆成 map、shuffle、reduce 三个阶段,shuffle 是真正的性能瓶颈所在。YARN 把资源管理与作业逻辑分离,让同一个集群可以同时跑多种计算框架。
6 分钟 · MP3 · 双主持人讲解
HDFS 把文件切分成固定大小的块,每个块默认保存多个副本分布在不同 DataNode 上。NameNode 只保存元数据——目录结构、文件到块的映射、块到节点的位置——这些元数据常驻内存,因此元数据条目的数量直接受限于 NameNode 的内存容量。读取时客户端先向 NameNode 询问块的位置,再直接与 DataNode 通信传输数据,这样元数据服务不会成为数据传输的带宽瓶颈。
这一设计的代价是对小文件极不友好:一百万个 1KB 的小文件与一个 1GB 的大文件占用的数据量相当,但前者会产生上百万条元数据,消耗大量 NameNode 内存,并让后续的计算作业产生大量极短的任务,调度开销远超实际计算。缓解方向包括在写入前合并小文件、使用容器格式(如序列文件或列式格式)打包、以及在采集侧就按时间窗口聚合,而不是等到查询时才处理。
MapReduce 的执行分三步:map 阶段在数据所在节点上就地处理并输出键值对;shuffle 阶段按键把中间结果重新分发到对应的 reduce 任务,这一步涉及排序、跨网络传输和落盘;reduce 阶段对同一个键的所有值做聚合。真正决定作业耗时的通常是 shuffle——如果某个键对应的数据量远大于其他键(数据倾斜),承担该键的 reduce 任务会成为长尾,此时增加节点数并不能缩短总耗时。
YARN 把资源管理从计算框架中独立出来:ResourceManager 负责集群级的资源分配,每个作业有自己的 ApplicationMaster 负责任务级调度,NodeManager 在各节点上启动容器。这个分层让同一个集群可以同时运行 MapReduce、Spark、Flink 等不同框架,也让资源隔离与队列策略成为集群级能力,而不必在每个框架里重复实现。
运行一个 WordCount 示例,观察 map、shuffle、reduce 三个阶段的输入输出与耗时分布,并解释小文件为什么会让 NameNode 成为瓶颈。
为什么 HDFS 上的「小文件问题」不能通过增加 DataNode 来解决?
尚未检查本题。
参考答案:小文件问题的瓶颈在 NameNode 的元数据内存,而不是数据存储容量。每个文件与块都会产生常驻内存的元数据条目,增加 DataNode 只增加数据容量与带宽,不减少元数据数量。正确方向是在写入侧合并文件或使用容器/列式格式打包。
评价要点:指出瓶颈在 NameNode 元数据内存;说明增加 DataNode 不减少元数据条目;给出合并或打包的缓解方向
一个 MapReduce 作业中 99 个 reduce 任务几分钟完成,剩下 1 个跑了两小时。最可能的原因是什么?该如何处理?
尚未检查本题。
参考答案:最可能是数据倾斜:某个键对应的数据量远大于其他键,承担该键的 reduce 任务成为长尾。处理方向包括为倾斜键加随机前缀做两阶段聚合、在 map 侧先做局部合并、或对倾斜键单独走一条处理路径;单纯增加 reduce 数量无效,因为同一个键只会落到一个 reduce。
评价要点:识别为数据倾斜;说明同一个键只落到一个 reduce,增加数量无效;给出加盐两阶段聚合或局部合并等具体处理
尚未完成自测。
使用教师证据包分析一份已有的作业日志,标出三个阶段的边界与耗时。
独立运行 WordCount 与倾斜对比实验并提交完整记录。
为倾斜键设计两阶段聚合方案并验证长尾任务耗时下降,说明该方案引入的额外 shuffle 代价。
学习状态:未学习
Day 31
建议时长:75 分钟
本日 CO:CO1 CO2 CO8
Spark 相对 MapReduce 的关键差异在于把中间结果保留在内存并用有向无环图统一调度,因而适合需要多轮迭代的计算。它的编程模型有两层:RDD 是不可变的分布式数据集,提供转换与行动两类操作,转换是惰性的,只有行动触发真正的计算;DataFrame 与 Spark SQL 在此之上提供结构化抽象,让优化器可以基于 schema 做谓词下推、列裁剪与执行计划重写,通常比手写 RDD 操作更快。理解「转换惰性、行动触发」和「宽依赖会引发 shuffle」这两点,才能解释一段 PySpark 代码为什么慢。
6 分钟 · MP3 · 双主持人讲解
RDD 上的操作分为转换与行动两类:map、filter、join 这类转换只是记录下要做什么,构建出一张有向无环图;只有 count、collect、save 这类行动才会真正触发计算。这个设计让 Spark 有机会把多个转换合并到同一次数据扫描中,但也意味着调试时看到的「这一行很快」并不代表它便宜——耗时会集中体现在触发行动的那一行,读日志时必须按阶段而不是按代码行归因。
依赖关系决定了是否需要 shuffle。窄依赖指子分区只依赖父分区的一部分(如 map、filter),可以在同一节点上流水线执行;宽依赖指子分区依赖多个父分区的数据(如 groupByKey、join、repartition),必须跨节点重新分发数据。Spark 按宽依赖把 DAG 切分成 stage,一个 stage 内的操作可以合并执行。因此优化的第一步通常是数一数代码里有几次宽依赖,能否合并或消除。
DataFrame 与 Spark SQL 在 RDD 之上引入了 schema,使查询优化器能够理解数据结构。有了这层信息,优化器可以把过滤条件下推到数据源、只读取用到的列、重写连接顺序,并生成更紧凑的执行代码。同样的逻辑用 RDD 手写时,这些优化都要靠开发者自己完成,而且很容易遗漏。官方文档因此建议结构化数据优先使用 DataFrame 或 Dataset API。
缓存不是万能的。把一个只使用一次的中间结果缓存起来,只会白白占用内存并可能触发落盘;真正值得缓存的是被多次复用且重算代价高的中间结果。判断依据应当来自执行计划与实测:先看 DAG 中该结果被引用了几次,再对比缓存前后的实际耗时,而不是凭感觉在每一步后面都加缓存。分区数同理,过少无法并行、过多则调度开销上升,需要按数据量与并行度实测确定。
用 PySpark 对一份结构化数据做清洗与聚合,对比 RDD 写法与 DataFrame 写法的执行计划,并找出代码中触发 shuffle 的位置。
为什么在 PySpark 中「某一行代码很快」不能说明它开销小?
尚未检查本题。
参考答案:转换操作是惰性的,只构建执行计划而不触发计算,真正的开销集中在触发行动的那一行。因此性能归因必须依据执行计划与各 stage 的耗时,而不是逐行计时。
评价要点:指出转换惰性、行动触发;说明耗时集中在行动处;提出按 stage 而非按行归因
哪些操作会引发 shuffle?为什么减少 shuffle 通常是优化的第一步?
尚未检查本题。
参考答案:宽依赖操作会引发 shuffle,例如按键分组、join、重分区。shuffle 需要跨节点传输数据并伴随排序与落盘,是网络与磁盘开销最集中的环节,同时也是数据倾斜的暴露点。因此优先合并或消除不必要的宽依赖,收益通常大于其他微调。
评价要点:举出至少两个引发 shuffle 的操作;说明跨节点传输、排序与落盘的开销;把 shuffle 与数据倾斜联系起来
尚未完成自测。
在教师提供的数据与骨架代码上完成聚合,并读出执行计划中的 shuffle 次数。
独立完成两种实现的对比与缓存实验,提交实测数据。
构造一个有明显倾斜键的数据集,用加盐两阶段聚合改写并验证 stage 耗时分布的变化。
学习状态:未学习
Day 32
建议时长:75 分钟
本日 CO:CO1 CO2 CO8
流处理的难点不是「实时」,而是时间与状态。事件时间指事件真实发生的时刻,处理时间指系统处理它的时刻,二者之间的差距由网络、重试和积压造成;只按处理时间开窗,结果会随系统负载而变化,无法复现。Flink 用水位线表示「事件时间已经推进到某一时刻」,据此触发窗口计算,并用允许延迟与侧输出处理迟到数据。有状态计算依赖检查点:作业定期把状态持久化,故障后从最近检查点恢复,这是端到端一致性保证的基础,而不是简单的「重启继续」。
6 分钟 · MP3 · 双主持人讲解
事件时间来自数据本身携带的时间戳,处理时间来自处理节点的系统时钟。用处理时间开窗实现简单、延迟低,但同一批数据在不同负载下重放会得到不同结果——积压时大量旧事件会被塞进同一个窗口。用事件时间开窗结果可复现,代价是必须处理乱序:系统无法确知某个时间点之前的事件是否都已到达。
水位线正是对这个问题的工程回答:它是一个随数据流动的时间标记,表示系统认为事件时间已经推进到该时刻,此刻之前的窗口可以触发计算。水位线通常由最大已见事件时间减去一个容忍偏移生成——这个偏移是一次显式的权衡:设得大,结果更完整但延迟更高;设得小,延迟低但更多事件会被判为迟到。这个数值应当基于实测的乱序程度来定,并写进设计文档。
水位线推进之后到达的事件称为迟到数据。Flink 提供两种基本处置:允许延迟让窗口在触发后再保留一段时间,迟到事件到达时重新触发并更新结果,代价是下游要能接受结果被修正;侧输出把迟到事件单独引出到另一条流,交由专门的补偿逻辑处理,代价是要额外实现这条路径。两者都不是默认行为——不做任何配置时,迟到事件会被直接丢弃,这一点必须在设计文档中写明。
有状态算子的容错依赖检查点:作业周期性地把各算子的状态一致地持久化到外部存储,故障后从最近一次成功的检查点恢复并重放之后的数据。这意味着恢复不是「从头再来」,而是回到一个一致的快照点。检查点有实实在在的开销——间隔越短恢复越快但常态开销越大,状态越大持久化耗时越长。这三个数字(检查点间隔、状态大小、恢复耗时)应当实测并记录,而不是沿用默认值。
实现一个基于事件时间的滚动窗口统计,故意注入乱序与迟到事件,观察水位线推进、窗口触发与迟到数据的去向。
为什么按处理时间开窗的统计结果无法复现?
尚未检查本题。
参考答案:处理时间取决于系统处理该事件的时刻,会随集群负载、重启与积压情况变化;同一批数据在不同条件下重放会落入不同窗口,得到不同结果。按事件时间开窗才能保证同一批数据无论何时重放都落入相同窗口。
评价要点:指出处理时间随负载变化;说明重放会落入不同窗口;指出事件时间开窗可复现
水位线的容忍偏移设置过大或过小分别会带来什么后果?这个数值应该怎么确定?
尚未检查本题。
参考答案:设得过大,窗口要等更久才触发,结果延迟上升;设得过小,更多乱序事件在窗口触发后才到达,被判为迟到而丢弃或需要额外处理,结果完整性下降。该数值应基于实测的乱序分布(例如观察事件时间与到达时间差的分位数)来确定,并记录测量条件。
评价要点:说明过大导致延迟上升;说明过小导致迟到事件增多;提出基于实测乱序分布确定并记录条件
尚未完成自测。
在教师提供的作业骨架上调整容忍偏移,观察并记录窗口触发时刻的变化。
独立完成窗口统计、两组偏移对比与侧输出配置。
在作业运行中制造一次失败并从检查点恢复,验证恢复后结果与不失败时一致,并记录恢复耗时。
学习状态:未学习
Day 33
建议时长:75 分钟
本日 CO:CO2 CO8
数据仓库解决的是「同一个指标在不同部门算出不同数字」的问题,核心是统一口径而不是存储技术。分层建模是常见做法:贴源层保留原始数据不做加工,明细层完成清洗与规范化,汇总层按主题聚合,应用层面向具体报表;每一层的职责边界清楚,问题才能被定位到具体层次。Hive 让 SQL 可以运行在分布式存储上,而表格式(如 Iceberg)进一步提供了模式演进、快照与时间旅行能力。真正决定数据仓库可信度的,是指标定义、口径文档和可追溯的加工链路。
6 分钟 · MP3 · 双主持人讲解
贴源层的职责是忠实保留原始数据,不做业务加工——这样当下游发现问题时,可以回到原始数据重新加工,而不必向业务系统重新索取。明细层完成清洗、类型规范、维度关联,产出可复用的明细宽表。汇总层按主题做预聚合,降低查询成本。应用层则直接服务于具体报表或接口。分层的价值在于:当某个数字不对时,可以逐层向上核对,快速判断问题出在采集、清洗、聚合还是展示。
分层最常见的失败是层次形同虚设:贴源层里混入了业务逻辑,汇总层直接查了业务库,应用层绕过汇总层自己算。这样做短期看更快,长期看会让同一个指标出现多条计算路径,口径分歧无法收敛。因此每一层不仅要写「应该做什么」,还要明确写出「不该做什么」,并在评审中检查。
一个指标的口径定义至少要回答:统计对象是什么(哪些记录计入)、时间口径是什么(按下单时间还是支付时间)、有哪些排除条件(测试订单、内部账号、已退款)、计算公式是什么、以及归属哪个层次的哪张表。这些内容写不清楚,同一个「日活」在两个部门算出不同数字就是必然的。口径文档应当与表一起维护并纳入变更评审,而不是散落在聊天记录里。
分区决定了查询要扫描多少数据。按日期分区后,查询最近七天只需扫描七个分区而不是全表,这是数据仓库中最直接的性能手段。但分区字段选错同样有害:按高基数字段分区会产生海量小分区,重新引入小文件问题。表格式(如 Iceberg)在此之上提供了模式演进、快照与时间旅行——可以安全地增删列、回查某个历史时刻的表状态,这对排查「昨天的报表为什么和今天重算的不一样」非常有用。
为一个业务主题设计分层模型,建表并跑通一次从贴源到汇总的加工,写出至少三个指标的口径定义。
为什么贴源层不应包含业务加工逻辑?
尚未检查本题。
参考答案:贴源层的价值在于忠实保留原始数据,使下游发现问题时可以从原始数据重新加工,而不必向业务系统重新索取(业务系统的数据可能已被覆盖或清理)。一旦贴源层混入加工逻辑,原始信息丢失,问题就无法回溯定位。
评价要点:指出保留原始数据以支持重算;说明业务系统数据可能不可再取;把可回溯性作为分层价值
一份指标口径定义至少应包含哪些要素?缺少其中任意一项会导致什么后果?
尚未检查本题。
参考答案:至少包含统计对象、时间口径、排除条件、计算公式与所属表。缺少统计对象或排除条件会导致不同人计入的记录集合不同;缺少时间口径会导致按下单时间与按支付时间算出不同结果;缺少所属表则无法确定使用哪条计算路径,同一指标出现多个数字。
评价要点:列出至少四项要素;为其中一项缺失给出具体后果;把口径分歧与多条计算路径联系起来
尚未完成自测。
在教师给出的表结构上完成一次分区聚合查询,并读出扫描量差异。
独立完成四层设计、建表加工与三个指标的口径定义。
为一次口径变更设计迁移方案:如何保证历史数据可回溯、下游何时切换、变更如何评审与公告。
学习状态:未学习
Day 34
建议时长:75 分钟
本日 CO:CO2 CO8
数据治理不是给数据加标签,而是让「这个数字从哪来、谁能看、能不能信」这三个问题有可查的答案。元数据管理回答第一个问题:表、字段、作业和它们之间的血缘关系被记录下来,一个指标出问题时可以沿血缘向上定位,一次表结构变更也能提前评估影响范围。权限与分级回答第二个问题:数据按敏感级别分类,访问按最小权限授予并留下审计日志。数据质量回答第三个问题:为关键表定义完整性、唯一性、及时性、一致性等可自动执行的规则,并在规则失败时阻断下游而不是静默放行。
6 分钟 · MP3 · 双主持人讲解
元数据描述数据本身的信息:表有哪些字段、字段是什么类型和含义、由哪个作业产出、什么时候更新。血缘则描述数据之间的加工关系:这张汇总表由哪几张明细表经过哪个作业生成,这个报表字段又来自汇总表的哪一列。Apache Atlas 这类元数据平台把这些关系集中管理,使它们可被查询而不是散落在各人的记忆里。
血缘的直接价值有两个方向。向上追溯:某个指标数字异常时,可以沿血缘逐层检查是采集、清洗还是聚合出了问题,把排查范围从「整个数据平台」缩小到几张表。向下评估:要修改一张表的结构或口径时,可以先查出所有下游依赖,评估影响范围并提前通知,而不是改完之后等下游报错。没有血缘的数据平台,这两件事都只能靠人问人。
数据质量规则应当是可自动执行的断言,而不是文档里的期望。常见的四类是:完整性(关键字段非空、当日分区行数不为零)、唯一性(主键或业务键无重复)、及时性(数据在约定时间前到达)、一致性(与上游或对照表的汇总值差异在阈值内)。每条规则都要有明确阈值和失败处置,否则规则只是装饰。
关键设计是失败时阻断下游。如果一张表的唯一性校验失败却继续向下加工,错误会扩散到所有下游报表,等到有人发现时,回滚成本远高于当时停下来。因此质量校验应当成为加工链路中的一个节点:通过才继续,不通过则停止并告警,同时保留上一版本可用的数据。权限方面,数据按敏感级别分类后按最小权限授予,审计日志至少记录访问者身份、访问时间、访问对象、操作类型和结果,这些字段是事后追责与合规检查的依据。
为一张核心表建立元数据与血缘记录,定义至少四条可自动执行的数据质量规则,并说明规则失败时的处置流程。
数据血缘在排查问题与评估变更时分别起什么作用?
尚未检查本题。
参考答案:排查时可沿血缘向上逐层定位,把问题范围从整个平台缩小到具体的几张表和作业;评估变更时可向下查出全部依赖方,提前评估影响并通知,而不是改完之后等下游报错。没有血缘,这两件事只能依靠人工询问。
评价要点:说明向上追溯定位问题;说明向下评估变更影响;指出缺少血缘时依赖人工询问
为什么数据质量规则失败时应当阻断下游,而不是告警后继续运行?
尚未检查本题。
参考答案:继续运行会把错误数据扩散到所有下游报表和应用,等到有人发现时污染范围已经很大,回滚与重算成本远高于当时停止。阻断并保留上一版本可用数据,可以把影响限制在一张表上,同时给出明确的修复入口。
评价要点:指出错误会向下游扩散;比较回滚成本与当时停止的成本;提出保留上一可用版本
尚未完成自测。
在教师给出的血缘图上补齐缺失的加工节点,并说出一次异常的排查顺序。
独立完成元数据、血缘、四条质量规则与处置流程设计。
为一次口径变更编写影响评估报告:列出全部下游依赖、通知计划、切换窗口与回退方案。
学习状态:未学习
Day 35
建议时长:75 分钟
本日 CO:CO2 CO8
本周收尾要回答一个反复出现的问题:什么时候用批处理,什么时候用流处理。判断依据不是「哪个更先进」,而是四组约束——结果需要多快可用、数据是否会迟到与需要重算、口径变更后是否要回溯历史、团队是否有能力运维有状态作业。批处理的优势是简单、易重算、口径变更后重跑即可;流处理的优势是延迟低,代价是状态管理、迟到处理和重放都要显式设计。多数团队的实际路径是先用批处理满足大部分需求,再对确实需要低延迟的少数场景引入流处理,而不是一开始就全面流式化。
6 分钟 · MP3 · 双主持人讲解
第一组是延迟目标:结果从数据产生到可用允许多久。分钟级以上的需求通常批处理即可满足;秒级以内且直接影响用户体验或自动决策的,才需要流处理。第二组是迟到与重算:如果数据经常迟到、经常需要按新口径重算历史,批处理天然更容易——重跑一遍即可;流式重算需要消息保留期足够长且作业支持重放。
第三组是口径回溯要求:口径变更后是否需要让历史数据也符合新口径。批处理只需重跑历史分区;流处理则要考虑状态迁移与重放窗口。第四组是运维能力:有状态流作业的升级、扩缩容、状态兼容性与故障恢复都需要专门经验,团队若不具备,勉强上线的流作业会成为长期负担。把这四组约束逐一写下来,选择通常就已经确定了。
只写优点的技术选型说明是不可复核的。每一个选择都应当配一段代价:选批处理,代价是延迟无法降到分钟以下、数据在窗口内对用户不可见;选流处理,代价是需要维护状态、处理迟到、设计重放,并承担更高的运维复杂度。把代价写清楚,评审时讨论的才是真实取舍,而不是各自的偏好。
更进一步,应当定义「触发条件」:当延迟要求从十分钟收紧到十秒、当日增数据量超过某个阈值导致批作业无法在窗口内跑完、当迟到率超过某个比例,就应当重新评估当前选择。写下这些条件的意义在于,未来的决策不必从头争论,只需检查条件是否被触发。这也是本课程反复强调的可复核性在架构决策上的体现。
写一份批处理与流处理的选择说明:为同一业务的三个不同需求分别给出选择、理由与代价,并列出改变选择的触发条件。
为什么「延迟要求」不是选择流处理的唯一依据?
尚未检查本题。
参考答案:还要考虑迟到与重算需求、口径回溯要求和团队运维能力。即使延迟要求较高,如果数据经常迟到、口径经常变更需要回溯历史,或团队不具备维护有状态作业的能力,流处理的总成本可能高于收益;此时更稳妥的做法是先用批处理满足大部分需求,只对确需低延迟的少数场景引入流处理。
评价要点:列出延迟以外的至少两组约束;说明运维能力是现实约束;提出分场景而非全面流式化
技术选型说明中为什么要写「改变选择的触发条件」?
尚未检查本题。
参考答案:因为约束会随业务变化,而重新评估如果没有事先约定的判据,就会退化为凭偏好争论。写明触发条件(如延迟要求收紧到某个值、日增数据量超过阈值、迟到率超过比例)后,未来只需检查条件是否被触发即可决定是否重评,决策过程可复核。
评价要点:指出约束会随业务变化;说明缺少判据会退化为凭偏好争论;强调触发条件让决策可复核
尚未完成自测。
在教师给出的三个需求上完成四组约束填写并给出选择。
独立完成三个需求的选择、代价与触发条件,并整合一页数据链路说明。
为其中一个需求写出从批处理迁移到流处理的分步计划,包含双跑对账期与回退条件。
学习状态:未学习