在字段可伸缩性的上下文中,重用字段与创建新字段之间有什么良好的平衡?


34

我已经在网站上阅读了以下短语:

与其将新字段添加到内容类型,不如添加现有字段是降低系统复杂性并提高可伸缩性的更好选择。

并产生了一些疑问。

在我们正在开发的系统中,我们有可能在3种或4种内容类型之间重用一个字段,但恐怕它不会像引号中所说的那样提高可伸缩性,因为它会减少它,因为该字段的表会更快成为瓶颈。 (至少在这种情况下,这是我的推理,因为该字段的所有值在一起每年将达到数百万美元,这会使表太大)。你同意吗?

进行架构时,要针对多少行是明智的最大目标?这样,我们可以决定何时重用字段以及何时创建新字段(即使存在重用的机会)。


6
我希望看到用实际指标备份的答案。
mpdonadio

认为我们已经针对这个问题收集了非常有建设性和有益的意见。但是,我将等待一两天,然后标记为已回答,因为我内心深处坚持认为,将一个或两个最重的字段分开(尽管它们可以重用)可能是个好主意:) ...特别是知道这些文件数量每年可以轻松增长5、10或2000万个项目。
rafamd 2011年

Answers:


24

字段中的数据量通常不是问题。如果您对此感到担心,请查看替代的现场存储插件或编写自己的插件。例如MongoDB,它可以处理您放入其中的几乎所有内容。例如,可以在http://examiner.com上使用它。

一个真正但是问题是你有字段数。因为当前在Drupal 7中,所有字段的完整字段配置(无论是否已加载)都是在每次单个请求时从缓存中获取的。

我见过具有250多个字段的站点,在其中加载和反序列化字段配置需要13MB +的内存。

编辑:使用Drupal 7.22 对字段信息缓存进行了改进(有关详细信息,请参见http://drupal.org/node/1040790),仅从缓存中加载了显示在特定页面上的包的字段,并且单独的缓存条目。仅当没有错误的API调用请求跨多个包的实例时,该方法才有效。


您好Berdir,谢谢您的回答。我不知道字段数的开销。因此,我们应该尝试尽可能多地重用,但仍然不应该尝试拆分那些我们知道最重的对象吗?我对mongo之类的知识了解不多,但是他们是否真的不在乎他们要查询的组的大小?谢谢 !
rafamd 2011年

我真的不知道 取决于,我猜。按照MPD的建议进行测试可能不是一个坏主意。您甚至可以直接在Mysql中对其进行非常低级的比较。创建两个具有与字段数据表相同的布局和索引的表,将10m(确保为object_id实际使用不同的值)行写入第一行,并将5m行写入第二行。然后比较写入性能和读取性能(基于entity_id,又称为索引)。我怀疑由于索引的原因,读取性能几乎是相等的,但是写入性能可能会有所不同。
Berdir 2011年

话虽这么说,拥有少量的田地并不会真正带来改变,所以如果您以这种方式感到舒适,那将不成问题。
Berdir 2011年

写作是棘手的部分,因此我建议您进行测试。可能违反直觉的事实是MySQL删除基于表而不是行的缓存条目(我上次检查)。我不确定哪个会更大,多个字段和表的内存开销或写入同一表的缓存丢失会带来更大的影响。当然,它确实取决于流量/使用情况。具有多个缓存(Drupal缓存,APC操作码,APC用户,MySQL查询缓存,memcached,清漆等)的系统使没有剖析的基于肠道的决策非常困难。
mpdonadio

情况不再如此:drupal.org/node/1040790
jackbravo

13

我完全同意伯迪尔。这是我在一个项目上的经验,该项目在某些节点类型上具有数百万行和30-40个字段。

  1. 字段表中的行数对于读取性能而言不是一个大问题,因为所有字段都是通过主键获取的。
  2. 编写新节点时,每个节点类型的字段数可能会迅速增长为严重的性能问题。创建新节点时,一个节点类型具有30+个字段会导致60+个INSERT语句。这需要几秒钟才能完成。如果您正在创建大量数据的用户,则会影响您的性能。批量插入1000个节点将花费近一个小时。如果必须更新100'000个节点,这是一个大问题。
  3. 如果您认为要解决的字段数问题,您应该认真考虑编写自己的字段存储,或者只是不使用字段。(仍然可以使您的节点付出更多努力来处理视图。)
  4. 关于MongoDB的一句话。这是一个非常有趣的项目,我希望它能成为大型DB的奥林匹克竞赛。不幸的是,与MySql或PgSql的成熟相比,这还算是婴儿。准备处理非常年轻的产品。

嗨,@BetaRide,谢谢您的见解。大约2),我们已经在尝试最小化每种内容类型的字段数,这与我们在此处讨论的内容不完全相同。真正的问题是:我应该在可能的情况下盲目重用字段,还是应该(至少)将最重的字段分开(即使它们很容易是相同的,例如:它们实际上具有相同的名称,等等)(至少)。是的,mongo应该是我们目前的最后选择:)
rafamd 2011年

5

如果您真的担心会发生什么,那么我认为应该进行模拟。

