【问题标题】:Improving the efficiency of searching a normalised logs table提高搜索规范化日志表的效率
【发布时间】:2020-01-17 00:15:48
【问题描述】:

多年来,我一直使用 PHP 和 MySQL 以标准化格式记录用户交互日志,例如:

  • Lo​​gID(整数)
  • 用户 ID(整数)
  • TargetUserID(可选整数)
  • ActionID (int)
  • AdditionalString1(字符串)
  • AdditionalString2(字符串)

这将允许我之后使用 PHP 重新构建日志以创建如下日志:

  • John Smith 将 Amy Adams 从服务器中踢出“垃圾邮件”(存储为“1,1,2,1,'spamming messages','')
  • Amy Adams 向 John Smith 发送了 300,000 美元的“house payment”(存储为“2,2,1,2,'300000','house payment')

所有同时只存储非常少量的数据,如图所示。

问题在于,为了搜索这些数据,必须在过滤之前重建每条日志消息。因此,如果我有 500,000 条日志消息,我必须将所有 500,000 条解析为上述格式,以便匹配过滤器,例如“Smith kicked”(匹配第一个日志)或“sent John”(匹配第二个日志) )。

我知道我可以将日志消息以全文形式存储,但这让我很担心,因为当用户更改名称或日志消息格式更改时,这些旧消息会卡住。

我只能假设有一个最佳实践,我担心可能会使用其他技术,例如 Logstash,但只是想先看看人们的想法。

提前致谢。

【问题讨论】:

  • 您是否有用于操作名称、用户名(日志表中的所有 FK)等的主表?如果是,为什么不简单地适当地加入它们,并过滤那里的值。
  • 我们发现对于日志记录,尤其是搜索,MySQL 并不是理想的工具。我们将完整消息和一些单独字段的组合记录到 ElasticSearch。搜索日志非常灵活。缩放很容易。清理旧日志很简单。我是 MySQL 的忠实拥护者——根据我的经验,它并不是这个特定目的的最佳工具。
  • @MadhurBhaiya 目前所有的解析都是用 PHP 完成的,所有的日志格式都存储在代码中。这是因为日志之间的格式不是标准化的。例如,一个日志可能写为 ,而下一个日志可能是 。也许这可以转换为 MySQL,我不太确定......虽然我担心这将是一项艰巨的任务
  • @Timo 这就是我担心的结果......我们确实将 ElasticSearch 用于其他一些东西,但是这个特殊的环境是轻量级的,并且没有 ELK 堆栈,所以我希望我可以想出一个更简单的解决方案,但可能不得不回退到这个(现有的解决方案适用于少量日志)。
  • @DuncanMcArdle 您能否详细说明您的搜索要求?谁想要搜索,以什么方式,为什么?这可能有助于在不引入额外基础设施的情况下找到一种方法。

标签: php mysql sql database logging


【解决方案1】:

有几种技术可以优化算法,需要遍历所有日志才能系统地解析它们。

您可以使用的一种技术是为昂贵的操作缓存部分结果,并在可能的情况下重用缓存的结果。在您的情况下,数据库 SELECT 查询的缓存结果意味着您不需要多次执行相同的 SELECT 查询 - 在某些情况下,它可能会执行数百/数千/数百万次。此技术也称为 Memoization,是 dynamic programming 中使用的技术之一。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-05-19
    • 1970-01-01
    • 1970-01-01
    • 2016-01-19
    相关资源
    最近更新 更多