做实时计算的朋友,可能都遇到过这种情况:明明 ORC 格式在批量处理时超好用,存数据省空间、查数据还快,可一放到实时计算里,就各种掉链子 —— 数据更新半天刷不出来,处理延迟高得吓人,眼睁睁看着实时推荐、监控预警这些场景没法用。今天咱就好好聊聊,ORC 文件格式在实时计算里到底有哪些坎儿,为啥它在批量处理里的优势,到了实时场景就成了短板,一起往下看吧!
限制 1:写入速度跟不上,实时数据存不及时
ORC 格式为了压缩好、查询快,在写入数据时会做很多 “额外工作”—— 比如把数据按列排序、建索引、做压缩编码。这些工作在批量写入时没问题,反正一次处理一大批,多花点时间不算啥。但实时计算不一样啊,数据是一条一条或者一小批一小批来的,比如电商平台每秒都有新订单,得马上存起来供后续计算用。
这时候 ORC 的写入流程就显得太 “笨重” 了。有个做实时监控的朋友说,他试过用 ORC 存实时日志,结果每秒 1000 条数据进来,ORC 写入就卡得不行,延迟能到 5 秒以上,监控大屏上的数据根本没法看。后来换成别的格式,延迟立马降到 0.5 秒以内。
ORC 写入时还得等数据攒到一定量才会真正落地成文件,就像快递要凑满一车才发车。可实时计算要的是 “随到随存”,这种 “凑数” 的机制,天然就和实时性拧着来。这或许暗示,ORC 的设计初衷就不是为了应付高频次的小批量写入。
限制 2:实时更新难如登天,改条数据太费劲
实时计算里,数据不是一成不变的,比如用户改了收货地址,订单状态从 “待付款” 变成 “已付款”,这些变动得马上反映到数据里。但 ORC 文件是 “整块” 存储的,就像一本装订好的书,你想改中间某一页的某个字,不能只改那一个字,得把整本书拆开,改完再重新装订 —— 这就是 ORC 的 “不可变特性”。
有网友分享,他在做实时订单系统时,用 ORC 存订单数据,用户取消订单后,系统要更新订单状态,结果每次更新都得把整个 ORC 文件读出来,改完再重新写回去,小文件还好,大文件动辄几分钟,实时性完全没法保证。后来他发现,ORC 的更新本质上是 “覆盖写”,不是 “增量改”,这在实时场景里太致命了。
更麻烦的是,ORC 文件还会定期合并(比如小文件合并成大文件),合并的时候整个系统都得停一下,实时计算最怕的就是这种 “中场休息”,数据处理一断,后续的分析结果就全错了。
限制 3:跟流处理框架 “不对付”,兼容问题一堆
实时计算离不开流处理框架,比如 Flink、Spark Streaming 这些,它们就像实时数据的 “传送带”,得把数据快速送到计算引擎里。可 ORC 格式跟这些 “传送带” 的配合,总有点磕磕绊绊。
比如用 Flink 读 ORC 文件时,经常会遇到 “schema 不兼容” 的问题 ——ORC 文件的列结构稍微变一点,Flink 就不认了,得重启任务才能解决。有个做实时用户画像的团队,就因为每天新增一个用户标签(ORC 文件多一列),Flink 任务天天报错,后来不得不放弃 ORC,换成了更灵活的格式。
而且流处理框架更习惯处理 “行式数据”,ORC 是 “列式存储”,读数据的时候得把列转换成行,这个转换过程也会拖慢速度。就像你要从一堆按列摆放的积木里,快速找出某一行的积木,总得花点时间翻找。
不过话说回来,某些实时场景下 ORC 也能凑合用
虽然 ORC 在实时计算里限制不少,但也不是完全不能用。如果你的实时计算对延迟要求不高,比如 5 分钟以内的准实时场景,ORC 的压缩和查询优势就能体现出来。比如每隔 5 分钟统计一次网站访问量,用 ORC 存数据,既能省空间,计算的时候读数据也快,这时候它的限制就没那么明显了。
还有些场景,数据写入后基本不更新,只是一个劲地追加新数据,比如实时日志收集(只存不改),这时候 ORC 的写入延迟虽然比别的格式高,但胜在存储成本低,查历史数据方便,也算有得有失。
小编的一点实在话
ORC 文件格式就像一把好刀,切大块肉(批量处理)特别顺手,但要切精细的肉丝(实时计算)就不太合适。它的优势 —— 压缩好、查询快,都是建立在 “批量处理”“少更新” 这些前提上的,放到实时计算这种 “高频次、快响应、常更新” 的场景里,自然就显得吃力。
要是做实时计算,优先考虑那些为流处理设计的格式,比如 Parquet 的某些变种,或者专门的流数据格式。当然了,具体用啥还得看场景,要是准实时、数据不怎么改,ORC 也不是不能用,毕竟省空间这一点太香了。
对了,ORC 在实时计算里的某些限制,比如小文件合并慢,具体为什么会这么慢,我还没完全搞懂,可能跟它的索引结构有关,有懂行的朋友可以留言说说。总之,别指望 ORC 能包打天下,选对工具比啥都重要。