正文
有了数据之后,我们开始进行日志收集。日志收集相关的开源技术框架中,第一个是 Flume。Flume 是一个开源且非常优秀的日志框架,我们可以把它理解成一个水池,它可以分成三部分,即 Source、Channel、Sink。其中 Channel 就是一个水池,Source 是它的进水管,Sink 是出水管。我们可以将进水管和出水管理解成,为它配置不同的管子支持不同的数据接入和 Sink 的不同目标。它们三个可以组成一个非常复杂的网络,由多个 Flume Agent 可以组成一道数据传输路由。
从架构上来说,Fluentd 与 Flume 非常相似,它带来了跨平台的能力,还有一个特性就是可以用 json 文件统一日志格式。
第三个框架也是非常优秀的日志收集框架,Logstash 更多的时候是跟 Elasticsearch 和 Impala 联合起来,用作运维方面的日志数据分析。
最后一个框架是 Scribe。Scribe 早在 2010 年就停止更新了,不过感兴趣的同学可以在网上查找一下资料进行了解。
实际上,前面三个开源框架都是非常优秀的。我们最终选择使用 Flume 技术框架进行日志收集。Flume 和 Fluentd 差不多,那么在相似的条件下,我们优先选择 Apache 开源产品。
Flume 监控官方推荐使用 Ganglia。Ganglia 监控主要是监控 Source、Channel、Sink 里面的 event 数。event 数实际上是一个个 log 日志,我们可以对比 Source 接收的 event 数和 Sink 已经处理的 event 数是否匹配,不匹配就报警。Channel 里也有 event 数,我们只需要关注它拥堵的 event 数,如果超过一定的阈值也需要报警。
日志数据获取包含几个过程:探针埋点、采集、收集、解析、入库。探针埋点实际上非常简单,它是纯粹的 JS 代码,我们会在业务系统上做一些 Cookie,通过 Cookie 获取到用户数据。JS 一旦被访问就会触发调用 Nginx 的 HTTP 服务。使用 Nginx 是因为它是一个性能很强大的 HTTP 服务器,它可以支持上万的并发量,而探针埋点对后台服务器的压力比较大,因此对并发要求较高。实际上 HTTP 只是记录访问,不会对后端进行任何操作,只会往 Nginx 里记录一条日志。我们对它采用不同的 JS 进行收集、过滤之后便可形成一个较为规范的数据格式,然后再发送到数据库里,或者说交到下一个环节的模块去处理。
上面介绍的是一个通用的数据获取方法,那么实际上还有新的一个问题,如果业务系统存在一些没有办法配合修改的情况,怎么办呢?这时我们只能从业务系统的数据库方面去想办法。
数据库里面最典型的是基于数据库 Change Data Capture 的方案。Change Data Capture,指的是变化数据捕获,我们称之为 CDC。CDC 有以下几种方法,实际上也可以归纳成两种,一种是侵入性的,另一种是非侵入性的。触发器、时间戳、全表比对这三类都属于侵入性 CDC 的获取方法,对业务系统的性能、数据库的性能会有一些影响,实时性也不是那么强。我们推荐使用日志对比的方案。日志对比,如 Oracle 日志、MySQL CDC 都支持,基于日志对比基本上对业务系统不会有任何影响。
针对各种数据库的 CDC 方案我们都做一下介绍。对于 Oracle,我们推荐使用 OGG 方案。OGG 方案是我们在所有的技术选型里面唯一使用的商业产品,因为相对来说 Oracle 还是比较封闭的,没有很好的开源解决方案。
我们之前也曾经尝试自己写代码,确实可以获取到 DML 和 DDL 语句的变化,但是捕获到了之后,会发现后面要做的事情非常多,你不得不去解决数据一致性的问题、顺序的问题、容错的问题等等,自己写的话需要一一考虑这些问题,实际上是得不偿失的,花费的时间也更长,因此我们直接使用 OGG 的商业产品。我们实际的生产库里有四个库,我们在备库上部署了 Oracle GoldenGate,还有 for big data 的 Oracle 组件部署在另外一个 OGG 上,由这两个 Oracle 的组件协作就可以捕获到 Oracle 的数据变化,并且投入到下一步的消息队列里面去。
所有的系统都需要进行监控,OGG 的监控也相当关键。OGG 的监控分为两种,一种是 GoldenGate Director,另一种是 GoldenGate Monitor,这两个功能实际上是类似的。但是 GoldenGate Monitor 提供的软件更为丰富,所以我们推荐使用 Monitor。
如今的大多数业务系统都使用了 MySQL 数据库。针对 MySQL,我们建议的方案就是大家首先会想到的 Canal,它是阿里巴巴的非常优秀的开源数据库,支持同步、增量订阅等功能。然而我们最终没有使用 Canal,因为需要为 Canal 客户端额外写一些代码,包括数据、消息的打包等,尤其是事务方面需要进一步考虑。我们查询了资料发现,GitHub 上有一个雅虎开源、可对外使用的方案 Yelp MySQLStreamer。Yelp 是美国最大的点评网站,它的开源组件能够直接获取数据的变化;它基于 MySQL 行的复制方式,而不是语义的方式;它可以直接将数据获取到下一步消息队列内,同时获取到 DDL、DML 的语义变化;基于该变化,可自动根据表进行打包,建立后面的消息队列的 topic。所以我们最终实现的方法是通过 MySQLstream。如果大家感兴趣,可以关注一下 Yelp MySQLStreamer。