在Rackspace Cloud,Amazon,Linode或您可以轻松启动VPS的其他任何地方获得一个帐户。制作两个相同的实例。在每个上安装Drupal。创建一些虚拟内容类型,然后在一个系统中以一种方式设置字段,而在另一系统中以其他方式设置字段。使用devel模块创建大量内容。调整性能设置以确保Drupal可以根据需要进行缓存。运行mysqltuner并根据每个建议调整MySQL。仔细检查PHP和APC设置,以免发生交换,也不会搅动APC缓存。

一旦获得了良好的基准配置,就可以开始使用wget和drush模拟流量(正常访客和管理员更新),然后进行配置。

模拟永远不会完美,但是它们可以使您朝正确的方向前进。


2

在创建的表的每个字段中的每个单个表字段上使用索引时,字段的可伸缩性是一个问题。主键聚集索引是大多数字段的组合,然后在每个字段个体上创建了单独的索引。索引为数据库创建了大量的开销写操作,并且在大多数情况下从不使用。


2

另一个提示:拥有很多字段也会导致许多不同模块的问题。例如,如果您尝试编辑url别名,则Token GUI将使您的浏览器滞后几分钟。在将加载和显示令牌的所有页面上都可以看到此行为(包括devel-dpm()等)。

使用InnoDB时,将数据拆分到多个表中不会带来性能优势(由于表锁定,MyISAM有所不同)。所以-如果您知道您将拥有许多具有相似字段的相似内容类型(其配置也将相同,或者仅在标签上可能有所不同),请重用您的字段!

由于节点属性相似,它也可能简化模板的创建。


1

只是分享我的故事,我们正在使用Drupal Commerce,我们的产品变型(Sku)中有大约40个字段,然后在我们的产品展示中还有460个字段(是的,很疯狂)。我们有一些产品比较视图,可以查看所有这些领域。如果不进行缓存,则某些页面加载可能需要一分钟!

但是,它确实起作用。如果您确实使用了缓存和Varnish,则用户等待时间还不错。

我们在这么多字段中遇到的主要问题是Display Suite,因为如果我们尝试重新安排或移动某个字段,它将变得非常缓慢(有时无响应)。

幸运的是,我们决定对产品进行一些重构,以便我们可以将最复杂的产品的最大字段数降低到200-250范围内(因为我们使用的是科学仪器,因此需要复杂的测量和规格) 。


0

这是一个有趣的问题。我之前已经考虑过这一点,有时重用一个字段可能会很方便,因为不必让大量类似的字段“躺在”,但是拥有某种内容类型却不得不从大量的数据中进行选择似乎很愚蠢,知道并不意味着要返回结果。

我需要有关该项目的更多信息,以建议扩展最佳实践。预期流量是多少?要登录的用户有多少?例如,如果除您的管理员用户以外的所有流量都未经身份验证并匿名缓存


嗨@drupaljoe,谢谢您的回复。预期流量很难估算,因为它是一个全新的网站。它的开发非常谨慎,我们希望能取得某种成功,所以可以说我们设法拥有了数百个并发用户(其中​​大多数已通过身份验证)。这正是我的想法,查询巨大的表一定很痛苦,所以也许我们应该架构师重用那些不会增长太多的字段,并分开那些将保存更多数据的字段。什么可以被认为太多呢?百万 ?1亿?3亿?...
rafamd 2011年

我认为来自其他两个方面的评论应该没有多大关系,因为选择位于主键上是很好的观点。我想我会说现在就使用它,但是请确保您已对未来的选择,字段的mongo等进行了一些阅读。您不能总是对您的网站的未来
一无所知

0

到目前为止,我一直在重复使用字段,但是现在考虑为新项目使用每个节点类型的唯一字段。我实际上想将每个实体束的所有内容(字段,视图,规则,上下文等)很好地分隔开。因此它提出了可扩展性的问题,这导致了我的到来。我对Berdir的编辑感到很满意(Drupal 7.22 改进了字段信息缓存(有关详细信息,请参见http://drupal.org/node/1040790),仅从特定页面上显示的包的字段会被加载缓存,它们是单独的缓存条目。只有在没有错误的API调用(请求跨多个捆绑软件请求实例)的情况下,该方法才有效。

我只想指出,在多个复杂的站点上,我已经使用了一个非常有趣的模块几个月。:https : //www.drupal.org/project/render_cache。在我看来,这是这些隐藏的宝石之一。

正如在项目页面上所说的那样,注释部分实际上是在DO本身上使用的。

因此,考虑到所有这些,是否会使共识有利于其他领域?但是,关于DS的警告仍然令人um目结舌。它非常讨厌通过ajax保存的方式,而不是例如核心块管理界面如何处理重新排序的方式。我觉得这是ds问题,不过...


-3

根据我的建议,在单独的内容类型中使用相同的字段是个好主意。因为这将提高您的网站性能。在Drupal 7中,当您当时使用选择操作时,在内容类型中使用相同的字段对于您的Drupal7站点确实有用。


1
在Drupal 7中,他们开始使用Doctrine ORM ...不,他们没有。Drupal 8甚至不使用教义
Clive

“ Doctrine总是从所有映射的数据返回对象”,这也是一个错误的陈述。可以对对象进行注释,以表明默认行为不合适。这并不十分相关,因为正如Clive所说的那样,Drupal不使用Doctrine。
Letharion
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.