对七牛云存储日志处理的思考

对七牛云存储日志处理的思考

Posted by bluesky blog on August 2, 2015

  这两天,一篇名为《七牛是如何搞定每天500亿条日志的》的文章,在大数据圈子里火起来。

通过文章,可以看出,七牛将日志处理分为三个大的步骤:

  • 日志收集:使用Agent,收集原始业务日志,并将日志发送到Flume

  • 日志流转: Flume将日志发送到Kafka集群,作为Kafka生产者

  • 日志计算:离线计算,消费Kafka,存入HDFS,用于离线任务。实时计算,通过Spark Streaming实时消费数据,将计算结果,存入到DB中。

简单画张图描述下,

为什么不直接将日志发送到Kafka?

七牛的解释如下:

具体架构上,Agent并没把数据直接发送到Kafka,在Kafka前面有层由Flume构成的forward。这样做有两个原因:

Kafka的API对非JVM系的语言支持很不友好,forward对外提供更加通用的HTTP接口。

forward层可以做路由、Kafka topic和Kafka partition key等逻辑,进一步减少Agent端的逻辑。

如果直接将日志发送到Kafka中,不光只是上面这些原因,还有,网络,安全方面的因素,所以日志和Kafka集群中间,存在一个桥梁是合理的,用Flume或者其它的工具都是一种选择,回过头看我们公司也是如此。

异常处理?

Agent需要有记忆功能,用来保存同步的位置(offset),这样才尽可能保证数据准确性,但不可能做到完全准确。由于发送数据和保存offset是两个动作,不具有事务性,不可避免的会出现数据不一致性情况,通常是发送成功后保存offset,那么在Agent异常退出或机器断电时可能会造成多余的数据。

通俗的说,Agent异常恢复后,会导致日志重发。

当开启speculation参数或代码层面没处理好异常时,task可能会被重放。但是有外部状态的task是不可重入的,否则会造成计算结果的不准确

这个是Spark Streaming实时计算任务恢复后,Task重做,但有些需传入数据已经过时了,所以导致计算结果的不准备。

第一个问题,从个人经验来看,确实没有什么好的办法。宁愿计算重复,也不愿意没有计算。第二个问题,speculation是很一个不稳定的Spark参数,用起来需要慎重,这个是要一个调校的过程,通过不断优化程序,这个问题是可以避免的。

开源工具?

数据平台在大部分公司都属于支撑性平台,做的不好立刻会被吐槽,这点和运维部门很像。所以在技术选型上优先考虑现成的工具,快速出成果,没必要去担心有技术负担。早期,我们走过弯路,认为没多少工作量,收集存储和计算都自己研发,发现是吃力不讨好。去年上半年开始,我们全面拥抱开源工具,搭建自己的数据平台。

这一点,作为同是大数据平台的从业者,感同身受,造轮子是需要时间和精力的,如果不能迅速支撑业务,一味的造轮子,是不可取的。希望七牛在拥抱开源的同时,也能贡献出自己的一份力量,那便是极好的。