【问题标题】:Database architecture for millions of new rows per day每天数百万新行的数据库架构
【发布时间】:2011-03-31 09:31:38
【问题描述】:

我需要为大量网站实施定制开发的网络分析服务。这里的关键实体是:

  • 网站
  • 访客

每个唯一访问者在数据库中都会有一行,其中包含登录页面、一天中的时间、操作系统、浏览器、引荐来源网址、IP 等信息。

我需要对此数据库进行汇总查询,例如“统计所有使用 Windows 作为操作系统并来自 Bing.com 的访问者”

我有数百个网站要跟踪,这些网站的访问者数量从每天几百到几百万不等。总的来说,我预计这个数据库每天会增长大约一百万行。

我的问题是:

1) MySQL 是一个很好的数据库吗?

2) 什么是好的架构?我正在考虑为每个网站创建一个新表。或者,如果现有表中的行数超过 100 万,则可能从单个表开始,然后(每天)生成一个新表(我的假设是正确的)。我唯一担心的是,如果表变得太大,SQL 查询会变得非常缓慢。那么,每个表我应该存储的最大行数是多少?此外,MySQL 可以处理的表数量是否有限制。

3) 对数百万行进行聚合查询是否可取?我准备等待几秒钟以获取此类查询的结果。这是一种好的做法还是有其他方法可以进行聚合查询?

简而言之,我正在尝试设计一种大型数据仓库类型的设置,这种设置会很繁重。如果您知道任何已发表的案例研究或报告,那就太好了!

【问题讨论】:

  • 如果您已经设计了数据库。可以分享一下数据库设计吗?

标签: mysql database scalability analytics data-warehouse


【解决方案1】:

一些与数据库无关的建议。

最简单的理性是区分读密集型和写密集型表。每天/每周创建两个并行模式和一个历史模式可能是个好主意。可以适当地进行分区。可以考虑使用来自每日/每周模式的数据来更新历史模式的批处理作业。再次在历史模式中,您可以为每个网站创建单独的数据表(基于数据量)。

如果您只对聚合统计数据感兴趣单独(可能为真)。有一个汇总表(每月、每天)是一个好主意,其中存储了汇总的总访客数、重复访客数等;这些汇总表将在一天结束时更新。这样就可以在不等待历史数据库更新的情况下即时计算统计数据。

【讨论】:

  • 保持读写表分开的有趣建议。任何具体的建议为什么会有所帮助(而不是使用队列进行批量写入)?
  • 大多数数据库都提供离线导出导入规定。用于 oracle 的 sqlloader,用于 db2 的 db2export/import。我认为是mysql的mysqldump
【解决方案2】:

如果您谈论的是大量数据,请查看MySQL partitioning。对于这些表,按数据/时间进行分区肯定会提高性能。有一篇关于分区here 的不错的文章。

看看创建两个独立的数据库:一个用于写入的所有原始数据,索引最少;第二个用于使用汇总值进行报告;使用批处理从原始数据数据库更新报告数据库,或使用复制为您完成。

编辑

如果您想真正巧妙地处理汇总报告,请创建一组汇总表(“今天”、“周至今”、“月至今”、“按年”)。每天或“实时”从原始数据汇总到“今天”;每晚从“按天”汇总到“迄今为止的一周”;每周从“一周至今”到“本月至今”等。执行查询时,为您感兴趣的日期范围加入(UNION)适当的表。

编辑#2

我们不是每个客户端一个表,而是每个客户端使用一个数据库架构。根据客户端的大小,我们可能在单个数据库实例中有多个模式,或者每个客户端有一个专用的数据库实例。我们为原始数据收集和每个客户的聚合/报告使用单独的模式。我们运行多个数据库服务器,将每个服务器限制为单个数据库实例。为实现弹性,数据库在多台服务器之间复制并进行负载平衡以提高性能。

【讨论】:

  • 实际上聚合将发生在任意列上。因此,这不仅仅是关于唯一访问者或重复访问者的数量,而是用户可以选择任何变量组合(操作系统、浏览器、引荐来源、一天中的时间)来进行细分。这就是让它变得有点困难的原因,因为我需要为此访问原始数据。
  • 我的业务正在为一些非常大的客户(AA、几家主要银行和保险公司、大型旅行社),因此我们获得了同样大的数据量(每天数百万行)。我们在 Oracle 而不是 MySQL 上运行,但许多原则是相同的。我们更喜欢提供向下钻取报告,允许使用汇总数据生成高级报告,并选择性地“向下钻取”基础原始数据。
  • 您是否永久存储历史数据?或者您有清除策略(比如删除所有超过 100 天的数据)?
  • 我们实际上将所有数据保留在 7 年的期限内,之后将被存档。考虑到网络的发展速度,七年可能过多; 2 年或(可能)3 年应该绰绰有余;但是我们有几个客户想要 7 年,并且更容易在整个客户群中应用该规则。有几年的时间来运行“比较”报告(例如,将今年 7 月的数据与之前的 7 月数据进行比较)和趋势报告很有用。
  • 7 年增补...此外,我们可以收取维护额外数据量的费用(如果已明确要求)
【解决方案3】:

您确实应该使用“真假”数据(正确的格式和长度)测试尽可能接近真实环境的模拟环境。基准查询和表结构变体。既然您似乎了解 MySQL,就从那里开始。设置几个用查询轰炸数据库的脚本应该不会花费您那么长时间。使用您的数据类型研究您的数据库的结果将帮助您了解瓶颈会出现在哪里。

不是一个解决方案,但希望能在途中有所帮助,祝你好运:)

【讨论】:

    【解决方案4】:

    您绝对应该考虑跨数据库或架构按站点拆分数据 - 这不仅可以更轻松地备份、删除单个站点/客户端等,而且还消除了确保没有客户可以看到任何其他站点的麻烦客户数据意外或编码不佳等。这也意味着更容易选择分区,超过数据库表级分区,时间或客户端等。

    您还说数据量是每天 100 万行(这不是特别繁重,不需要巨大的能力来记录/存储,也不需要报告(尽管如果您在午夜生成 500 个报告,您可能logjam)。但是你也说有些网站每天有 100 万访问者,所以你的估计可能太保守了?

    最后,您没有说您是否想要实时报告 la chartbeat/opentracker 等或像谷歌分析这样的周期性刷新 - 这将从第一天起对您的存储模型产生重大影响。

    M

    【讨论】:

    • 马克,感谢您的回复。报告需要实时完成。这就是挑战之一。你说每天一百万行并不重。 3 年内,数据库总容量将达到 10 亿行左右。那不是很大吗?我特别担心数据不断增加的性质。我们不可能永久存储所有数据?
    • 当然,您需要对其进行一些调整,以确保您同时拥有存储容量和强大的功能,但是通过合理的分区,您应该能够将更新的性能和确实的报告与当你扩大规模时容易受到问题的影响。您可能需要围绕在其中构建一些聚合表并拥有正确的模型来支持您尝试提供的 BI 方面做出一些明智的选择。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-09-15
    • 2018-12-21
    • 2018-03-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多