ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

Flink实时数据分析平台实战:从数据采集到可视化大屏

Flink实时数据分析平台实战:从数据采集到可视化大屏 1. 从需求到架构先想清楚实时到底意味着什么接到一个实时数据分析平台的需求时我心里第一反应不是写Flink代码而是先问对方一句话你说的实时是秒级、分钟级还是小时级这个问题问出来很多需求就瞬间清晰了。我见过太多团队一上来就铺Flink集群、搞大屏结果做了三个月发现核心指标延迟五分钟就能满足白费了一堆功夫。Java工程师做实时数据平台有个天然优势Flink本身就是Java/Scala生态你熟悉的Spring Boot、Maven、JVM调优经验全部能复用。相比Python系或者纯SQL系的数据栈Java团队啃Flink的上手成本要低得多。这篇实战文章我就围绕数据采集→实时计算→可视化大屏这条完整链路把从零搭建一个实时数据分析平台的架构思路、核心代码、踩坑记录都讲透。1.1 先拆需求你的大屏是不是假实时大多数实时数据分析平台的真实需求拆开来看无非三类指标监控类比如订单量、成交额、在线用户数要求秒级或分钟级刷新行为分析类用户点击流、页面路径要求准实时但允许一定延迟预警通知类比如异常流量、交易失败率飙升要求延迟越低越好这三类需求对技术选型的影响完全不同。我之前遇到一个做污水处理可视化大屏的项目客户说实时结果详细了解才知道污水数据本身是五分钟采集一次那你就算用Flink做到毫秒级计算也没有意义瓶颈在采集端。反过来如果是电商大促的实时成交大屏每秒钟都有成千上万条订单事件那你就需要认真设计从采集到展示的每一层。所以第一步永远是做延迟预算端到端延迟 采集延迟 传输延迟 计算延迟 存储延迟 展示刷新延迟。把每一项都列出来标出可接受范围后续所有技术决策都有依据。1.2 端到端链路的分层设计我做的实时数据分析平台标准链路分五层层级组件选型职责采集层Filebeat / Flink CDC / HTTP SDK将日志、数据库变更、业务事件统一送入消息队列传输层Kafka削峰填谷、缓冲削流解耦采集与计算计算层Flink实时ETL、窗口聚合、状态计算、规则匹配存储层Doris / ClickHouse / Redis结果表存储、维度数据缓存、大屏查询加速展示层Vue ECharts / DataV可视化大屏、指标卡片、趋势图表这套链路跟传统的离线数仓最大的区别在于数据不是按天批量加工而是以事件流的方式持续流动。Flink跑在Kafka和存储之间相当于一个永不停止的计算引擎——上游数据来了就算算完就写写完后端到端延迟通常控制在秒级。关于架构理念现阶段我做项目基本直接采用Kappa架构思路不再搭建Lambda架构。Lambda那套实时链路离线链路双跑、最终结果合并的方案维护成本太高两套代码逻辑要一致本身就是灾难。现在Flink的流批一体能力已经相当成熟一套代码可以同时跑实时和离线Kappa架构足够覆盖绝大多数场景。1.3 为什么选Flink而不是Spark Streaming每次做技术选型都要面对这个问题。我的答案很直接如果你的场景需要事件时间处理、精确一次语义、丰富的状态管理Flink是当前最优解。事件时间处理数据在网络上传输会有延迟和乱序Flink的Watermark机制可以基于事件真正发生的时间进行计算而不是基于数据到达时间。这在处理日志类数据时尤其重要——用户点击发生在10:00:00但因为网络抖动这条日志10:00:10才到如果你用处理时间计算就把这10秒的误差算进指标里了。精确一次语义Exactly-OnceFlink通过Checkpoint 两阶段提交保证即使任务崩溃恢复数据也不会重复或丢失。做交易类指标时这是刚需。状态管理Flink可以把中间结果存在内存或RocksDB中实现跨事件的聚合计算比如统计每个用户的累计访问次数这是纯SQL流处理引擎很难做好的。当然Spark Streaming在吞吐量上和微批处理也有自己的优势但说实话真心追求实时性的场景Flink的灵活性和生态完整度更适合。更何况现在Flink CDC已经是数据库实时采集的事实标准配合Java开发效率很高。2. 数据采集层的工程落地三种来源一套规范数据采集是整个实时链路的起点也是脏活累活最多的地方。很多同学把精力都花在Flink计算逻辑上结果数据源没管好后面计算、展示全是垃圾进垃圾出。这里我按来源类型分开讲。2.1 日志类采集Filebeat Kafka是黄金组合服务端日志是最常见的实时数据来源。我通常用Filebeat做日志采集器它比Flume轻量太多部署就是解压一个二进制文件配置也简单filebeat.inputs: - type: filestream enabled: true paths: - /data/logs/*.log fields: app_name: order-service log_type: business output.kafka: hosts: [kafka1:9092, kafka2:9092, kafka3:9092] topic: app-order-log partition.round_robin: reachable_only: true这个配置看起来简单但有几个细节务必注意不要用filestream直接用Kafka producer consumer方式Filebeat自带背压机制Kafka不可用时会暂停读取本地文件不会丢数据。这是它作为采集端的核心理由。fields里打上应用名和日志类型标签后面Flink消费时可以根据这些字段路由到不同处理逻辑。每个应用单独一个topic或者至少按业务线分topic。我曾经见过所有应用混在一个topic里的架构Flink消费端要做大量过滤还会互相影响消费速度非常痛苦。2.2 数据库变更采集Flink CDC到底怎么部署热搜词里flink cdc pipeline部署和flink cdc安装部署出现频率很高说明这个方向已经成了实时数据平台的主流需求。Flink CDC基于数据库日志Binlog/Redo Log捕获变更不打业务表对业务系统零侵入。部署上有两种形态形态一Flink CDC作为Source接入Flink作业DataStreamSourceString stream env .addSource( MySqlSource.Stringbuilder() .hostname(localhost) .port(3306) .databaseList(shop) .tableList(shop.t_order) .username(cdc_user) .password(cdc_pwd) .deserializer(new JsonDebeziumDeserializationSchema()) .build() ) .setParallelism(1);这种形态适合在Flink作业里实时消费数据库变更。注意setParallelism(1)很关键因为单个MySQL实例的Binlog读取是单线程的并行度设置高了反而会出问题。形态二Flink CDC Pipeline独立部署如果你的目标是数据库实时同步到另一个存储可以用Flink CDC Pipeline也就是之前的CDAS它基于Yaml配置就能完成整库同步不需要写一行Java代码source: type: mysql hostname: localhost port: 3306 username: cdc_user password: cdc_pwd tables: shop\.* sink: type: doris fenodes: doris:8030 username: admin password: admin123Pipeline形态适合快速落地但是如果你想在同步过程中做数据加工比如字段映射、类型转换、过滤还是写Java代码更灵活。我的建议是同步裸数据用Pipeline需要加工用源码。关于Flink CDC最大的坑是存量数据与增量数据的一致性问题。Flink CDC默认会先做一次全量快照再切换到Binlog增量这个过程对数据库有一定压力。建议在业务低峰期做首次同步并且监控好源库的IOPS和连接数。2.3 业务主动上报HTTP SDK Kafka注意采样与限流有些数据源既不是日志也不是数据库而是客户端行为埋点前端点击、APP启动等。这时候通常是业务方直接调用HTTP接口上报你在接口里把数据写入Kafka。这个环节最常见的坑是突发流量打垮写入服务。我在某个项目中遇到过前端埋点日志突然暴增导致上报接口被瞬间打满Kafka客户端批量发送超时丢了一批数据。后来做了三层保护SDK端批量发送不要一条一条发HTTP请求在SDK内攒批比如攒够100条或500ms显著降低请求频率服务端限流单机QPS上限设置好超出部分直接丢弃并记录日志注意埋点数据丢几条通常不影响大屏指标趋势但要保证不拖垮服务Kafka端分区数规划根据峰值吞吐预估分区数分区数 目标吞吐量 / 单分区吞吐量。例如目标10万条/秒单分区吞吐约2万条/秒分区数至少5个数据采集层的通用规范也很重要。所有上报数据统一JSON格式包含event_id全局唯一、event_time事件发生时间、source数据来源、biz_body业务字段。有了这个规范后续Flink侧做解析、去重、Watermark定义都有据可依。3. Flink实时计算核心状态、时间语义与Sink的坑到了计算层就是Flink的主战场。这里我把最高频的三个技术点拆开讲这三个点也是面试和实战中最容易翻车的状态管理、时间语义、自定义Sink。3.1 状态与Checkpoint为什么你的作业重启丢数据Flink的状态State是它区别于普通流处理引擎的核心能力。简单理解状态就是算到一半的中间结果。比如你要统计每分钟每个商品的累计销售额这个累计值就需要保存下来这就是State。我见过很多使用者在应用里定义了一个MapState来保存用户维度的累计数据然后把Checkpoint间隔设置成5分钟。结果某个凌晨Flink作业因为OOM挂掉了恢复后发现损失了将近10分钟的统计结果。复盘时发现Checkpoint间隔太大状态恢复点太靠前中间的数据全丢了。这里必须记住一个基本参数组合state.backend: rocksdb state.checkpoints.dir: hdfs:///flink/checkpoints execution.checkpointing.interval: 60s execution.checkpointing.mode: EXACTLY_ONCE execution.checkpointing.timeout: 5min我的经验是线上作业至少每分钟做一次Checkpoint太频繁会影响性能但5分钟就太长了。另外一定要用RocksDB作为状态后端——数据量一大纯内存Heap状态分分钟把JVM堆撑爆。RocksDB是把状态写到本地磁盘内存只是缓存可靠性和容量都更好。3.2 事件时间与Watermark乱序数据怎么算Flink的窗口计算有个经典三选一ProcessingTime、EventTime、IngestionTime。做实时大屏我强烈建议用EventTime也就是按业务事件发生的时间来划分窗口。但EventTime带来的问题是数据可能乱序到达。用户点击发生在10:00:00的日志可能到10:00:30才到Flink。如果你正好在做每分钟点击量的滚动窗口这条数据就会被算到10:01的窗口里指标就错了。解决方案是Watermark水位线它表示事件时间小于等于这个值的数据都已经到达了。DataStreamOrderEvent withWatermark orders .assignTimestampsAndWatermarks( WatermarkStrategy.OrderEventforBoundedOutOfOrderness( Duration.ofSeconds(30) ) .withTimestampAssigner((event, timestamp) - event.getEventTime()) );forBoundedOutOfOrderness(Duration.ofSeconds(30))的意思是容忍最多30秒的乱序。代价是窗口结果会延迟30秒才输出。这里就是业务延迟和数据准确率的权衡。如果大屏指标允许延迟30秒这个配置就合理如果要求秒级延迟那就要接受部分乱序数据会算错窗口。窗口计算上我做实时指标统计会用TumblingEventTimeWindows滚动窗口AllowedLateness的组合stream.keyBy(OrderEvent::getProductId) .window(TumblingEventTimeWindows.of(Time.minutes(1))) .allowedLateness(Time.seconds(30)) .aggregate(new CountAggregate()) .process(new WindowResultFunction());allowedLateness的意思是窗口正常计算后还会等30秒的迟到数据迟到数据到达时单独触发一次计算输出更新。这样既保证了主链路结果快速产出又能修正部分乱序数据带来的误差。3.3 自定义DataSource与DataSink从入门到放弃再入门热搜词里flink 自定义 data source和flink 自定义 data sink出现频率极高我猜是因为官方文档的示例太简单一上生产就漏出各种问题。这里我把两个痛点讲透。自定义DataSource通常是为了从非标准源读数据。核心是继承RichSourceFunction或实现SourceFunctionpublic class MetricSource extends RichSourceFunctionMetricEvent { private volatile boolean running true; private transient KafkaProducer producer; Override public void open(Configuration parameters) { producer new KafkaProducer(...); } Override public void run(SourceContextMetricEvent ctx) throws Exception { while (running) { // 模拟读取外部数据源 MetricEvent event readFromExternalSystem(); synchronized (ctx.getCheckpointLock()) { ctx.collect(event); } } } Override public void cancel() { running false; } }注意两点一是collect操作必须在ctx.getCheckpointLock()锁内执行否则Checkpoint时的状态一致性会出问题数据可能重复或丢失。二是cancel()方法里要释放外部连接资源否则作业取消时连接泄漏时间长了会把源系统连接池打满。自定义DataSink的坑就更多了。我之前写过自定义Sink写入某个内部监控平台代码如下public class MonitorSink extends RichSinkFunctionMetricEvent { private MonitorClient client; Override public void open(Configuration parameters) { client MonitorClient.connect(monitor-server:8080); } Override public void invoke(MetricEvent value, Context context) throws Exception { boolean success client.send(value); if (!success) { throw new RuntimeException(send metric failed: value); } } Override public void close() { client.close(); } }这段代码看起来没问题生产上却出过事故监控平台的单机处理能力有限Flink端并发写入量一大client.send就频繁超时我让invoke直接抛异常结果Flink作业一直在重启上游Kafka消费被阻滞整个实时链路瘫痪。3.4 从事故学到的Sink设计原则那次事故之后我给自己定了几条Sink设计的铁律也分享给你写外部系统必须做重试和熔断不能一失败就抛异常重启作业。应该捕获异常做有限次数重试重试仍失败就写本地容灾文件或者发告警跳过保证主链路不中断区分业务错误和系统错误数据格式错误比如字段缺失属于业务错误直接throw没问题因为重试一万次也还是会失败外部系统不可用属于系统错误应该让作业保留现场继续运行等待外部系统恢复批量写入优先于逐条写入能批量就别单条单条写的性能开销太大了。Flink提供了JdbcBatchingOutputFormat支持攒批提交但要注意攒批参数batchSize和batchInterval要配合好另外热搜词里flink的jdbc连接器异常是个高频问题。我遇到过的大部分情况是连接池耗尽和连接空闲超时。Flink JDBC Sink的每个并发Task都会建自己的连接你在连接池里配置了最大连接数10结果Flink作业并行度是20直接就有10个Task拿不到连接报错。解决办法很简单要么把连接池最大连接数设成大于等于Flink并行度要么给连接设置合理的maxRetryTimes和connectionTimeout。4. 高频事故复盘Flink Sink到Hive表数据不落盘的根因这一节我要重点复盘一个几乎每个做Flink接数仓的人都会踩的坑——Flink sink Hive表数据不入表。这个热搜词出现得如此频繁说明大家都在这上面栽过跟头。我把排查链路完整还原出来你以后遇到可以直接照着查。4.1 现象与第一反应当时的情况是Flink作业运行状态正常没有报错但查询Hive表时发现数据一直是空的或者只有很久以前的一部分数据。我第一反应是是不是SQL写错了结果检查Flink SQL和Table Schema都对得上Kafka source也在正常消费。于是开始逐步排查。4.2 排查链路四个层面逐个击破第一层看Flink作业日志别被正常骗了打开TaskManager日志结果发现了端倪日志里出现了大量Need to partition the files into Hives format和Abortable相关的词。这个信息很关键——Flink写Hive是按照分区来管理的如果你没有开启自动提交分区数据写入的是临时目录永远不会变成Hive的正式分区。第二层确认Hive表的分区提交机制Flink写Hive表默认配置涉及两个核心参数。如果你的Hive表是分区表必须显式开启分区提交并且设置正确的提交触发策略CREATE TABLE hive_orders ( order_id BIGINT, product_id BIGINT, amount DOUBLE ) PARTITIONED BY (dt STRING, hour STRING) WITH ( connector hive, sink.partition-commit.trigger partition-time, sink.partition-commit.delay 0s, sink.partition-commit.policy.kind metastore,success-file );sink.partition-commit.trigger如果没配或者配成process-time意味着Flink按数据到达时间来决定提交分区不是按数据的事件时间。我当时就是用了process-time结果业务上凌晨的数据被算到了早上的分区等了一早上没看到该有的数据。第三层检查写入文件格式与可见性很多刚用Flink写Hive的同学不知道Flink写Hive默认是写ORC或Parquet格式文件到分区的临时目录然后通过Table Metastore注册分区。但文件从写入中到可见之间有一个提交环节。如果你看到HDFS上分区目录下已经有Parquet文件但查询不到数据大概率就是分区提交没有正确执行。还有一种可能是你写的是非分区表Flink写非分区表会把数据直接写到表的目录下。但我见过一个案例表本身是分区表Flink SQL里却只指定了分区字段的部分值导致Sink端认为这是一个不可写分区就一直默默丢数据。排查方法是用SHOW PARTITIONS hive_orders看分区元数据是否存在。第四层Hive Streaming协议与Metastore对接Flink写Hive底层有两种协议一种是通用的Hive Streaming API通过HiveTableSink另一种是直接写文件然后调用Metastore注册分区。前者需要开启hive.streaming.enabled老版本。如果你用的是较老版本的Flink和Hive建议用hive-streaming-client包并显式开启dependency groupIdorg.apache.flink/groupId artifactIdflink-connector-hive_2.12/artifactId version你的版本/version /dependency注意Flink和Hive的版本兼容矩阵很挑剔Flink 1.14之前和Hive 3.1.0有兼容问题Hive Streaming API在部分版本上是broken的。最稳妥的做法是Flink 1.15配Hive 3.1.2同时把Metastore从嵌入式切换为独立部署避免并发写入时Metastore锁冲突。4.3 问题根因与修复最终我们定位到了根因Flink作业里写Hive表的并行度设置过高默认等于Kafka分区数每个并发Task都在尝试写同一个分区的临时文件而且Flink内部会出现文件内容不完整的竞态。配合开启分区提交后问题消失。修复后的经验总结成一条Flink写Hive表并行度不建议大于1。因为Hive表Sink的文件写入不是天然按key分区的多个并行度同时写一个分区文件合并和提交的复杂度会指数上升。要么做rebalance并设置并行度1要么就用bucket功能把数据按字段散列到多个文件让Flink自己去整理。还有一个很小的点容易被忽略检查你的作业是在本地IDEA跑还是集群跑。本地跑Flink时HDFS路径如果写的是hdfs://...会直接连不上集群如果写的是本地路径file://...那数据其实是写到你个人电脑磁盘上Hive当然查不到。这种环境不一致问题我遇到过不止一次。5. 可视化大屏的实时感数据刷新频率、聚合策略与接口设计实时计算做完数据源源不断写入结果表了最后一步是可视化大屏。很多团队在这里其实没有技术问题但做出来的大屏看起来不实时——有实时数据却没有实时感。这节讲讲大屏之后端数据接口设计。5.1 大屏的数据不要直连数据库查询我刚做第一个实时大屏项目的时候犯过低级错误大屏前端每5秒轮询一次数据库原始明细表SQL里现场做SUM和GROUP BY。这种做法的结果是数据库CPU飙升、查询越来越慢、大屏的实时变成了每10秒才刷新一次因为查询耗时就占了5秒。正确的思路是打一层结果表。Flink实时计算出来的指标本来就已经按分钟/小时粒度聚合好了直接写入结果表比如dashboard_metrics大屏端每5秒查询的就只有几行聚合好的数据查询耗时基本在毫秒级。这才是实时大屏该有的性能。5.2 大屏接口的三种刷新模式轮询模式前端每N秒调一次后端接口适合指标值更新不频繁、需要简单稳定的场景。N一般设为5秒或10秒。WebSocket推送Flink侧结果更新时后端主动向已连接的大屏客户端推送数据适合大屏数量多、希望即时刷新、减少无效请求的场景。SSE流推送如果你只做单向数据推送SSE比WebSocket更简单基于HTTP协议兼容性和调试成本都低很多。这三个模式可以混合使用关键指标用WebSocket推送次要指标用轮询兜底。前端技术栈我用得比较多的是Vue ECharts大屏布局用Grid实现自适应。如果你不想花太多时间调布局可以直接用现成的DataV或者大屏编辑器但要注意编辑器的数据接入协议是否支持实时推送。5.3 减少大屏刷新压力聚合结果表 缓存策略大屏本身有几十个图表如果每个图表都单独去查一次结果表也是压力。我的做法是按业务场景把大屏所需的指标打包成一个JSON大接口一次查询返回所有图表的数据。比如实时成交大屏这个场景接口返回的数据结构大致是{ timestamp: 1715673600000, gmv: 102400.5, orderCount: 1287, userCount: 846, trend: [...], rankList: [...], geoDistribution: [...] }大屏端拿到这个JSON各自渲染对应的图表组件。这样一个接口的查询时间通常能控制在50ms以内刷新频率甚至可以提到1秒。还有一点给结果数据加Redis缓存。Flink写入结果表的同时把热数据同步一份到Redis大屏接口优先读Redis而不是查Doris或ClickHouse。Redis查询是纯内存操作性能远高于OLAP数据库。但要注意最终一致性——如果Flink写入结果表成功但写Redis失败缓存里就是旧数据。我的解决方式是结果表带一个update_time大屏接口拿数据时会比对Redis缓存时间和本地时间超过5秒则强制回源查结果表。5.4 大屏可视化的实时感还有视觉层面说实话大屏的实时感一半靠数据一半靠视觉设计。有几位项目里的前端同学总结过一些经验非常有效数字跳动效果关键指标成交额、订单数用滚动数字代替静态数字视觉上强化正在变化的感受刷新闪光提示每次刷新成功后给指标卡片加一个淡入的闪烁效果说明我更新了时序图的时间轴ECharts的时间轴坐标保持固定宽度数据向右侧推进给人一种趋势正在流动的感觉最后更新时间显示大屏角落永远显示数据截至 HH:mm:ss让使用者知道数据有多新这些都是细节但对于不懂技术的领导来说看起来实时和数据实时同等重要。6. 全链路延迟测量与容灾没有指标就没有发言权实时平台上线只是开始真正难的是让它稳定运行、出了问题能快速定位。这一节讲讲我怎么给实时链路做体检和急救。6.1 延迟指标每个环节都要有钟表我构建的任何实时平台都会在数据流里埋一个端到端延迟衡量机制。思路很简单在数据入口打上时间戳在每个关键节点记录观察时间。我在采集端会在每个事件的头部塞一个ingest_time然后Flink计算层、存储层、接口层分别在日志里记下当前时间。通过一条测试数据就能算出延迟环节计算方式常见瓶颈采集延迟Kafka收到时间 - 事件发生时间日志攒批时间过长、Filebeat端阻塞传输延迟Flink收到时间 - Kafka收到时间Kafka broker配置、网络带宽计算延迟Flink输出时间 - Flink收到时间窗口尺寸、状态大小、反压存储延迟数据库落库时间 - Flink输出时间Sink并行度、批量提交间隔展示延迟大屏收到时间 - 数据库返回时间前端轮询周期、接口查询耗时实操里我会写一个LatencyMonitor的Flink作业专门消费Kafka的监控topic解析每个事件的ingest_time并计算延迟分布P50/P95/P99再写入监控面板。延迟一旦超过阈值就触发告警。6.2 每个环节的容灾机制实时链路比离线链路脆弱得多任何一个环节抖动都会波及到后面。我的容灾设计分三层数据源头采集端必须保证数据不丢。Filebeat有本地backlog机制Flink CDC有Binlog位点记录Kafka有多副本。这三层可以保证即使整个实时平台崩溃数据还在源端或Kafka里躺着。Flink作业打开Checkpoint配合RestartStrategy自动恢复。我常用的策略是fixed-delay3次重试间隔10秒。如果3次都失败就不盲目重启了发告警让人工介入避免无限重启导致状态反复加载、Kafka消费位点反复跳跃的恶性循环。存储与展示结果表要设计幂等写入Flink重启后重放数据不会产生重复数据。大屏端接口要做降级——如果结果表查询失败至少返回缓存数据或者数据暂不可用的明确提示而不是白屏。6.3 数据积压是最大的坑三招止损实时链路最怕的故障就是数据积压——Kafka里堆积了大量未消费的数据Flink作业无论如何都追不上这时你看到的大屏是越来越旧的数据实时性彻底丢失。数据积压的典型原因和处理方式Flink作业遇到瓶颈看Flink UI的Backpressure指标如果Source端显示High/Medium说明是下游处理不过来需要增加并行度或优化算子逻辑如果Sink端显示High说明写外部系统慢了需要检查外部系统的连接池、批量参数。上游突然峰值流量比如大促秒杀采集量瞬间涨10倍。这时候Flink集群如果没有弹性扩缩容只能硬扛。我的建议是Kafka的topic保留时间设长一点7天等峰值过去后Flink作业自动追赶消费。Sink端故障比如ClickHouse或Doris暂时不可用Flink的Sink会积压数据在算子内部。如果积压太严重我在Doris不可用期间会临时把结果写到Kafka的另一个备份topic等Doris恢复后重放。数据积压其实是实时平台的急性病处理原则是先止损、后排查——先通过扩容或调整并行度把消费速度提上来再来分析瓶颈根因。反之如果先停下来查根因积压只会越来越多雪上加霜。6.4 关于实时平台到底需要多实时的一些个人体会做完整条链路我的体会是实时平台的技术难点从来不是某个单一组件而是整个链路的平衡工程。很多时候你不需要追求极致的秒级延迟只要端到端控制在10秒内大屏的体验已经相当好了。为了那个极致实时你付出的代价可能是系统复杂度翻倍、稳定性踩坑无数。给新手的最实际建议是先用最简单的方案跑通全链路——Kafka Flink 结果表 大屏接口把延迟指标测出来再针对瓶颈做优化。不要一上来就上CDC、上高级状态、上复杂窗口先把骨架立起来。数据和可视化这条路上跑通的那一刻获得的成就感比任何理论推演都来得实在。希望这篇实战经验贴能帮你少走几步弯路。
返回列表