1. 课程导入与场景锚定
在开始写任何一行代码之前,我们需要先把这门课要解决的问题“钉”在一个真实的位置上。所谓实时逐笔数据,指的是以单条记录为单位、持续不断到达、且每条记录都带有明确时间属性的数据流。它有三个典型来源:
- 交易类数据:委托下单、成交回报、撤单、账户资金变动。特点是单条价值高、顺序敏感、不允许丢失或乱序,往往还要求可追溯。
- 行情类数据:逐笔委托、逐笔成交、快照、盘口变化。特点是吞吐量极大、峰值突发明显,例如开盘集合竞价结束瞬间或极端行情下,单秒可达数万到数十万条。
- 日志类数据:网关访问日志、风控命中日志、系统运行指标。特点是写入持续、单条较小、允许极短的延迟,但长期累积体量惊人。
这三类数据有一个共同点:到达是“逐笔”的,而落盘是“昂贵”的。如果每来一条记录就立刻写一次磁盘或发一次数据库请求,系统会被 I/O 次数拖垮;如果为了省事把数据全部攒在内存里,一旦进程崩溃或机器宕机,未落盘的数据就全部丢失。这就是本课程要处理的核心矛盾——吞吐、延迟与可靠性之间的三角权衡。
为了把这个矛盾讲清楚,我们先看一条数据从产生到安全落盘的完整链路。下图展示了本节要建立的整体心智模型:数据源逐笔进入缓冲区,缓冲区按策略触发批量落盘,落盘结果再进入可校验的存储层。
从图中可以看到,整条链路的关键不在“写”,而在“什么时候写、写多少、写失败怎么办”。这三个问题分别对应缓冲触发策略、批量大小设计和可靠性保障。我们用一个具体的示例参数来感受一下量级差异(以下为教学假设,非实测):假设行情逐笔峰值 5 万条/秒,单条记录约 200 字节,即约 10 MB/s。若每条记录单独写一次文件,每秒 5 万次系统调用,开销几乎全部耗在 I/O 上;若改为每 500 条或每 200 毫秒批量写一次,写入次数降到每秒约 100 次,单次写入约 100 KB,吞吐和 CPU 占用都会显著改善,代价是最坏情况下约 200 毫秒的数据停留在内存中。
因此,本课程的整体任务链可以概括为四步递进:先建模——明确数据来源、字段结构、顺序与时间语义;再缓冲——设计队列结构、容量上限、触发条件与背压策略;然后落盘——实现批量写文件或批量入库,处理刷盘、重试与幂等;最后验证——通过位点、条数对账、回放校验确认“不丢、不重、不乱序”。
需要特别提醒的是,缓冲不是“把数据堆在内存里等一等”这么简单。缓冲区一旦引入,就同时引入了三个必须回答的问题:内存上限是多少(防止 OOM)、满了之后怎么办(阻塞上游、丢弃低优先级数据还是告警降级)、进程崩溃时未落盘的数据如何界定损失范围(这决定了批量大小和刷盘频率的下限)。这三个问题会在后续章节逐一展开,而本节只需要建立一个判断标准:任何缓冲方案,都必须能清楚说出它的“最大丢失窗口”和“最大内存占用”。
最后,我们用一句话锚定本课程的立场:逐笔数据的第一价值是“完整与有序”,第二价值才是“快”。批量落盘是为了让系统扛得住吞吐,但绝不能以悄悄丢数据为代价。后续所有设计,都会围绕“在可接受的延迟与内存成本下,保证数据完整、有序、可校验地落盘”这一目标展开。