为什么在分布式存储中获取项目计数是一项代价高昂的操作?

Why getting items count in distributed storage is a costly operation?

我在读 JJ Geewax 写的那本关于 API 的书,叫做“API 设计模式”,其中有一节讲的是获取项目的数量,他说这不是一个好主意特别是在分布式存储系统中的想法。

第 102 页

Next, there is often the temptation to include a count of the items along with the listing. While this might be nice for user-interface consumers to show a total number of matching results, it often adds far more headache as time goes on and the number of items in the list grows beyond what was originally projected. This is particularly complicated for distributed storage systems that are not designed to provide quick access to counts matching specific queries. In short, it's generally a bad idea to include item counts in the responses to a standard List method.

任何人都知道为什么会这样,或者至少给我搜索关键字。

在典型的数据库中(例如,一个 MySQL 数据库,里面有几千兆的数据),计算行数非常容易。如果这就是您要处理的全部内容,那么提供匹配结果的数量就不是什么大问题了——当事情变得更大时,问题就会出现。

随着数据量开始增长(例如……10T?),动态计算匹配行的准确计数可能会开始变得非常昂贵(您必须扫描并保持 运行 计数所有匹配数据)。即使使用分布式存储系统,这也可能很快,但仍然很昂贵。这意味着您的 API 将花费大量计算资源来计算结果总数,而它本可以做其他重要的事情。在我看来,这是一种浪费(API 上的“nice-to-have”是一笔很大的开销)。如果计数对 API 至关重要,那么计算就会改变。

此外,随着对数据的更改变得越来越频繁(更多的创建、更新和删除),计数变得越来越不准确,因为它可能从一秒到下一秒发生巨大变化。在那种情况下,不仅需要做更多的工作来得出一个数字,而且这个数字甚至都不是那么准确(而且大概在那个时候不是很有用)。

所以总的来说......更大数据集的结果计数往往是:

  1. 比业务关键nice-to-have更多
  2. 不准确

并且由于 API 的寿命往往比我们预测的要长得多,并且可以长到比我们想象的大得多的大小,我不鼓励在 API 回复中包含结果计数。

虽然每个 API 都是不同的,所以在您的 API 中进行计数可能是有意义的,但我仍然建议使用粗略估计而不是 future-proof 的精确计数API.

包括计数的一些充分理由:

  1. 您的数据大小将保持相当小(即,能够由单个 MySQL 数据库提供服务)。
  2. 结果计数对您的 API(不仅仅是“nice-to-have”)至关重要。
  3. 对于您的用例,您得出的任何数字都足够准确(即小数据集或“良好估计”的准确数字,而不是无用的估计)。