TrafficServer日志系统配置指南

  TrafficServer日志系统配置指南

  淘仇恕(张云开)

  原文放在Google Doc里,这里只做镜像不更新

  一、TS日志系统简介

  在中大规模的软件系统中,日志系统(logging system),已经成为标配。Linux有syslog,Java有Log4j,Python有logging模块。日志系统的模型,已经非常成熟,大体如下图所示:

  概括地说,就是日志系统里,允许配置多个日志对象(LogObject),这些对象描述了日志的过滤规则(filter)、格式(format)、以及日志的去向(target)。日志的输入(input),是通过约定的日志API,由应用程序调用这些API完成输入。日志最终会输出(output)到磁盘或写入到网络的另一台日志服务器上。

  在TrafficServer中:

  日志输入,由的TrafficServer的worker线程完成,这些线程会把HTTP状态机的信息,直接传递给日志系统的API里。

  日志API,由两个简洁的函数组成:Log::access()——访问日志,Log::error()——错误日志。

  日志对象,通过一个logs_xml.config文件描述,这个文件通常位于:/etc/trafficserver/目录下,文件内部对配置方法有详细的描述。

  日志输出,由LogObject的target属性描述,但在具体的logs_xml.config中,target属性由LogObject的Filename及CollationHosts描述。如果不存在CollationHosts,则表示输出到本地磁盘,否则输出到网络上的日志服务器。

  在讲解TS的日志系统配置之前,需要先了解TS日志系统的内部结构,包括它的线程模型、工作流程。下图对其内部结构进行简要描述:

 

  由上图可知,TS的日志系统,其线程包含:

  worker线程,即日志的输入方,它会调用Log::access()/Log::error() 日志API。在这些API内部,会根据用户在logs_xml.config配置的LogObject对日志进行过滤。若满足了过虑条件,则把该条日志写入到该LogObject下的LogBuffer里。若LogBuffer已满,则把它发送到预处理线程的queue里,然后继续与下一个LogObject的过虑条件进行匹配,直到所有LogObject都匹配结束。

  preproc线程,即预处理线程,它负责做一些转换工作(例如,把worker线程传递进来的HTTP状态机,根据LogObject的format格式,转换成Ascii字符串,这部分转换工作不是必需的,取决于LogObject配置的日志类型,若是二进制类型则不进行转换),然后根据LogObject的target类型,把预处理后的数据发送到flush队列或collation队列。

  flush线程,这部分线程只是简单地把preproc线程传递过来的预处理过的内容,写到磁盘上。

  net线程,负责把preproc线程传递过来的、未经转换的LogBuffer发送到远端的日志服务器上(日志服务器在接收到LogBuffer后,再经过它自己的预处理线程、flush线程,最终写到磁盘上,也可以继续发送到其他日志服务器)。

  有了前面的基础知识,下面开始介绍日志系统的配置参数。

  二、TS日志系统配置指南

  TS日志系统涉及到的参数还挺多的,并不是每个参数都需要关注。为了简明起见,先给出一份适合咱们淘宝场景的配置单(未列出的选项,使用TS的默认值):

  日志客户端的配置

  LOCAL proxy.local.log.collation_mode INT 0

  CONFIG proxy.config.log.max_space_mb_for_logs INT 2500

  CONFIG proxy.config.log.max_space_mb_for_orphan_logs INT 2500

  CONFIG proxy.config.log.max_space_mb_headroom INT 1000

  CONFIG proxy.config.log.squid_log_enabled INT 0

  CONFIG proxy.config.log.log_buffer_size INT 262144

  CONFIG proxy.config.log.collation_max_send_buffers INT 1024

  CONFIG proxy.config.log.ascii_buffer_size INT 524288 //log_buffer_size两倍

  CONFIG proxy.config.log.rolling_enabled INT 3 //roll on time or size

  CONFIG proxy.config.log.rolling_interval_sec INT 600

  日志服务端的配置

  LOCAL proxy.local.log.collation_mode INT 1

  CONFIG proxy.config.log.max_space_mb_for_logs INT 100000 //100G,酌情调整

  CONFIG proxy.config.log.max_space_mb_for_orphan_logs INT 2500

  CONFIG proxy.config.log.max_space_mb_headroom INT 1000

  CONFIG proxy.config.log.squid_log_enabled INT 0

  CONFIG proxy.config.log.log_buffer_size INT 262144

  CONFIG proxy.config.log.collation_max_send_buffers INT 1024

  CONFIG proxy.config.log.ascii_buffer_size INT 524288 //log_buffer_size两倍

  CONFIG proxy.config.log.collation_preproc_threads INT 4 //4个预处理线程

  CONFIG proxy.config.log.rolling_enabled INT 3 //roll on time or size

  CONFIG proxy.config.log.rolling_interval_sec INT 600

  CONFIG proxy.config.log.rolling_size_mb INT 2000

  日志系统配置详解

  proxy.local.log.collation_mode0,客户端模式

  即表示,TS不负责从别的机器接收日志。

  1,服务端模式

  可接收别的机器发送的日志,值得一提的是,它还可以继续充当「客户端」。

  proxy.config.log.max_space_mb_for_logs普通日志的最大容量,普能日志是指写往本地磁盘的日志。

  proxy.config.log.max_space_mb_for_orphan_logs孤儿日志的最大容量,孤儿日志是指原本发送到网络上的日志,由于网络的原因,如日志服务器连接中断、网络传输速度太慢,导致发送端的日志堆积量超过指定的阈值(这个阈值可由collation_max_send_buffers等参数控制,后面会介绍),则会把这些日志,写到本地磁盘上,变成孤儿日志。

  max_space_mb_for_orphan_logs的配置值,常令用户感觉到困惑,这里详细解释一下:

  TS在往磁盘写日志前,会计算日志的容量以及磁盘的容量,检查它们是否达到指定的阈值,如果达到则会丢弃日志。

  TS在计算已经写到磁盘上的日志的总容量时,是把普通日志与孤独日志,一起计算的。因此,TS需要确定日志的最大容量,该采用max_space_mb_for_logs还是max_space_mb_for_orphan_logs?TS采用下面的规则计算:

  如果logs_xml.config里,没有任何LogObject配置了CollationHosts,则采用max_space_mb_for_logs的值。

  如果所有LogObject都不写本地磁盘(注意若打开了squid_log,会自动创建一个写本地磁盘的LogObject),则采用max_space_mb_for_orphan_logs的值。

  如果即有写本在磁盘的LogObject,又有写网络的LogObject,则取这两者的较大的值。

  这个算法太绕口了,建议大家把两者配为相同的值,防止出错。

  proxy.config.log.max_space_mb_headroom这个值,用来防止磁盘被日志打满,它能确保:普通日志+孤儿日志+headroom < 磁盘容量。

  但值得的一提的是:traffic.out不属于普通日志,更不属于孤儿日志,在旧版的TS里,磁盘有可能被traffic.out打满。在master版本里,traffic.out的大部分内容,会写到diags.out里,diags.out的内容会作为普能日志对待,当磁盘不够时,会被日志进程回收。

  CONFIG proxy.config.log.squid_log_enabled若设置为1,日志进程会自动创建一个内部的LogObject,这个LogObject会把HTTP状态机的信息按照squid的格式,写到本地磁盘上。

  既然我们已经把日志发送到日志服务器,建议设置为0,否则大量的squid日志会占用本地磁盘,浪费资源。

  proxy.config.log.log_buffer_sizeLogBuffer的大小。「线程模型vs工作流程」的示意图中,有提到LogBuffer。每个LogObject都有自己的LogBuffer,当LogBuffer写满后,就会push到preproc线程的队列中(如果超过5秒的时间还没写满,也会被push到队列中)。

  在一个很繁忙的系统中,如果LogBuffer太小,在5秒内被频繁的写满,就会导致无谓的申请、释放内存。如果LogBuffer太大,在5秒内无法被写满,有太多的冗余空间,也会浪费内存。

  当LogBuffer被push到preproc线程的队列后,如果preproc线程的处理速度太慢,就会造成LogBuffer在队列上堆积。当堆积的数量达到2048个,preproc线程就会把多余的LogBuffer丢弃,并打印出Warning信息:

  "Dropping log buffer, can't keep up."

  在遇到这种报警时,首先要尝试调大log_buffer_size,那么如何计算这个值?

  假设每条日志的平均大小是avg_size = 300bytes,qps = 3w,假如LogBuffer足够大,在5秒内不会被写满,因此在5秒后才被强制push到preproc队列里,又由队列的最大容量为2048,即在5秒内队列的容量不能超过2048(如果超过新push的LogBuffer就会被丢弃),可以计算出LogBuffer的大小:

  log_buf_size = (avg_size * qps * 5秒) / 2048

  = 5/2048 * avg_size * qps

  根据上面这个公式,就可以根据自己的日志特点、业务压力,设置一个合理的LogBuffer大小。

  我在前面的表格中,推荐值为:262144,根据这个值,在avg_size=300bytes的前提下,可以支持35W的qps,应该足够了。

  proxy.config.log.collation_max_send_buffers从「线程模型vs工作流程」的示意图中,可以看到,在preproc线程与net线程之间,还有一个collation队列。collation队列的容量,就是由collation_max_send_buffers参数确定。

  当collation队列中的LogBuffer的数量超过了配置值,就会被丢弃。当发生丢弃时会报如下告警:

  "[log-coll] send-queue full; orphaning logs ... "

  这个值与网络的发送速率有关。如果网络慢,collation队列中的LogBuffer就会被堆积,当出现这些告警时,请先尝试调大本参数。推荐值为:1024。

  proxy.config.log.ascii_buffer_size从「线程模型vs工作流程」的示意图中,可以看到,在preproc线程往flush线程push数据之前,需要把LogBuffer的内容,转换为Ascii字符串。

  TS会根据ascii_buffer_size的值,预先申请一块ascii_buffer内存,用来保存Ascii字符串的内容。在转换过程中,内容的长度可能会膨涨,为了确保一个LogBuffer的内容在转换后,能够被一个ascii_buffer完整的保存,从而减少不必要切割,ascii_buffer的大小,一定要比LogBuffer大。

  因此,建议设置为log_buffer_size的两倍大小。

  proxy.config.log.collation_preproc_threads预处理线程的个数。

  如果日志客户端,不往本地磁盘写数据,只是简单地把日志发往远端的日志服务器,使用默认值1就够了。因为只有一个tcp连接,日志的发送瓶颈在net线程,预处理线程不会有任何压力。

  对于日志服务端,通常4个预处理线程足够了。

  proxy.config.log.rolling_enabled日志回滚的选项,可设置以下值:

  0,no rolling.

  1,roll_on_time_only

  2,roll_on_size_only

  3,roll_on_time_or_size

  4,roll_on_time_and_size

  proxy.config.log.rolling_interval_sec设置rolling的时间间隔

  proxy.config.log.rolling_size_mb设置rolling的文件大小

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值