用于 Web 访问日志的实时数据仓库

Posted

技术标签:

【中文标题】用于 Web 访问日志的实时数据仓库【英文标题】:real-time data warehouse for web access logs 【发布时间】:2009-12-30 22:16:23 【问题描述】:

我们正在考虑建立一个数据仓库系统来加载我们的网络服务器生成的网络访问日志。这个想法是实时加载数据。

我们希望向用户展示数据的折线图,并让用户能够使用维度进行深入分析。

问题是如何平衡和设计系统,以便;

(1) 可以实时(

(2) 可以按每小时和每天汇总数据,并且

(2) 大量数据仍然可以存储在仓库中,并且

我们当前的数据速率大约为每秒约 10 次访问,这为我们提供了每天约 800k 行。我对 mysql 和简单星型模式的简单测试表明,当我们有超过 800 万行时,我的查询开始花费超过 2 秒的时间。

是否有可能从像这样的“简单”数据仓库中获得实时查询性能, 并且仍然让它存储大量数据(能够从不丢弃任何数据会很好)

有没有办法将数据聚合到更高分辨率的表格中?

我有一种感觉,这并不是一个真正的新问题(不过我已经用谷歌搜索了很多)。也许有人可以给这样的数据仓库解决方案加分吗?想到的一个是 Splunk。

也许我抓得太多了。

更新

我的架构是这样的;

尺寸:

客户端(IP 地址) 服务器 网址

事实;

时间戳(以秒为单位) 传输的字节数

【问题讨论】:

非常非常有趣的问题。这很时髦,我不知道,但我也想了解这个...... 【参考方案1】:

上面赛斯的回答是一个非常合理的答案,我相信如果你投资于适当的知识和硬件,它很有可能成功。

Mozilla 做了很多网络服务分析。我们每小时跟踪详细信息,并使用商业数据库产品 Vertica。它非常适合这种方法,但由于它是专有的商业产品,因此具有不同的相关成本。

您可能想要研究的另一项技术是 MongoDB。它是一个文档存储数据库,具有一些使其可能非常适合此用例的功能。 即上限集合(搜索 mongodb 上限集合以获取更多信息)

还有用于跟踪页面浏览量、点击量等的快速增量操作。 http://blog.mongodb.org/post/171353301/using-mongodb-for-real-time-analytics

【讨论】:

谢谢,我查看了 MongoDB 来保存我的非关系数据。也许它也适合其他事物。对每个事实都有一个独特的维度(例如客户端 IP 地址)是不好的做法吗?正如我所看到的,这使得无法将数据聚合到较低分辨率的表中。还是我错过了什么? 如果您只想存储客户端IP地址,那么您可以将其存储为退化维度。由于基数高,它仍然会很丑陋,但可以做到。如果可以的话,您会希望避免将其设置为单独的维度,因为连接两个极高的基数表对性能非常不利。【参考方案2】:

听起来这不是问题。 MySQL 非常快。

要存储日志数据,请使用 MyISAM 表——它们速度更快,非常适合 Web 服务器日志。 (我认为 InnoDB 现在是新安装的默认设置 - 日志表不需要外键和 InnoDB 的所有其他功能)。您也可以考虑使用merge 表 - 您可以将单个表保持在可管理的大小,同时仍然能够将它们作为一个大表访问。

如果您仍然跟不上,请按顺序为自己准备更多内存、更快的磁盘、RAID 或更快的系统。

另外:永远不要丢弃数据可能是个坏主意。如果每行大约 200 字节长,那么您说的是每年至少 50 GB,仅用于原始日志记录数据。如果有索引,则至少乘以 2。再次乘以(至少)2 进行备份。

您可以根据需要保留所有数据,但我认为您应该考虑将原始数据存储几周,将汇总数据存储几年。对于任何旧的,只需存储报告。 (也就是说,除非法律要求您保留。即使那样,也可能不会超过 3-4 年)。

【讨论】:

感谢您的回答。将更多地研究MySQL。这个想法是使用星型模式,将日志行的时间戳放在事实表中。这使每个日志条目的数据保持在较低水平,但是如何聚合这种数据呢?客户端很可能永远不会再次请求相同的实体,因此相同的(客户端、资产、服务器)行将永远不会在表中出现两次。 为了收集数据,我会创建一个包含一堆列的表——如果你做的事情比这更有趣,你必须花时间打开其他表并在服务器负载时进行计算.由于您表示您已经无法跟上进度,因此您可能希望尽可能简化。如果您设置一个从服务器来进行规范化和聚合(将报告与日志分离),那么您可以进一步减少主服务器的负载。【参考方案3】:

另外,请研究分区,尤其是当您的查询主要访问最新数据时;您可以 - 例如 - 设置约 550 万行的每周分区。

如果汇总每天和每小时,请考虑使用日期和时间维度——您没有列出它们,所以我假设您不使用它们。我们的想法是在查询中不包含任何函数,例如 HOUR(myTimestamp) 或 DATE(myTimestamp)。日期维度的分区方式应与事实表相同。

有了这个,查询优化器可以使用分区修剪,所以表的总大小不会像以前那样影响查询响应。

【讨论】:

我是否正确理解您在查询中不应使用任何函数?它们对性能有那么大的影响吗?根据时间维度进行连接是否更快? 是的,这是正确的——请记住,必须为每一行数据评估一个函数。正确设置后,WHERE 子句仅包含维度表字段、常量和 ` = = AND `;如果你有一个函数,那么在维度表中预先计算它。 同样对于查询优化器使用分区修剪,只允许` = = BETWEEN`。当优化器使用分区修剪时,只扫描包含 WHERE 数据的分区,其他分区被忽略——速度更快。【参考方案4】:

这已成为一个相当常见的数据仓库应用程序。我已经运行了多年,它每天支持 20-1 亿行,响应时间为 0.1 秒(来自数据库),来自 Web 服务器的响应时间超过一秒。这甚至不在大型服务器上。

您的数据量不会太大,因此我认为您不需要非常昂贵的硬件。但我仍然会选择多核、64 位和大量内存。

但是您将希望主要访问聚合数据而不是详细数据 - 特别是对于按天、月等进行的时间序列图表。聚合数据可以通过异步过程在您的数据库上定期创建,或者在这种情况下如果转换数据的 ETL 过程创建聚合数据,则通常效果最佳。请注意,聚合通常只是事实表的分组依据。

正如其他人所说 - 访问详细数据时,分区是一个好主意。但这对于聚合数据而言并不那么重要。此外,对预先创建的维度值的依赖比对函数或存储过程的依赖要好得多。这两种都是典型的数据仓库策略。

关于数据库 - 如果是我,我会尝试使用 Postgresql 而不是 MySQL。原因主要是优化器的成熟度:postgresql 可以更好地处理您可能运行的各种查询。 MySQL 更容易在五向连接上感到困惑,在运行子选择时自下而上等。如果这个应用程序很有价值,那么我会考虑像 db2、oracle、sql server 这样的商业数据库。然后,您将获得额外的功能,例如查询并行性、针对聚合表的自动查询重写、额外的优化器复杂性等。

【讨论】:

以上是关于用于 Web 访问日志的实时数据仓库的主要内容,如果未能解决你的问题,请参考以下文章

Flink实时数仓数据仓库项目实战 《四》日志数据分流 DWD

Greenplum 实时数据仓库实践——实时数据同步

Greenplum 实时数据仓库实践——实时数据同步

日均百亿级日志处理:微博基于Flink的实时计算平台建设

日志服务Python消费组实战:实时跨域监测多日志库数据

实时数据仓库介绍(Genie)