TrafficServer日志系统配置指南

TrafficServer日志系统配置指南

淘仇恕(张云开)

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


一、TS日志系统简介

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


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


在TrafficServer中:

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

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

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

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


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

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

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

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

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

  4. 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_mode

  • 0,客户端模式

即表示,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_size

LogBuffer的大小。「线程模型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的文件大小



展开阅读全文

没有更多推荐了,返回首页