集中记录 - 首先写入本地文件?

Centralized Logging - Write to local file first?

我有一台服务器 API,它有几个应用程序实例和一个工作实例。目前,应用程序将一些数据发送到 Loggly(一种 SAAS 集中式日志记录服务)。这很好开始,但我开始考虑使用一些开源软件创建一个设置。

此外,我目前使用 Loggly 的成本最大的问题是:在请求结束时连接到 Loggly 以记录数据,这会增加请求的时间。

我阅读了一些关于 Logstash、Graphite、ElasticSearch 等与 LogRotate 结合使用的资料,一些消息来源似乎建议写入每台服务器上的本地文件,然后在 LogRotating 时将它们发送到Logstash

我很好奇人们认为在集中式日志记录场景中哪些做法最有效。我应该先写入每台服务器上的本地文件吗?或者是将每个框设为 "stateful" 而不是我应该直接将数据从 Logstash 或 SQS 发送出去,以便由中央服务器处理?

当谈到集中式日志记录场景时,将日志生成器与 logstash 紧密耦合和松散耦合之间存在实现差异。对于非常大的规模,应避免向中间紧耦合。紧耦合是在你的生产者和你的接收者之间创建一个套接字来传输事件,如果接收者很慢,这会在 生产者 端产生延迟。

松散耦合有多种方法:

  • 队列调解,通过 SQS、Redis、Kafka、AQMP 等
  • 文件-中介,通过文件。

我所知道的非常大的集中式日志记录系统都在集中层使用某种形式的队列调解。

也就是说,在边缘,用例是不同的。如果您需要避免写入文件以减少 I/O,使用 TCP 或 UDP 套接字传输到本地安装的 logstash(然后将事件发送到中央队列)会非常快。

使用 logstash 的集中式日志记录可以采用多种形式。如果您可以在您的日志生成节点上安装 logstash,那么这是一种非常有效的架构:

  • Logstash 安装在生产节点上。
    • 该实例配置为侦听 TCP 端口以进行应用程序日志记录,并侦听一些文件以进行系统日志记录。
  • Instance-logstash 将事件发送到 SQS。
  • 一组解析器-logstash 实例从 SQS 中提取作业并处理它们,输出到任何地方。

在这个架构中,所有的过滤逻辑都放在 parser-logstashes 中,而 instance-logstash 只是一个托运人。最好的部分是解析器-logstash 层可以根据负载保证进行扩展和缩小。这使 instance-logstash 保持最小的内存占用,因此它不会与应用程序竞争资源。

由于 Logstash 有一个 loggly 插件,如果您愿意,您仍然可以在那里提供数据,同时在本地保留一份副本。

文件与直接连接

最好通过回答几个问题来在这两者之间做出决定:

  • 如果我通过 TCP 套接字之类的东西直接连接,如果日志接收器在 5 分钟内不可用,我的应用程序会怎样?
  • 我的实例对存储有多敏感I/O?

文件是实例上松耦合的一种方法。如果您对第一个问题的回答是,应用程序暂停,直到日志接收器返回,您可能不希望这种紧密耦合。在这种情况下,日志文件是提供缓冲区的一种方式。如果这对您很重要,那么将在实例重启后继续存在的缓冲区。

它正在保持实例的状态。但是,它应该是非常短暂的状态。日志传送器应足够快地将状态转储到中央队列系统,您不会保留超过几秒钟。

如果你对存储很敏感I/O,对TCP状态也很敏感,你还是可以queue-mediate到一个点。安装一个本地 redis 实例,让您的应用程序发送到该实例,然后让 logstash 从那里拉取并发送到中央队列。这允许应用程序从队列事件集中缓冲。不过,在某些情况下,如果应用程序可以配置为直接发送到中央队列,那么它仍然更好。