ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

广电大数据可视化全流程:数仓分层、ECharts大屏与指标口径治理

广电大数据可视化全流程:数仓分层、ECharts大屏与指标口径治理 干广电数据这行快八年了从最早拿Excel拉机顶盒回传日志、人工拼收视日报到后来带队搭Hadoop集群、做数据可视化平台中间踩的坑能写一本小册子。广电这个行业做数据可视化和互联网公司做大屏完全是两码事数据源杂、口径乱、样本不全、领导要看的和运营要看的不是一张图而且大部分场景对实时性没那么多执念日报、周报、月报才是主战场。这篇就把我这些年做广电大数据可视化的完整思路摊开讲——从数据源梳理、指标口径定义、数仓分层建模到ECharts大屏实现、集群容量估算、上线后天天被问这个数为什么和昨天不一样的排查方法。不管你是刚入行做数据开发的新人还是正在找数据可视化项目练手的学生或者被临时抓来接手广电大屏的运维老哥都能从里面抄到能直接用的东西。1. 广电大数据到底长什么样先搞清楚你手里有什么料做可视化最容易犯的错是先挑图表、先想配色最后才去对数据。我见过太多项目大屏UI做得跟科幻电影一样上线三天就没人用了因为图上的数字业务不认。所以在动手写第一行SQL之前先把数据源摸清楚这一步花的时间越久后面返工越少。1.1 四类核心数据源与它们的脾气广电体系里的数据按我实际接触的情况大致分四类每一类的采集方式、数据质量、更新频率都不一样做可视化时的处理策略也完全不同。第一类是播出与EPG数据。这是最干净的一类来自播出系统和节目单系统本质是结构化的节目排期表频道、节目名称、开始时间、结束时间、节目类型、时长。它的特点是准确、稳定、体量小一天全国几十个频道的排期也就几千条记录。但它的坑在于人工维护——节目临时调整、插播、延后EPG如果没同步你算出来的时段归属就是错的。我的习惯是每天凌晨跑一次EPG和实际播出日志的差异比对差异超过阈值就告警。第二类是终端回传数据也就是机顶盒、IPTV终端、OTT盒子回传的行为日志。这是广电数据里体量最大、最有价值、也最脏的一类。典型字段包括设备号、账号、频道号、事件类型开机/切台/关机/点播/暂停、事件时间戳、终端型号、区域编码。单台终端一天能产生几十到几百条记录百万级终端就是亿级记录量。脏点在哪设备号重复、时间戳漂移、区域编码为空、切台事件和开机事件乱序到达、时移回看和直播混在一起。这些不处理直接上大屏报表口径必然打架。第三类是BOSS与计费数据。用户订购关系、套餐、缴费记录、停机复机状态。这类数据在关系型数据库里结构规范但涉及用户隐私出库到分析层之前必须做脱敏处理账号ID要做哈希映射绝对不能把手机号、身份证号直接落到大屏上。这一点不是技术问题是合规红线团队里必须有人盯。第四类是运维与客服数据。网络质量指标丢包率、信噪比、光功率、设备告警、客服工单。这类数据流式特征强适合做实时监控大屏而不是做经营分析大屏。我一般把它们拆成两个独立的可视化产品不要混在一个页面上否则页面信息密度过高看的人抓不住重点。1.2 广电大屏和互联网大屏的根本差别很多人拿互联网那套数据指标体系往广电上套结果处处别扭。差别主要在三个地方。第一分析单元是户不是人。一个家庭可能有多台终端、多个账号回传上来的设备数是终端数但业务关心的是家庭数。你得先做设备到家庭的归并归并规则通常靠BOSS里的账号关系或者同IP同区域加设备绑定关系来推这一步做不干净用户规模指标就会虚高两到三成。第二时效性要求分层明显。领导看的经营看板T1更新足够运营做节目编排优化的需要小时级运维盯网络质量的才需要秒级。我早期吃过亏把三个场景的需求全塞进一套实时链路Kafka、Flink全上结果成本和维护复杂度爆炸实际上80%的图表根本不需要实时。后来改成离线为主、准实时为辅、实时只做告警的三层策略集群规模直接砍了一半。第三可视化受众分三种视角。管理层视角讲趋势和对比图要少、要大、要一眼看懂运营视角讲明细和下钻需要能点进去看某个频道某个时段的曲线运维视角讲异常和定位需要能按区域、按设备型号筛。这三种视角对图表类型的要求完全不同硬塞进一个大屏必然失败。2. 整体架构设计与技术选型别一上来就堆重型方案架构这件事原则只有一条用能被你和你的团队维护得起的最简方案。我见过一个地市级项目数据量一天不到50GB结果上了十几个组件的全家桶最后运维的两个人谁也说不清数据从哪流到哪。2.1 从采集到展示的五层链路我目前用的链路稳定跑了三年结构是五层。采集层终端回传日志走消息队列Kafka落盘EPG和BOSS数据走定时抽数Sqoop或者自写的JDBC抽取任务网络质量数据走Flume采集。关键设计是Kafka的Topic按日期分区保留7天方便回溯重放。存储层明细数据落HDFS用Parquet列式存储按天分区。维度表放Hive外部表或者直接放MySQL量小、更新少、需要频繁关联的放关系库更快。计算层离线用Spark SQL或者Hive on Spark做T1批处理准实时用Spark Structured Streaming做小时级聚合实时告警用Flink做窗口统计。注意这里我刻意避开了什么都用Flink的诱惑批处理仍然用Spark因为大部分数据开发同事对Spark SQL更熟维护成本低。服务层聚合结果落MySQL或者ClickHouse。这里的选择很关键——如果大屏查询需要多维组合、秒级响应ClickHouse几乎是最优解如果只是固定几张报表MySQL加缓存就够。我一般把ADS层的宽表落到ClickHouse因为是列存做聚合查询比MySQL快一到两个数量级。展示层前端统一用ECharts配合大屏框架做自适应。后端提供一个统一的查询接口服务按页面-图表的粒度封装成接口不让前端直接拼SQL。2.2 选型对比自研、开源、商业BI怎么选方案适合场景优势代价商业BI工具报表需求固定、业务人员自助取数上手快、拖拽出图、权限体系成熟授权费高、大屏定制能力弱、数据量大时性能受限自研ECharts大屏定制化大屏、领导驾驶舱视觉自由度最高、性能可控、无授权成本前端工作量集中在细节上维护需要专人开源可视化平台中等规模、需要自助分析免费、组件丰富、能二次开发部署运维复杂、版本升级容易踩坑纯Python出图内部周报、分析师自用开发最快、和pandas无缝不适合做交互式大屏我实际的选择通常是混合领导驾驶舱用自研ECharts大屏视觉和交互完全可控业务部门的自助取数用开源BI工具或者轻量的报表服务分析师的临时分析直接用Python出图。三种场景三种工具不追求统一。2.3 数仓分层ADS层才是大屏的真正数据源这套分层几乎是行业惯例但我强调一下每层的职责边界因为边界不清是后期口径混乱的根源。ODS层原始数据落地不做任何清洗保留全量字段。这一层只增不改出问题可以回溯。DWD层清洗、去重、脱敏、标准化。设备号做哈希时间统一到时区区域编码补全事件类型做枚举映射。这里最关键的产出是用户行为明细事实表一行一个事件。DWS层按主题做轻度聚合。比如频道-小时-区域粒度的收视汇总设备-日粒度的活跃汇总。这一层的目标是让下游不用重复做同样的group by。ADS层面向具体图表做宽表。一张ADS表对应大屏上的一到两个图表字段名直接和图表需求对齐。宁可多几张表也不要让前端做复杂关联。提示ADS层表名建议带上业务域和更新频率前缀比如ads_rating_channel_hour_d、ads_user_active_region_m团队协作时一眼就知道能不能用。3. 指标口径与数据建模这一步错了大屏全废技术实现可以慢慢调口径错了是灾难性的——业务看到数字不对整个平台的可信度就崩了。我在项目里坚持一件事所有指标必须有书面定义包括公式、数据来源、过滤条件、更新频率写进字典表谁改谁签字。3.1 收视类指标的公式与计算口径这是广电最核心的一组指标公式本身不复杂难的是口径统一。到达率Reach统计周期内至少观看过某频道/某节目一次的户数除以统计范围内的总户数。注意至少一次这个定义意味着要去重SQL里就是count(distinct household_id)。收视率Rating统计周期内某频道/节目的总收视时长除以总户数 × 统计周期时长。这个是加权概念不是简单计数。市场份额Share某频道收视时长除以所有频道收视时长之和。分母是正在看电视的人不是全部用户这一点经常被混淆。人均收视时长总收视时长除以到达户数反映的是粘性而不是覆盖。时长怎么算这是个实操难点。回传数据里是离散事件一次完整的收视行为是切台进入-切台离开这样一个区间。我的处理方式是在DWD层用窗口函数按设备号时间排序把相邻的进入和离开事件配对算出区间时长。对于跨天的问题按自然日切分区间超长的异常区间比如超过12小时没关机要做截断处理否则会污染时长指标。-- 按设备配对计算单次收视时长简化版 select device_id, channel_id, start_time, end_time, unix_timestamp(end_time) - unix_timestamp(start_time) as duration_sec from ( select device_id, channel_id, event_time as start_time, lead(event_time) over ( partition by device_id order by event_time ) as end_time, event_type from dwd_user_event where dt ${bizdate} and event_type in (switch_in, switch_out) ) t where event_type switch_in and end_time is not null and unix_timestamp(end_time) - unix_timestamp(start_time) between 1 and 43200;上面那个between 1 and 43200就是12小时截断实测能过滤掉大部分异常数据。3.2 用户画像标签怎么落地广电做画像标签体系不用追求互联网那种几千个标签的规模落地二三十个高价值标签就够用了。我一般分四类基础属性区域、入网时长、套餐档位、终端型号。行为属性日均观看时长、活跃时段、开机频次、点播偏好。内容偏好最爱看的频道TOP3、节目类型偏好新闻/影视/少儿/体育、是否偏好回看。价值属性ARPU分层、付费点播频次、流失风险等级。标签计算放DWS层用宽表的方式按户一行输出。这里有个经验标签更新周期不要都设成日更。基础属性月更就够行为属性日更价值属性周更。全部日更会让计算资源浪费得厉害而且标签抖动会让人困惑——今天用户是高活跃明天变成中活跃运营看了会来问你系统是不是坏了。解决方法是在标签上加一个稳定性窗口连续3天满足条件才切换状态。3.3 时间维度和区域维度最容易踩的坑时间维度上有三个坑我反复遇到。第一时区。如果数据源里有UTC时间一定要在DWD层统一转成业务时区不要留到前端转。第二时移回看。用户晚上11点点播昨天的节目这条记录的时间应该是观看时间而不是节目播出时间但统计节目收视时又要按节目时间归属。这两个口径要分开建两张表。第三直播延时。同一个节目在不同区域的播出时间可能差几秒到几分钟做跨区域对比时要做时间对齐否则曲线会错位。区域维度上的坑主要是编码不统一。BOSS系统里是一套区域编码网络管理系统里是另一套终端回传里可能是最粗的行政区划。必须在DWD层建一张区域映射维表把三套编码打通映射不上来的数据单独归档不要默认丢掉——我见过丢了12%的数据导致某地市报表明显偏低的案例。4. 可视化大屏实现从布局规范到ECharts实操前端这块我踩的坑最多因为代码写对了但效果不对的情况太常见。大屏做得好不好一半看数据一半看视觉。4.1 大屏布局与视觉规范我做大屏有几条硬性规矩团队里新人都要先背下来。一是三秒原则。任何一张图用户三秒内看不懂它在说什么就该改。这意味着标题要写清楚什么指标什么范围什么时间比如全市数字电视日均开机户数近30天而不是只写开机户数。二是数字要大图要少。领导驾驶舱上核心KPI用大号数字卡片展示一屏不要超过8个图。我见过一屏塞20个图表的大屏实际使用中根本没人看。三是配色统一且有语义。不要彩虹色乱刷同一含义用同一颜色。增长用一套色、下降用另一套但要避开大面积红绿部分人群色觉差异看不清。背景用深色系图表主体色相控制在3个以内辅助色用于高亮。四是分辨率适配。大屏通常跑在超宽屏上比如3×3拼接或者3840×1080布局要用相对单位百分比、rem、vw/vh不要写死像素。字体最小不低于14px拼接屏实际观看距离远太小了看不清。4.2 ECharts关键配置与可直接复用的代码下面这段是我常用的暗色系柱状图配置做过大屏的可以直接拿去改。const option { backgroundColor: transparent, title: { text: 各区域日均开机户数, subtext: 统计周期近7天 单位万户, textStyle: { color: #d7e6ff, fontSize: 18, fontWeight: 500 }, subtextStyle: { color: #7f96b8, fontSize: 12 } }, grid: { top: 80, left: 60, right: 30, bottom: 50, containLabel: true }, tooltip: { trigger: axis, axisPointer: { type: shadow }, backgroundColor: rgba(12,30,56,0.9), borderColor: #2b6cb0, textStyle: { color: #e6f0ff } }, xAxis: { type: category, data: [], axisLabel: { color: #9db3d0, fontSize: 13, interval: 0, rotate: 0 }, axisLine: { lineStyle: { color: rgba(140,170,210,0.3) } } }, yAxis: { type: value, axisLabel: { color: #9db3d0, fontSize: 13 }, splitLine: { lineStyle: { color: rgba(140,170,210,0.12) } } }, series: [{ type: bar, barWidth: 42%, data: [], itemStyle: { borderRadius: [4, 4, 0, 0], color: { type: linear, x: 0, y: 0, x2: 0, y2: 1, colorStops: [ { offset: 0, color: #4facfe }, { offset: 1, color: #1a4f8a } ] } }, label: { show: true, position: top, color: #cfe4ff, fontSize: 12 } }] };配置里有几个细节值得说。grid的containLabel: true一定要开否则坐标轴标签会被裁掉这是新手最常见的白边问题。axisLabel的interval: 0让类目名全部显示区域名多的时候要配合rotate: 30否则会重叠。渐变色用linear类型比纯色更有质感但两个色值不要太跳。4.3 数据量大时的渲染优化大屏卡顿通常不是ECharts本身的问题是数据量和更新频率的问题。我的优化顺序是这样的。第一步先看数据量。如果一个系列超过2000个点折线图基本就不用看了改做聚合或者加sampling: lttb。ECharts内置的LTTB降采样特别适合长时间序列视觉上几乎无损。第二步减少重绘。大屏轮播刷新时不要每秒都调setOption重建全部配置用setOption(option, false)做增量更新并且把不变的配置项坐标轴、标题分离出去只设一次。第三步处理分页轮播。表格类内容用dataZoom或者手写轮播索引不要用CSS动画直接改DOM。我见过用CSStransform做滚动列表的60条数据就掉到20帧改成JS定时替换内容后稳定60帧。第四步控制定时器。一个页面上如果有5个图表各自每秒刷新加上背景动画浏览器会累。我的做法是统一用一个定时器按顺序错峰刷新不同图表间隔控制在3到5秒业务上完全够用。注意定时器一定要在组件销毁时清理setInterval不清理的话路由切换几次之后内存就上去了大屏长时间运行会直接崩掉这是生产环境最常见的稳定性事故。5. 部署与运维集群容量怎么估数据质量怎么盯很多人觉得大屏上线就完事了实际上运维才是真正的长跑。5.1 集群容量估算的实操算法容量估算不用算得很精确但必须有个量级判断。我给你一套我常用的算法。假设地市规模100万终端每终端每天产生500条行为日志单条日志平均0.5KBJSON文本。日增原始数据100万 × 500 × 0.5KB 250GBParquet列存压缩比按5:1算约50GB/天保留90天50GB × 90 4.5TBHDFS三副本4.5TB × 3 13.5TB加上中间表、维度表、临时表整体乘以1.5的系数约20TB生产环境建议按60%水位规划实际采购容量33TB左右内存和CPU怎么估离线批处理作业一般按单核处理10GB压缩数据/小时这个经验值算。50GB日增要求3小时内跑完至少需要2个core但考虑Spark的shuffle和并发作业我一般按8到16个core配置。内存按core数的4倍GB给也就是32到64GB。这套算法不精确但足够你写采购申请和做初期规划。准实时链路小时级用的是Structured Streaming资源需求比离线低但要注意微批的触发间隔设置——间隔太短小文件多间隔太长延迟高。我通常设5到10分钟。5.2 调度与数据质量监控调度用Airflow或者DolphinScheduler都行我倾向DolphinScheduler可视化配置、对国内团队友好、上手快。关键是要建立依赖关系ODS抽取完成 → DWD清洗 → DWS聚合 → ADS宽表 → 刷新缓存 → 通知大屏。中间任何一步失败下游不启动并且要有人收到告警。数据质量监控我通常埋三类规则规则类型具体做法触发动作完整性关键字段非空率低于95%告警阻断下游时效性分区数据未在约定时间产出告警波动性核心指标同比或环比偏离超过30%告警人工确认唯一性主键重复率高于0.1%告警一致性明细汇总与报表口径不一致阻断并回滚波动性规则最有用也最容易误报。节假日、重大赛事、系统割接都会造成真实波动所以这条规则我一般设成告警但不阻断让人来判断。6. 常见问题与排查技巧实录这部分是我这些年被问最多的问题整理成速查表遇到直接查。6.1 这个数和昨天不一样怎么排查这是每天都要面对的问题我总结了一个固定排查顺序照着走基本十分钟内能定位。第一步确认是不是口径变了。翻指标字典的修改记录看最近48小时有没有人改过公式、过滤条件或者数据源。改口径不改文档是团队里最常见的混乱源头。第二步确认数据是否完整产出。看ODS到ADS每一层分区的记录数和历史均值对比。如果某一层少了往上游追。我遇到过好几次是新终端型号上线后日志格式变了清洗规则没跟上导致这部分数据被静默丢弃。第三步看是否有重复数据。终端回传在网络抖动时可能重发如果DWD层去重规则写得松就会重复计数。检查方式是看主键设备号事件时间事件类型的唯一性。第四步看维度关联是否丢失。比如区域映射维表更新后某些编码映射不上了join之后变成null被过滤掉数字就会掉。这种情况最隐蔽因为每一步SQL都成功了。第五步看时间边界。跨天任务如果用的是dt ${bizdate}而数据延迟到凌晨2点才落完就会漏掉尾巴。解决方案是把调度时间从凌晨1点推到凌晨3点或者用事件时间而不是处理时间做过滤。6.2 大屏卡顿、白屏排查表现象可能原因排查方法处理方案首次加载慢接口返回数据量过大看Network面板接口大小和耗时后端分页或聚合单个接口返回不超过500条页面卡顿掉帧定时器过多或数据点过多Performance面板录制看长任务统一定时器折线图开启LTTB采样白屏JS报错导致渲染中断看Console第一条报错给每个图表加try-catch单个图表失败不影响全局长时间运行后崩溃内存泄漏看内存曲线是否持续上涨清理定时器和事件监听重载页面兜底图表模糊canvas分辨率未适配DPR检查devicePixelRatio初始化时传入devicePixelRatio: window.devicePixelRatio饼图标签重叠扇区过小或标签未防重叠看小比例扇区合并小项为其他开启labelLayout防重叠补一个小技巧大屏部署在拼接屏上时浏览器建议用Kiosk模式启动并在URL上加一个版本参数配合自动刷新策略比如每4小时重载一次页面能有效规避长时间运行积累的内存问题。6.3 常见误区清单做广电数据可视化这几年我看到的高频误区有这些值得提前避开。误区一先做大屏再补数据治理。顺序反了一定是先有稳定的数据链路再做可视化。反过来做就是不停地改图表去迁就脏数据做到最后没人信。误区二追求全指标覆盖。一张大屏塞30个指标结果每个都没人看。我通常的做法是先上线5到8个核心指标跑一个月看点击率和反馈再迭代。误区三忽略数据权限。同一个平台不同角色看到的数据范围应该不同。地市只能看本地市省级能看全省这个必须做在接口层不能只做在前端隐藏。误区四不做离线兜底。实时链路一旦挂掉大屏就空了。我的方案是所有实时指标同时保留一条T1的离线结果实时数据不可用时自动降级显示离线数据并打上标记。7. 小成本起步从练手项目到生产系统的两条路有不少人是通过课程实训或者毕设项目接触数据可视化的我经常被问我这个项目能不能算企业级。说实话能不能算差别不在于图表好不好看而在于有没有处理真实的数据复杂度和运维场景。7.1 个人练手的最小可用方案如果你想在有限资源下做一个完整的广电风格数据可视化项目我建议这样搭用Python生成一份模拟的机顶盒回传日志可以是CSV几十万行字段包括设备号、区域、频道、事件时间、事件类型。用pandas做清洗和聚合把结果写进SQLite或者MySQL。前端用ECharts做一个单页大屏包含四个图表区域开机户数柱状图、频道收视份额饼图、近30天活跃趋势折线图、节目类型偏好横向条形图。整个项目跑在一台笔记本上完全够。关键是要把数据清洗的环节做出来而不是直接拿干净数据画图。比如在生成数据时故意加入5%的重复记录、3%的空区域编码、2%的时间戳异常然后写清洗逻辑处理掉。这一步做扎实了面试时讲起来完全不一样因为你真的踩过坑。7.2 从demo到生产要跨过三个门槛我面试过不少简历上写着数据可视化项目的同学问了三个问题基本就分层了。第一你的数据量多大什么存储查询延迟多少能答出具体数字和选型理由的说明真的跑过。第二你的指标口径怎么定的有没有文档这是工程意识和业务意识的体现。第三如果半夜数据没产出你怎么知道这一问是区分会画图和能维护系统的分水岭。对应的三个门槛就是存储与查询的工程能力从CSV到列存数据库、指标治理能力从随手写到有字典、可观测能力从人肉检查到自动监控告警。跨过这三个你的项目就真的能拿出去讲。最后分享一个我自己的习惯每做一个新的数据可视化项目我都会先写一份数据字典把每个指标的名称、公式、数据来源表、更新频率、负责人写清楚放在项目根目录。这份文档看起来不起眼但它是整个项目最值钱的东西——三个月后你自己回来看或者新人接手全靠它。我踩过最惨的一次坑就是接手一个没有字典的项目为了搞清活跃用户到底是按开机算还是按有观看行为算翻了三天代码。从那以后字典先写图后画。
返回列表