我需要为 Amazon VPC 中的一组服务器 (10-20) 设置集中式日志记录。日志记录应确保在任何单个服务器离线或整个可用区域离线的情况下不会丢失任何日志消息。它还应容忍数据包丢失和其他正常网络条件,而不会丢失或重复消息。它应将消息持久存储,至少存储在两个可用区域的两个不同 EBS 卷上,但 S3 也是一个不错的地方。它还应是实时的,以便消息在生成后几秒钟内到达两个不同的可用区域。我还需要同步不是通过 syslog 生成的日志文件,因此仅使用 syslog 的集中式日志记录解决方案无法满足所有需求,尽管我猜这个限制可以解决。
我已经审查了一些解决方案,我将在这里列出它们:
Flume 到 Flume 到 S3:我可以设置两个日志服务器作为 Flume 主机,将日志消息存储在本地或 S3 中,并使用端到端可靠性选项为所有服务器配置 Flume,以便将所有消息发送到两个服务器。这样,单个服务器的丢失不会导致消息丢失,并且所有消息都会实时到达两个可用区域。但是,需要某种方式来连接两个服务器的日志,对发送到这两个服务器的所有消息进行重复数据删除。这可以通过在发送端为每条消息添加一个唯一 ID,然后在日志文件上编写一些手动重复数据删除运行来实现。我还没有找到解决重复问题的简单方法。
Logstash 到 Logstash 到 ElasticSearch:我可以在服务器上安装 Logstash,并让它们通过 AMQP 向中央服务器交付,同时启用持久性选项。但是,要使它工作,我需要使用一些具有集群功能的 AMQP 实现,或者像 Flume 的情况一样扇出交付。AMQP 似乎是另一个移动部件,有几种实现,并且没有关于哪种设置最适合的真正指导。而且我并不完全相信我可以从 logstash 到 elasticsearch 获得真正的端到端持久性,假设中间服务器崩溃。扇出解决方案再次遇到重复数据删除问题。似乎可以处理所有情况的最佳解决方案是 Beetle,它似乎通过 redis 存储提供高可用性和重复数据删除。但是,我还没有看到任何关于如何使用 Logstash 进行设置的指导,而 Redis 又是另一个移动部件,这应该不会太难。
Logstash 到 ElasticSearch:我可以在所有服务器上运行 Logstash,在服务器本身中设置所有过滤和处理规则,然后让它们直接记录到远程 ElasticSearch 服务器。我认为这应该能给我带来可靠的日志记录,我可以使用 ElasticSearch 集群功能透明地共享数据库。但是,我不确定该设置是否真的能经受住 Logstash 重启和间歇性网络问题,而不会在故障转移或类似情况下重复消息。但这种方法听起来很有希望。
同步:我可以将相关日志文件全部 rsync 到两个不同的服务器。这里的可靠性方面应该很完美,因为同步完成后文件应该与源文件相同。但是,每秒执行几次 rsync 听起来并不好玩。此外,我需要日志在发送后不可篡改,因此 rsync 需要处于仅附加模式。而且,如果我不小心,日志轮换会把事情搞得一团糟。
带有 RELP 的 rsyslog:我可以设置 rsyslog 通过 RELP 向两个远程主机发送消息,并有一个本地队列来存储这些消息。这里又出现了重复数据删除问题,而且 RELP 本身也可能重复一些消息。但是,这只能处理通过 syslog 记录的内容。
这些解决方案似乎都不太好,并且仍然存在许多未知数,因此我在此向已经设置了集中式可靠日志记录的人员寻求更多信息,以了解实现该目标的最佳工具是什么。
答案1
我是日志记录我们即将发布我们软件的 Amazon EC2 云解决方案。我很乐意有机会讨论您的目标以及为您提供此解决方案的可能性。如果您有兴趣,请随时联系我。
虽然我确信您可以使用 rsyslog,但我们使用的是带有 tcp 的 syslog-ng(您也可以使用 tls 加密和基于磁盘的缓冲来确保安全并帮助确保消息传递)。
我们的测试箱每秒可发送多达 3000 个事件而不会丢失任何事件 - 全部在 Amazon EC2 微型箱上(请注意,这在生产中无法实现,主要是因为存储需求,但这证明了我们所做工作的成果)。
对于高可用性,使用两个目标日志服务器比尝试对它们进行重复数据删除要容易得多 - 然后,只需在两个服务器之间使用心跳,如果主服务器离线,则故障转移到备用服务器。如果您愿意,您仍然可以进行重复数据删除,但前者往往更容易实现并且效果很好。
同步非系统日志文件很简单,只需通过 perl 解析它们,然后使用 Log::Syslog::Fast 通过系统日志发送它们即可 - 我们的软件的 contrib 目录中包含一个示例(如果您需要副本,请查看 svn)。您也可以将它们复制到 LogZilla 服务器,然后直接将它们导入我们的预处理器。