日志管理(3) scribe浅析

Scribe从各种数据源上收集数据,放到一个共享队列上,然后push到后端的中央存储系统上。当中央存储系统出现故障时,scribe可以暂时把日志写到本地文件中,待中央存储系统恢复性能后,scribe把本地日志续传到中央存储系统上。需要注意的是,各个数据源须通过thrift(由于采用了thrift,客户端可以采用各种语言编写)向scribe传输数据(每条数据记录包含一个分类category和一条信息message),可以在scribe配置文件中配置用于监听端口的thrift线程数(默认3)。
在后端,scribe可以将不同category的数据存放到不同目录中,以便于进行分别处理。后端的日志存储方式可以是各种各样的store,包括file(文件),buffer(双层存储,一个主储存,一个副存储),network(另一个scribe服务器),bucket(包含多个store,通过hash的将数据存到不同store中),null(忽略数据),thriftfile(写到一个Thrift TFileTransport文件中)和multi(把数据同时存放到不同store中)。
scribe架构图如下:
scribe

1、scribe中常用store存储介绍
file
将日志写到文件或者NFS中,支持两种文件格式,即std和hdfs即普通文本文件和HDFS。
buffer
最常用的一种store。该store中包含两个子store,其中一个是primary store,另一个是secondary store。日志会优先写到primary store中,如果primary store出现故障,则scribe会将日志暂存到secondary store中,待primary store恢复性能后,再将secondary store中的数据拷贝到primary store中。
null
用户可以在配置文件中配置一种叫default的category,如果数据所属的category没有在配置文件中设置相应的存储方式,则该数据会被当做default,如果用户想忽略这样的数据,可以将它放入null store中。

2、配置文件解析 Scribe的配置文件由全局的section和一个或多个store的section组成,在源码包的examples目录下有多个配置文件实例可以参考。
1)、全局配置项
port: (number)
scribe监听的端口,当然也可以通过命令参数-p指定
max_msg_per_second: (number) 每秒最大日志并发数,默认为0,0则表示没有限制
max_queue_site:(byte) 队列最大可以为多少,默认为5,000,000 bytes
check_interval:(second) 检查存储的频率,默认为5s
new_thread_per_category:(yes/no) 是否为每个一个分类创建一个线程,为no的话,只创建一个线程为每个存储服务,默认为yes
num_thrift_server_threads:(number) 接收消息的线程数,默认为3
比如可以这样配置

1
2
3
4
port=1463 
max_msg_per_second=2000000
max_queue_size=10000000
check_interval=3

2)、局部配置项,主要是store相关的配置。

1
2
3
4
5
6
7
8
9
10
cateogry:  哪些消息由这个category的store处理 
type: 指定store的类型,如file,buffer,network,bucket,thriftfile,null,multi
target_write_size:(byte) 对应category的消息在处理之前,消息队列最大可以为多大,
默认为16,384
max_batch_size:(byte) 内存存储队列一次性可以处理的消息数量,超过这个大小将调用thrift
max_write_interval:(second) 对应category的消息队列在处理消息这些消息之前可以维护多长
时间,默认为1秒
must_succeed:(yes/no) 消息是否必须要成功处理,如果一个消息存储失败再重试,如果设置为no,
则如果一个消息存储失败,则该条消息会被抛弃,默认为yes。强烈建议使
用buffer类型的store去指定一个secondary store去处理失败的消息。

比如这些参数可以这样使用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<store> 
category=test_* #所有以"test_"开头的分类category信息由这个store处理
type=buffer
target_write_size=20480
max_write_interval=1
buffer_send_rate=2 #从secondary store多少次读取一个组消息发送到primary store
retry_interval=30 #写入到primary store失败后,多久时间再次发送到primary store
retry_interval_range=10 #重试间隔

<primary>
... ... ...
</primary>
<secondary>
... ... ...
</secondary>
</store>

不同的类型的store配置有区别,上面的配置参数只是一些通用参数。
a)、file store

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
file_path 默认路径是‘/tmp’。 
base_filename 默认category名称。
use_hostname_sub_directory 是否使用server的hostname建立子目录,默认是no。
sub_directory 使用指定的名称创建子目录。
rotate_period 设置多久创建一个文件,周期可以是“hourly”, “daily”, “never”, or number[suffix];
“never”是默认值,suffix可以是“s”, “m”, “h”, “d”, “w”,‘s’是默认值。
rotate_hour 如果rotate_period是daily,设置每天何时创建新文件,值可以是0-23,默认是1。
rotate_minute 如果rotate_period是daily或者hourly,设置一个小时多久后可以创建新文件,
值可以是0-59,默认是15。
max_size 在轮转一个文件前,该文件可以增长到多大,默认是1,000,000,000 bytes 。
write_meta 值可以是yes或者其他值,false是默认值,如果文件被轮转,最后一行将包含"scribe_meta"
跟着就是下一个文件名。
fs_type 支持两种类型std和hdfs,默认是std。
chunk_size 默认是0,如果一个chunk大小被指定,在文件内没有消息能够跨越chunk的边界,
除非有消息的大小超过chunk的大小。
add_newlines 默认是0,如果是1,则在每行后面加入换行符。
create_symlink 默认值是yes,如果是真,则维护一个符号连接到最近被写入的文件。
write_stats 是否对每一个store创建一个scribe_stats文件用来跟踪文件的写入轨迹,默认yes。
max_write_size 当块大小大到max_write_size时,store会将数据刷新到文件系统,max_write_size不能
超过max_site.由于target_write_size大小的消息被缓存,file-store会被调用去保存
这些缓存中的消息.file-store每次最少会保存max_write_size大小的消息,但file-store
最后一次保存消息的大小肯定会小于max_write_size.默认值为1,000,000

