什么是日志?在非常长的一段时间内,日志对我来说,就是协助定位系统问题的一种手段。在开发阶段我打了非常多DEBUG级别的日志协助调试,到了线上,我们只保留INFO级别以上的日志。这样,在系统出现和我们预期不符的状况时,通过日志,我可以定位到异常发生时的一些蛛丝马迹。这就是日志所有的作用了。tailf几乎是我会对日志去做的唯一操作。
所以,当来到大数据领域,我听到人们都在说,我们需要一套日志系统,我一直很迷茫。ELK可能是最容易搭建的日志系统。Logstash
抽取硬盘上的日志文件,发送到Elastic Search
,最后通过Kibana
进行可视化。但我所见过的ELK
实践,依然没有改变那个最初的定位,我们还是在通过日志系统查询系统异常(Exception)。这和大数据又有什么关系?
某种程度上,日志系统也成为了像大数据概念本身一样的Teenage Sex。所有人都在谈论它,可是没有太多人知道它究竟是什么。
直到有一天,我们读写分离的系统遭遇了严重的主从不同步问题,我好奇地想搜索一下MySQL的主从同步究竟是通过什么机制来实现的,我第一次知道了MySQL的binary log这个东西,从此打开了新世界的大门。
日志与表合二为一
更详细的介绍可以参见这篇博客,但简单地说,主实例的所有INSERT和UPDATE操作事件,都会被发布到binlog中,而从实例只要同步这个日志并尽可能快地执行日志中的变更事件即可。主从同步延迟问题的排查也就变得容易入手,从实例或者无法及时读取binlog,或者读取后无法及时执行。反过来说,只要从实例严格执行了主实例发布的所有事件日志,主从一定处于同步状态。
binlog设计之初,就是供机器阅读的,它忠实记录了发生的事件和时间。把它看做一个数据结构,binlog只允许唯一一个操作,那就是追加 append。依次执行所有这些事件,就能来到最新的状态。就像只要知道所有的交易记录,我总能知道你的账户余额。
数据操作事件Log和数据库表Table,这两个概念在这里奇妙地合二为一。甚至Log比Table更棒,Table永远只有最新的状态,而通过Log,我可以来到任何中间状态。
日志系统才应该是数据的核心,而不是数据仓库
这里我们要稍微绕些路,谈一谈数据仓库。来到一定规模的公司,数据仓库的建设会被提上议程。不管是基于Oracle
的传统数据仓库,还是Hadoop
时代以Hive
为中心,配合Presto
,Impala
等OLAP工具的分布式数据仓库,其特点并没有发生本质的变化。数据仓库将散落(微服务时代,数据实际上变得更加散落了)、来源各异(异构数据库,搜索引擎)的数据,集中到统一的地方,配合ETL过程,将数据整理成更加规范的形式,供报表、分析、挖掘使用。事实上,所有花哨的名词,数据挖掘、机器学习、神经网络,如果缺乏统一的数据接入层,都只是花哨的名词,而已。
数据仓库的这些特点,使其非常适合成为整个企业数据的核心,毕竟所有的数据经过汇总都可以从仓库中方便地获取。但有一点不该忘记,数据仓库的定位,始终是离线的,它定时地将数据从相互隔离的数据源中抽取过来,转换加工后,加载到目标系统。当你开始搭建实时数据的时候,数据仓库的核心地位,就开始成为阻碍因素。并不是所有数据消费系统,都可以接受T+1的时滞。
我们注意到大数据平台,和分布式数据仓库(基本上就是Hive
)的概念是不划等号的,它通常还包括实时计算的部分。而在上一节里我们已经发现了,作为离线的表和作为实时的日志,这两个概念是一体两面。如果你拥有实时,你就拥有了离线!(反过来却不是)
而实时数据的管理?不言而喻,是日志系统。
结构化的日志数据
数据仓库的数据都非常结构化,易于查询。而日志系统的数据,都是日志,日志通常被视为半结构化的数据,它本身具备一定的结构,但是又以非强制约束的形式存储。如果我们的日志本身就是格式化的,无疑在易用性上会更胜一筹。
所谓结构化,千万不要认为JSON是格式化的。我们需要数据带有schema,给定一份数据,我想清楚地知道它有哪些字段,每个字段是什么类型。
在日志结构化方面,Avro, Thrift, Protocol Buffer都是不错的选择。如果业务系统的数据交互,已经在使用这样的格式。或者说,对于HTTP API,你使用了诸如SWAGGER这样的API工具来规范数据传输。那么打造这样一个日志系统,会容易得多。
最后
以日志为核心,Data Pipeline 数据管道
这个词可能前所未有地接近其字面意思。毕竟,不能简单地插拔、组合,还怎么能称之为管道呢?