前言
随着近些年来实时技术的不断成熟,越来越多的企业投身到实时业务场景的开发和使用当中,其中证券、保险、银行等金融行业使用的尤为甚之。以证券行业的场景为例,核心的业务场景是围绕业务交易展开。本文将向大家展开证券行业内实时开发的业务场景以及「定时启停」一个简单却又实用的功能介绍,欢迎共同交流探讨。
01
实时能做什么?
对于实时开发,很多人会有这样的疑问:
-
指标还是那个指标,实时开发只是提高了指标结果产出的速度,有什么意义嘛?
-
除了提高数据计算的速度,实时开发还能做哪些场景呢?
-
实时任务需要持续运行,对于资源的占用不会很高么?集群规模有限,需要同时执行离线和实时任务难道只能加机器?
诸如此类的问题还有很多,但万变不离其宗。我们在引入实时开发这一新的开发链路时,首先要明确实时开发将会如何在当前已有的开发场景中接入与结合,归纳总结为以下三方面:
1. 直接缩短数据计算过程
顾名思义,实时计算是基于当前产生的数据进行快速计算得到数据结果的开发方式,不同于离线开发周期性的对一批数据进行计算,实时计算中每一条数据从业务端产生后都会直接计算,并产出结果发送给下游或进行存储,整个过程有着极小的延时,且极少有繁复的「分支」,通常是一条链路直通到底,就像河流一般,所以实时计算也被称之为“流式计算”。
实时计算可以将关键指标的生产周期从小时、分钟级缩短至秒级甚至亚秒级别。
更快的计算过程意味着更精确的数据结果。例如基金估值计算,通常需要大盘与股票的动态数据与股指占比等静态数据计算得到,通过缩短生产周期我们可以得到更为精细的基金估值变化情况。
2. 实现基于数据流的事件监控场景
事件监控在证券行业内其实更为常见,例如对股票交易中虚假申报、拉台打压股价、维持涨跌幅限制价格、自买自卖和互为对手方交易、严重异常波动股票申报速率异常等异常交易情况进行监控。
这些异常数据被采集到消息中间件中,实时任务通过提取不同的监控指标来识别业务流程中可能存在的风险行为并通知内部告警系统,去触发基于规则的账户锁定和人工二次审核。
通过实时任务可以实现完善的监控与预警体系,帮助企业加强对于数据中潜在风险的感知和应对能力。
3. 作为营销、监管等业务场景的助力器
实时任务除了直接进行关键指标快速计算和事件监控外,仍在智能推荐、算法计算等领域有较多的应用。在金融类产品推广和营销的场景中,通过将埋点系统获取的用户行为数据进行实时采集,与训练后的算法模型进行匹配和计算,最终将符合用户投资习惯的产品推荐给用户,助力了付费用户转化比例的提高。
除了上面提到的三大部分,其实还有基于风险识别、行为感知、贷前审计等多场景的价值。实时开发对于企业本身的数据能力是一种与离线不同场景的增强,在实时中我们基于流式数据能够挖掘更为丰富的场景,为企业带来新的发展。
02
怎么提高资源利用?这是道开放题
从以上提到的三大场景中,相信有不少人已经蠢蠢欲动了,看起来实时能做的比自己想象得还要多,赶紧跟自己的开发沟通沟通给安排上。然后被开发泼上一盆凉水:集群资源不够用。
在我们许多客户地方也都有相似的问题产生,毕竟引入实时意味着全新的开发线路,有技术的投入,有资源的损耗,有架构的调整,而实时带来的收益可能并没有那么直观,所以大家都抱着“摸石头过河”的心态,极少数才愿意在项目初期投入大量资源。
在集群资源并不充裕的前提下,如果要持续运行实时任务同时周期性调度离线任务,对于整体的任务执行和集群稳定性都会带来较大的压力,极有可能出现离线任务执行时间加倍,同时实时任务处理的数据延迟还特别大的情况。
而券商场景中缓解这一问题的方法也非常简单。
首先,实时开发底层引擎Flink本身具有Global CheckPoint检查点机制,能够将任务运行过程中的状态和数据本身以「快照」的形式保存下来。当任务停止后,用户可选择指定CheckPoint进行续跑操作,此时任务将会恢复对应状态,从上次的计算结果继续向下执行,不会出现丢数的情况(根据所选择的CheckPoint点位可能会存在数据重复的情况)。这就为我们对实时任务的启停提供了技术上的可能性。
其次,在券商场景中,离线与实时任务执行时间天然有所区别。券商的业务时间段比较集中,大量交易会集中在9:30-15:00之间,即便是收盘后的交易,也会由委托交易系统在第二天开盘时间集中在连续竞价、集中竞价阶段分别提交。因此针对于交易相关的实时任务并不需要24h全天运行,只需要在白天稍早于开盘时间启动,保证委托交易系统提交的数据能够纳入计算,下午收盘后保证当天业务数据已计算完毕后再保存CheckPoint并停止即可。而离线开发的任务实例执行通常在晚上,等待业务系统数据变化较小时进行T+1的数据计算。
所以,只需要每天收盘后用户手动将实时任务停止并保存CheckPoint,然后在第二天开盘前将任务续跑起来就可以实现离线、实时资源的最大化利用了。不过听起来似乎还有一些些麻烦?其实,想要实现自动启停只需要解决三个问题:什么日子启停、什么时候启停、什么方式启停。
那不妨来看看我们的实时开发StreamWorks是如何通过「启停策略」来解决这一麻烦的吧!
在实时开发的项目管理中,用户可以创建不同的启停策略,像券商每年年初会有交易日历敲定,实时支持用户通过下载模版文件的方式手动上传交易日历,解决「什么日子启停」的问题。
在时间范围的选择上,产品支持选择多个时间段进行任务的启停,券商场景中就可以配置9:30-11:30,13:00-15:00 上下午两个开盘时间段进行任务启停控制,实现对业务时间的精准覆盖,自然也就解决了「什么时候启停」的问题。
*在实际任务调度过程中,考虑资源可能无法及时分配,建议预留5分钟左右的误差时间。
实时本身支持重跑、续跑两种不同的启动方式;当选择「续跑」时,任务将会默认选择最近存在的CheckPoint点位进行任务状态的恢复;选择「重跑」时,平台将使用任务中设定的初始参数进行任务执行,例如当实时任务中源表Kafka offset设定为latest并进行重跑时,任务将丢弃历史所有数据,仅从运行时开始记录新数据并进行计算。
如果券商的业务逻辑中包含「每日成交量统计」等指标需要产出,则通常建议任务Offset设置为Latest并配置「重跑」启动方式,这样前一日数据就不会影响到今天的统计结果;
如果是基于「互为买手交易」等一段时间范围内的异常交易监控场景,则建议配置「续跑」启动方式,此时无论原有任务Offset设置是什么,任务都会根据CheckPoint保存的数据与状态持续下去。
通过这种方式,我们就解决了「什么方式启停」的问题。
在我们完成了启停策略的配置之后,只需要给策略取一个易于辨识的名称并进行保存。然后在实时开发的任务设置中配置策略并进行保存。
这样就可以让任务自动启停,节省下夜晚的集群资源去执行离线任务啦。
03
批流一体,是未来的必答题
本篇中我们从「定时启停」这个简单的场景切入,从而对实时在证券场景中的应用有了具体的感知了解,其实实时业务的场景随着近些年技术的愈发成熟,有了更多钻研的空间和环境,我们只是抛砖引玉。
目前离线和实时分属不同的开发场景,独立进行数据存储和计算。为保证实时任务数据的准确与稳定,离线开发通常会有相同任务进行异常恢复,这带来了数据冗余和维护成本。
从引擎发展趋势来看,当Flink引擎对批处理的支持能力自Flink1.10以来越来越健全,离线大批量复杂调度执行的任务也不再必须依赖SparkSQL、HiveSQL等方式,未来Flink将会支持批流一体的业务场景。
当计算引擎统一,底层存储就成为了中台架构优化最后需要苦恼的问题。目前离线数仓仍依赖Hive作为底层存储,Hive在大数据量存储下有着吞吐的性能优势,但对于高读写频次的支持能力却不佳。所以离线与实时这俩大主要数据开发场景的存储层一直处于割裂状态。数据湖的出现却也解决了这一问题,Iceberg和Hudi能够帮助企业切实打通底层存储割裂的困局。从而迈入批流一体、湖仓一体的「新中台」时代。
「新中台」的到来意味着实时技术的广泛应用,从「数据产出」、「数据感知」的阶段,进一步实现「数据驱动」,从而促进业务场景多元化,为企业带来整体能力的螺旋式上升。
End