比如实际使用中可以这样配置

1
2
3
4
5
6
7
8
9
10
11
12
<store> 
category=nginx
type=file
file_path=/tmp/nginx
base_filename=nginx_log
max_size=1000000
add_newlines=1
rotate_period=daily
rotate_hour=0
rotate_minute=10
max_write_size=4096
</store>

b)、Network Store network store向其它scribe server发送消息,Scribe保持持久的链接打开以至于它能够发送消息,在正常运行的情况下,scribe会基于当前缓存中存在多少条消息等待发送而分批次的发送。

1
2
3
4
5
remote_host 远程主机的ip或者名称。 
remote_port 远程主机的端口。
timeout socket超时时间,默认为default_socket_timeout_ms,
在store.h中设定默认为5000毫秒。
use_conn_pool 是否使用连接池代替为每一个远程主机打开的链接,默认是false

比如实际使用中可以这样配置

1
2
3
4
5
<primary> 
type=network
remote_host=192.168.192.168
remote_port=1463
</primary>

c、Bucket Store
buffer store中包含两个子store:primary和secondary,日志会先尝试写到primary store中,如果primary store出现故障,则scribe会将日志暂存到secondary store中,待primary store恢复性能后,再将secondary store中的数据拷贝到primary store中(除非replay_buffer=no),其中secondary store仅支持两种store(file和null)。

1
2
3
4
buffer_send_rate 默认是1,在check_interval周期内,执行多少次secondary store读出一组消息并且发送到primary store中。 
retry_interval 默认是300秒,primary store写入失败后,等待多久尝试重新发送primary store。
retry_interval_range 默认是60秒,将在retry_interval的区间内随机的选择一个重新发送时间。
replay_buffer 默认是yes,如果设置为no,将不会从secondary store迁移消息到primary store。

比如实际使用中可以这样配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
<store> 
category=php_*
type=buffer
target_write_size=1463
max_write_interval=1
buffer_send_rate=2
retry_interval=30
retry_interval_range=10

<primary>
type=network
remote_host=192.168.192.168
remote_port=1463
</primary>

<secondary>
type=file
fs_type=std
file_path=/opt/log/php
base_filename=thisisoverwritten
max_size=10000000000
add_newlines=1
rotate_period=daily
rotate_hour=0
rotate_minute=0
</secondary>
</store>

d、Bucket Store bucket stores使用消息前缀作为key,将消息hash到多个文件中去(具体我没有用过,不知道效果怎样)。

1
2
3
4
5
num_buckets 默认值是1,hash到buckets的个数,不能被hash进bucket的消息将被放入一个特别的0号bucket。
bucket_type “key_hash”, “key_modulo”, or “random”。
delimiter 值必须是1~255之间的ascii,默认是':',第一次出现在消息前缀中的delimiter在‘hash/modulo’中将被用作key。
remove_key 是否移除key的前缀,默认是no。
bucket_subdir 如果使用一个单独定义的bucket,则每一个子目录的名称根据bucket的数量编号生成。

配置实例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<store> 
category=bucket_me
type=bucket
num_buckets=5
bucket_subdir=bucket
bucket_type=key_hash
delimiter=58
<bucket>
type=file
fs_type=std
file_path=/tmp/scribetest
base_filename=bucket_me
</bucket>
</store>

e、Null Store

1
Null store告诉scribe对给定的category,忽略所有的消息。

配置实例

1
2
3
4
<store> 
category=tps_report*
type=null
</store>

f、Multi Store 一个multi store会将消息转发到多个子stores中去,子store以“store0”, “store1”, “store2”命名。

1
report_success 值可以是all或者any,默认是any,是否所有substores或任何substores必须成功地记录消息。

配置实例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<store> 
category=default
type=multi
target_write_size=20480
max_write_interval=1
<store0>
type=file
file_path=/tmp/store0
</store0>
<store1>
type=file
file_path=/tmp/store1
</store1>
</store>

关于scribe的资料网上不是很多,可能是用的人少吧,我也是查询了相关资料及结合实际使用经验写下了这篇文章。

----------------本文结束 感谢阅读----------------