当涉及磁盘时,最快的稀疏矩阵访问

时间:2014-09-09 15:07:00

标签: bitmap rdbms database-performance graph-databases key-value-store

想象一下,你有一张桌子'用户'有10个Mio记录和一个表'组'有1个mio记录。平均而言,每组有50个用户,我至少会在名为users2groups的表中的rdbms中存储。 users2groups实际上是一个稀疏矩阵。用户和组的完整数据集中只有80%适合可用内存。组成员资格(users2groups)的数据排在最前面,因此如果需要内存来缓存组成员资格,则必须从用户或组表或两者中取消分配。

我希望能够:

  • 按名称快速查找用户
  • 按名称快速查找群组
  • 快速获取群组中的所有用户
  • 快速获取用户所属的所有群组

根据我所知道的经验,磁盘延迟会确定您的访问速度。您还可以在读写速度之间取得平衡。然而,在人们可以做到这一点之前,现在必须决定数据库类型......例如:

  • 关系DBMS
  • 键值商店
  • 文件商店
  • RDF商店
  • 面向对象的DBMS
  • 图表DBMS
  • 搜索引擎
  • 多值DBMS
  • 原生XML DBMS
  • 宽列商店
  • 内容商店
  • Navigational DBMS
  • (压缩)位图
  • 文件
  • 更多...?

所以问题是当RAM容量低于考虑稀疏matixes的可用数据时,所有这些系统中的哪一个或哪些组合提供最佳的整体读访问性能(具有可接受的写访问性能)? ......在选择的技术中,如何平衡所有三个实体/表中的内存利用率......?

由于这是一个概念性问题,因此磁盘空间和CPU容量超出范围或被视为可用"无限期"。

顺便说一下。我知道通过使用基于哈希的索引(例如crc32(lower(STRING)))可以有效地加速搜索用户名或组名这样的名称 - 一个例子选择就是这样:选择一些有用的东西其中name = SEARCHSTRING和hash = crc32(lower(SEARCHSTRING))的用户。但是,当我说用户和组表具有80%的RAM覆盖率时,哈希及其索引还没有包含在内存中。这是因为我不清楚,如果没有更好的集成解决方案。目前我只是假设,将整个主题分解为三个部分用户,组和用户2组是最明智的。我在这里缺乏证据。

-------------------- UPDATE -------------------------- -----------

我知道桌子上有相互竞争的概念:

  • 非规范化到一个扩展,我可以使用一组非常简单的查询对磁盘。 (例如,mongodb等)
  • 压缩数据,以便大多数数据无论如何都适合内存(例如压缩位图)

因为非规范化意味着:“炸毁数据量'这两个概念似乎相互矛盾。是否有最佳实践或科学或明智的论据,何时使用非规范化以及何时使用挤压数据方法?例如。一个KPI说:如果少于80%适合内存,那么去非规范化吗?

-------------------- UPDATE -------------------------- -----------

额外的内存需要额外的资金,大多数数据库服务器通常会有很多空磁盘空间让他们感到无聊。所以非规范化很便宜。另一方面,非规范化机会是有限的:磁盘延迟在物理上限制了每秒最大查询量,完全停止。因此,对磁盘的查询太多会排队,这会对具有大量流量的应用程序进行非规范化约束。甚至非规范化的数据访问速度也在很大程度上取决于内存。

所以也许KPI在这里是不可能的。无论如何,对于给定的稀疏矩阵示例,如何对非规范化和挤压数据方法进行平衡?我想在压缩用户和组表时,将它们留在rdbms中,然后将释放的内存分配给服务于users2groups关系的文档db的缓存。然而,这引入了一整套新问题,例如处理2个数据库系统的多次往返以及更复杂的查询管理。那么如何解决这个问题?

-----------------------更新-----

根据lagivan的建议,只有标记关系的稀疏矩阵似乎以合理的方式解决:拥有2个表用户和组,然后在表中用户具有ID与组相关的多字ID字段,反之亦然在表格组中,多个ID字段包含与用户相关的字段。我想这个解决方案并没有与特定技术紧密结合。它甚至可以通过VARBINARY或任何blob在MYSQL中实现。

