今天总结一下工作中遇到的一些关于数据例行化的问题,并给出几点思考。

如果你从事机器学习的工业应用,那么你有可能遇到过数据数据例行化的问题。假设你遇到了如下场景:

你是一个机器学习攻城狮,每隔15分钟从源数据服务器获取数据,对数据进行业务处理。那么有一个问题,如何保证你wget到的数据是完整的呢?

这个问题比较简单,只需要源数据服务器每次生成数据之后,生成一个md5的校验文件,当你把数据拉取下来之后,进行md5校验即可。

然后有一天,你看到业务告警,经过排查,你发现原来自己wget到的数据和源数据服务器上的数据不一致。这是怎么回事呢?

经过分析相应日志,你发现原因是这样的:你每隔15分钟获取数据,在某一个时刻点,网络出现了延迟或者机器性能问题,导致原来可以在15:07时刻就可以wget到的数据,现在15:16还没有完全wget下来,然后源数据服务器又开始产生新的数据覆盖了上一份数据。

你思考了一会,发现有如下方案。1,使用锁机制。即每次从源服务器读取数据的时候,首先给要读取的数据加锁,当读取完之后解锁。这可以通过增删一个文件实现,即lock_filename.txt。没错,这是一种比较简单的方式,但是只适用于源数据和你的业务机制在相同机器上。 2,可以在源数据每生成一份数据的时候,加一个时间戳。例如,源数据产生的时间是15:00,然后对文件名加一个时间戳,即filename_201810221500.txt。当你在15:15获取数据的时候,date命令获取15分钟前的时间戳,拼接文件名,进行数据获取。

由于本人遇到的场景是同机数据获取,所以就这种情况继续进行分析。

本人通过shell脚本进行数据获取,shell脚本中调用了Python脚本。在每个时刻00,15,30,45分钟调用shell脚本。有一天线上业务告警,这是怎么回事呢?

经过排查,发现获取的数据少了。通过打印日志,发现在每个小时00分钟调用的shell脚本需要在22分钟才结束,而其它三个时刻的脚本调用均未发生延时情况。经过分析,发现是因为shell脚本中的Python脚本发生了延时调用。

Python脚本延时调用和数据变少有什么关系呢?shell脚本源代码如下:

1
2
3
4
> #shell脚本
> check_fileMD5()
> python f.py #Python调用延迟执行 (1)
>
1
2
3
4
5
> # f.py
> lock_file()
> getData()
> unlock_file()
>

(1)Python脚本发生了延迟调用,但是此时已经对文件md5进行了校验。所以,当下一个时刻点15分钟的时候新数据会覆盖了旧数据,此时00分钟调用了shell卡在了Python脚本调用这里,但是已经无法再次调用check_fileMD5()检查源数据的完整性,所以导致了读写冲突,数据变少了。

至于Python脚本为什么会延时调用呢?这是因为在0-15分钟有别的Python脚本占用了Python解释器,导致Python脚本无法及时获取Python解释器。