标签:日志
随着业务和系统的规模增大,我们后台的机器也逐渐增多,带来了很多新的问题,比如系统的统一发布升级、监控等等。如何解决这些问题相信大家都有自己的思路和实践,这篇博文也不打算就这些问题展开,而是从其中一个点——日志说起。不论实现怎样一个系统,日志都不可或缺,后台系统也是如此。无论是基于日志来做业务监控,还是遇到突发事故通过查找日志来定位问题,日志扮演着很重要的角色。在单机时代,可以简单地把日志写到本地磁盘。日志文件增大以后,要考虑日志切分、日志分类、甚至日志清理等问题。有很多现有的工具可以用来解决这些问题,比如log4j、log4cpp等。而到了多台机器,写本地磁盘的做法已经不能满足业务的需求。比如出现某个业务问题,要及时还原现场找到问题的症结,按照以往的方式你可能会先去查找日志流水,但多台机器你怎么查?一台台ssh上去查找?这是很不现实的一种做法,效率低下而且浪费时间。这时候你可能需要将多台机器上的日志汇集到一起查找,kids是一个可以参考的选择。
Kids是知乎团队开发的一款分布式日志系统,缩写是“kids is a data stream”,有点GNU的味道。最初在技术选型的时候大概有三种思路,一种是自己手写一个传输工具把日志发到一个固定的server上,第二种是结合pubsub消息队列来收集日志,第三种是已有的分布式日志系统。最开始是比较倾向于使用第二种方案来做,比如kafka、rabbitmq等。由于后台技术栈主要还是以C++为主,不甘心继续找,后来无意中看到facebook开源的scribe,但这玩意一是很久没更新,第二这玩意要依赖thrift,并不是一个轻量级的东西。再后来无意中在infoq上看到一篇关于知乎架构的文章,文章里介绍了他们团队开发的日志系统kids,正好也开源了,于是从github上clone下来用了用。第一感觉上手很快,配置很简单很清晰,觉得可以试用下。
由于线上系统的gcc不支持C++11,只有一台测试机支持,倒腾了下把libstdc++做了静态编译放到了线上系统试用。由于没有做很严格的性能测试,事实上也没有性能测试的思路,只把日志量很少的部分业务用到了kids,每天的日志大概100多K,每台机器上的kids进程占50多M内存,而且就算Kids crash掉也不影响实际业务。kids的日志不会实时写到日志,而是会缓冲到内存一段时间再写入,可以在配置文件中设置flush的频率,确保内存中的数据及时写入文件。后面有空可以研究下它的实现机制,看有没有什么可以优化的空间。大概是这么个情况。
Kids具有实时订阅、分布式收集、消息持久化、多线程、采用Redis协议、没有第三方依赖等特点。Kids在每台服务器上可以配置成agent或server。agent直接接受来自应用的消息,把消息汇集之后,可以打给下一个agent或者直接打给中心server。订阅日志时,可以从server上获取,也可以从中心节点的一些agent上获取。
Kids的配置很简单,重点说下Kids配置里的store,它是在使用Kids最需要关注的配置项,前面提到的agent和server也是通过这个配置来实现的。store的配置有两种形式:简单配置和混合配置。
简单配置里有三种方式:FileStore、NetworkStore和NullStore:
store file {
path /path/to/logs/[topic]/[date];
name [time].log;
rotate 1hour; # 时间单位支持hour与min
}
采用该配置后,kids 会将日志按照 /topic/date/time.log
的形式存储,每小时进行一次文件的切分。 此外,还可以在文件存储配置块中添加flush 5s
之类的配置来确保内存中buffer的数据被及时写入到文件中。 这在处理量少但是较为关键的log类型时可能会带来帮助,但大部分时间你并不需要flush
选项,或者使用订阅模式来获得真正实时的数据。
store network {
host kidsserver;
port 3388;
}
store null {
topic kids.ignoretopic;
}
混合配置也分为三种方式:PriorityStore、BufferStore和MultipleStore:
store priority {
store null {
topic kids.ignoretopic1;
topic kids.ignoretopic2;
}
store network {
host kidsserver;
port 3388;
}
store file {
path /path/to/logs/[topic]/[date];
name [time].log;
rotate 1hour;
}
}
采用该配置后 kids 会忽略 kids.ignoretopic1 与 kids.ignoretopic2 的存储,对于其他 topic,会转发至 kidsserver:3388,若转发失败,会保存到指定文件中。
store buffer {
store network primary { # primary
host kidsserver;
port 3388;
}
store file secondary { # secondary
path /data/kidsbuf;
rotate 5min;
}
}
success
的类型,判断存储的成功与失败success
的值可选any
或者all
。store multiple {
success any;
# master
store buffer {
store network primary {
host kidsserver;
port 3388;
}
store file secondary {
path /tmp/kidsbuf;
rotate 10min;
}
}
# backup
store buffer {
store network primary {
host kidsbackup;
port 3388;
}
store file secondary {
path /tmp/kidsbuf2;
rotate 10min;
}
}
}
参考链接:
标签:日志
原文地址:http://blog.csdn.net/cool_sti/article/details/45073923