概述
随着 Hadoop 生态的快速发展,海量数据的处理的方法已经非常成熟并且丰富了,但是这些处理方法一般都是批处理方式,也就是输入的数据是确定的,例如1小时的日志,在日志已经准备好之后再开始计算。当今产品业务的快速发展,在很多场景(反作弊等)下对数据处理的时效性提出了新的要求,要求更高的时效性。于是,流式计算就逐步开始发展起来,目前仍处于快速发展阶段,业界对于流式计算的问题认识也在逐步加深。
本文首先来讨论一个在批处理中经常被忽略,但是在流式计算中非常重要的一个问题——日志的时间。首先,我们来看看批处理视角下的日志时间。
批处理视角
批处理是大家非常熟悉的,输入的一般是HDFS上的文件,例如当前1小时的日志文件,任务触发的时间是下1个小时的某个时刻,我们会默认这份数据的时间就是今天当前时刻的,最终产出的数据放入对应的时间分区。
但是,实践中也会发现某个时间分区下的日志时间可能并不属于这个时间分区,产生这种情况的原因有很多,这里列举笔者见过的情况。
第一种情况:输入的上游服务器的日志,每隔一段时间日志进行一次滚动,日志滚动的方式导致在小时的临界点切分的不干净,有部分上一小时或下一小时的日志残留。这种情况的量一般比较少,可以基本忽略。
第二种情况:在PC互联网时代,大部分的服务都是Web服务,后端服务器可以在浏览器请求后直接记录日志,数据的上传是实时的。而到了移动互联网时代,用户习惯实用App,App拥有了比浏览器更加强大的功能,会聚合大量的日志再进行上报,如果用户因为坐飞机或信号不好等原因,导致网络连接有问题的时候,就会导致这份日志的上报延迟非常大,可能是几分钟、几小时、甚至几天。这部分的数据延迟是非常大的,而且数据量一般也并不少。常见的处理方法有两种:直接忽略客户端时间,都算入接收到数据的那个时间周期内;数据写入客户端时间的时间周期内,然后数据定时进行回溯,例如滚动回溯7天的数据,最多就只关注7天的延迟上报数据。
我们可以看出,批处理并没有明确地对日志时间做出定义,根据业务的不同情况,可以选择客户端时间、服务器(后端服务)时间等。
但是,在流式计算中,数据的时间是数据的固有属性,没有了批处理明确的数据边界,需要根据数据时间来进行边界的划分,认识到这个时间的问题,在流式计算认知发展中是非常重要的。
流式计算视角
在流式计算中,日志的时间划分成了Event Time(后续简写为ETime)和Processing Time(后续简写为PTime),其中有一种特殊的PTime是Ingestion Time(后续简写为ITime)。
- ETime 是日志产生的时间,例如Web服务端接收请求后记录的access时间戳,App用户操作后记录的时间戳等,是属于日志数据的固有属性,是不可变的。
- PTime 是日志被流式系统接收后的处理时间,这个时间是不确定的,每次重跑数据的时候可能不一样,最大的特点就是单调递增的时间戳。
- ITime 是日志进入流式系统的时间,这个时间也是不确定的,属于一种比较特殊的PTime,可以当做是ETime的近似。
由此,我们可以看出,流式计算的日志时间ETime是最为重要的,因为这个是属于数据发生的时间,一般的数据统计等都是以这个为准的。也存在一些场景更适合使用PTime,例如流量异常检测,只需要检测到流量突增突降即可,其实对于时间不是特别敏感。
接下来,简单讨论下流式计算中的边界问题,认识ETime和PTime,主要还是为了解决数据完整性的问题,可以实用两种时间中的一种。
目前,主要的完整性判断方法是使用watermark(水位)的方式,其中有一种简单的方式叫low watermark(低水位,后续简写为LWM)。LWM的思路比较简单,就是以当前处理的数据中最早的时间戳作为当前的进度,在此之前的数据认为都已经完整了,但是这个方法有个前提就是输入的数据时间戳是有序的,单调递增的。
两种时间中PTime是肯定符合单调递增的,所以对于LWM来说是非常友好的,可以构建一个完美的watermark。对于ETime来说,一般情况下都不能保证是有序的,乱序数据的情况是非常常见的,所以LWM的方法对其并不好。
目前对于ETime的watermark其实并没有通用的方法,不过这里可以提供一个简单的思路:数据都是通过服务器来传入到日志消息队列(例如Kafka等),我们可以在这些服务器上进行信息的收集,收集其各个时间戳发送的数据量,在流式计算中也对机器和时间戳进行计数统计,这样可以粗略的估算一个百分比的进度。这里可以假设当个服务器发送的数据时间戳是单调递增的,即使无法在源端对数据进行采集,也可以在流式计算的导入层进行统计和预估。百分比的进度有一个非常好的特点,就是可以设置完成到一定比例就触发计算,更灵活。当然这个方法依然无法很好地解决乱序数据,延迟很大的数据,这其实涉及到了准确性、时效性、成本之间的权衡问题了。也就是流式计算的CLC(Correctness、Latency、Cost,与分布式系统的CAP理论类似)。
结束
本文是笔者对于流式计算中日志时间问题的一些思考和笔记,流式计算仍然是一个快速发展的方向,笔者目前对此的理解还不够深入,文中观点仅供参考,如有纰漏,敬请赐教。