问题的突出部分与包含一些果汁信息的稀疏矩阵有关。喜欢status或lastupdatedate。因此,使用外键数组会按概念禁用这些信息。因此,针对此类场景的原始问题仍然存在:当RAM容量低于考虑稀疏matix的可用数据时,所有这些系统中的哪一个或哪些组合提供最佳的整体读取访问性能(具有可接受的写访问性能)? ......在选择的技术中,如何平衡所有三个实体/表中的内存利用率......?

2 个答案:

答案 0 :(得分:1)

考虑到您无法将完整的数据集放入RAM中,您无论如何都会遇到由I / O操作引起的性能问题。因此,您只能依赖缓存和最佳数据结构(db类型)。而且,我相信您应该选择面向未来的解决方案。我不能涵盖所有的数据库类型,但我投票反对RDBMS,因为有一个稀疏矩阵users2groups应该是相当低效的。以下是一些选项:

  1. 如果你对users2groups关系进行非规范化,那么文档存储(例如MongoDB)将是一个不错的解决方案,特别是如果你使用分片为用户和组使用多个服务器将它们放入内存中。因此,每个用户文档都将包含组列表,每个组将包含用户列表。因此,只要加载了用户记录,就可以进行缓存,您将免费获得组列表。
  2. RDF / Graph商店也可能是一个很好的解决方案。特别是如果使用SaaS解决方案是您的选择,那么扩展将更容易。例如,我们正在使用Dydra图数据库。在这种情况下,无论如何都会对数据进行标准化。
  3. 如果您更喜欢基于模式的数据,原生XML存储(例如eXist-db)也会起作用。在这里,我应用与文档存储选项相同的非规范化。
  4. 最后,我相信魔鬼在于细节。由此产生的性能主要取决于您的DBA的技能和经验。

    <强>更新

    考虑到存储与users2groups交叉引用相关的更多数据的额外要求,我建议两个选项:

    1. 保持用户2组的非规范化(MongoDB案例)。考虑到您的用例,我感觉组是管理users2groups关系的中心点。您最需要有关组的统计信息,但不需要有关用户的统计信息。然后,您应该将关系数据(创建,修改日期,状态)存储在组文档中。无论状态如何,用户文档都只包含链接组ID的列表。
    2. 拒绝非规范化。在这里,您可以选择使用图形数据库,也可以使用其他RDBMS表或MongoDB集合users2groups。在后一种情况下,您将不得不使用表连接或多个请求(MongoDB)。当然,与第一种选择相比,它会降低性能。但是如果你想出更多的关系数据或更复杂的用例,它会更有益。

答案 1 :(得分:0)

这是针对与稀疏矩阵相关的问题的一部分,该稀疏矩阵包含一些“果汁信息”,如状态或lastupdatedate。

我试图概括答案的第一部分:事实上我没有找到真正的理由,为什么要从RDBMS转变为任何其他技术来更好地解决稀疏矩阵。因此,我们只考虑RDBMS(非规范化数据可以存储在varbinary或blob中)。我是正常化的忠实粉丝。然而,我现在学到的是:非规范化,如果非规范化导致考虑数据和索引数据的较低内存消耗。规范化规则的目标是优化数据的内存消耗,而不考虑存在诸如稀疏矩阵(具有索引的外部 - 外键 - 密钥对)的情况,这些情况很容易混淆规范化的益处和努力。我也(重新)学会了,尽可能地将数据压缩到内存中是性能的关键(也是基于缓存的性能杠杆的滞后)。

话虽如此,答案的第二部分还有各种选择:

来自Lagivan的更新+

  • 为每个“果汁信息”用例都有一个自己的总和/跟踪/审核表 - 也就是根据汇总数据及时进行非规范化。
  • 结合非规范化和规范化,其中非规范化只适用于普通关系(参见答案的第一部分),使用“果汁信息”进行规范化的时间范围非常有限(例如,三个月)
  • 将“果汁信息”写入任何日志文件,而不是偶尔汇总报告(例如,每天一次) - 这就是数据仓库所做的事情

现在的解决方案是计算索引AND数据的每个可接受解决方案的内存消耗,然后选择具有最低消耗值的选项。顺便说一下,每个选项都有不同程度的实施工作。