分布式日志系统:Scribe
Scribe是非死book开源的日志收集系统,在非死book内部已经得到大量的应用。它能够从各种日志源上收集日志,存储到一个中央存 储系统(可以是NFS,分布式文件系统等)上,以便于进行集中统计分析处理。它为日志的“分布式收集,统一处理”提供了一个可扩展的,高容错的方案。当中 央存储系统的网络或者机器出现故障时,scribe会将日志转存到本地或者另一个位置,当中央存储系统恢复后,scribe会将转存的日志重新传输给中央 存储系统。其通常与Hadoop结合使用,scribe用于向HDFS中push日志,而Hadoop通过MapReduce作业进行定期处理。
Scribe支持的特性:
- 构建应用系统和分析系统的桥梁,并将它们之间的关联解耦;
- 支持近实时的在线分析系统和类似于Hadoop之类的离线分析系统;
- 具有高可扩展性。即:当数据量增加时,可以通过增加节点进行水平扩展。
如下图所示,Scribe从各种数据源上收集数据,放到一个共享队列上,然后push到后端的中央存储系统上。当中央存储系统出现故障时,scribe可以暂时把日志写到本地文件中,待中央存储系统恢复性能后,scribe把本地日志续传到中央存储系统上。
Scribe使用thrift传输log,因此无论是什么语言开发的项目都可以实现log收集,传送到远程或主从同步到远程。Scribe由两部分 组成:central scribe server和local scribe server。在分布式系统中,每一个节点都会运行一个local scribe server,收集此节点的日志信息,并将其发送给central scribe server。各个数据源需通过thrift向scribe传输数据,每条数据记录包含一个category和一个message。可以在scribe配 置中指定thrift线程数,默认是3。在后端,scribe可以将不同category的数据存放到不同目录中,以便于进行分别处理。后端的日志存储方 式可以是各种各样的store,包括file,buffer(双层存储,一个主存储,一个副存储),network(另一个scribe服务 器),bucket(包含多个store,通过hash将数据存到不同store中),null(忽略数据),thriftfile(写到一个 thrift tfile transport文件中)和multi(把数据同时存放到不同store中)。
Scribe中各种store介绍:
file
将日志写到文件或者NFS中。支持两种文件格式,即std和hdfs,分别表示普通文本文件和HDFS。可配置的选项有:
- max_size:文件大小上限,即当文件大小达到max_size时,创建新的文件继续存储数据。
- rotate_period:文件创建周期,可以是hourly,daily,never和number[sufix]。sufix可以是s(second),m(minute),h(hour),d(day),w(week)。
- sub_directory:子目录名字
- base_filename:文件前缀,如news,则会依次将数据存储到文件news_20110403_00000,news_20110403_00001,……
null
这也是一种常用的store。用户可以在配置文件中配置一种叫default的category,如果数据所属的category没有在配置文件中 设置相应的存储方式,则该数据会被当做default。如果用户想忽略这样的数据,可以将它放入null store中。需要注意的是,Scribe会将数据首先缓存到buffer中,待buffer满后再flush到HDFS上。当数据量非常少时,由于缓存 的原因,部分数据可能未写到HDFS中,这时用户可以调整scribe的相关配置参数或者关闭scribe(如减小max_size),使数据全部写到 HDFS中。如果用户采用减小max_size的方案,此时需要注意,HDFS不能很好的保存小文件(可能会丢失数据,见扩展阅读资料3)。
buffer
这是最常用的一种store。该store中包含两个子store,其中一个是primary store,另一个是secondary store。日志会优先写到primary store中,如果primary store出现故障,则scribe会将日志暂存到secondary store中,待primary store恢复性能后,再将secondary store中的数据拷贝到primary store中。其中,secondary store仅支持两种store,一个是file,另一个是hdfs。
Scribe的技术架构:
如上图所示:Scribe服务器底层数据通信框架是Thrift,Thrift也是非死book开源的,并得到了广泛的使用。也用到了C++的 准标准库boost,主要使用共享指针和文件相关的功能。Thrift也用到了libevent开发库和socket编程技术。
Scribe部署结构:
Scribe的主要功能
- 支持多种存储类型:7种并且可扩展
- 日志自动切分功能:按文件大小和时间切分
- 灵活的客户端:
(1)支持多种常用语言(Thrift提供支持);
(2)可与应用系统集成;可以作实现独立客户端
- 支持日志分类功能(非死book有上百种日志分类)
- 其他功能
(1)连接池
(2)灵活的日志缓存大小
(3)多线程功能(消息队列)
(4)scribe服务器之间可以转发日志
- 以上功能都是可以通过配置文件来灵活配置
Scribe使用方案
- 和产生日志文件的应用系统集成。scribe能够和各种应用系统很好的集成是因为它提供几乎所有的开发语言的开发包
- 应用系统在本地产生日志文件,使用一个独立运行的客户端程序同样,独立的客户端也可以采用各种语言开发,我们采用的是python来开发客户端
Scribe存在的问题
虽然scribe系统是如此的优秀,但是也存在着一些不足和问题,针对存在的问题我们对scribe进行扩展。我们发现scribe存在的主要问题如下:
1、单点故障问题,有三个地方存在单点故障:
(1)中心服务器
(2)本地服务器
(3)收集日志的客户端程序
2、日志丢失问题。当日志文件发生切分的时候可能导致日志丢失。
3、历史日志收集问题
4、scribe服务器挂了没有及时通知
总起来说,scribe为日志收集提供了一种容错且可扩展的方案。scribe可以从不同数据源,不同机器上收集日志,然后将它们存入一个中央存储 系统,以便于进一步处理。当采用HDFS作为中央系统时,可以进一步利用Hadoop进行处理数据,于是scribe+HDFS+MapReduce方案 便诞生了。具体如下图所示:
由于scribe资料比较少,网上讨论也不是十分活跃,不少人转用其它一些日志系统,比如:rsyslog 和 Chukwa。
参考资料
- scribe主页:https://github.com/非死book/scribe
- scribe介绍:http://blog.octo.com/en/scribe-a-way-to-aggregate-data-and-why-not-to-directly-fill-the-hdfs/
- HDFS小文件问题:http://www.cloudera.com/blog/2009/02/the-small-files-problem/
- Scribe所有资料的汇总:http://sameerparwani.com/posts/非死book-scribe-server-documentation-and-tutorials