【问题标题】:Reliable integration test for code using HyperLogLog?使用 HyperLogLog 对代码进行可靠的集成测试?
【发布时间】:2017-03-16 17:42:04
【问题描述】:

我们在 Algebird 中使用 Twitter 的 HyperLogLog 实现。给定一个数字 N 和我们系统中的一个检查,它使用 HyperLogLog 来估计逐渐增长的集合的当前大小并测试它是否大于或小于 N,我们如何编写一个集成或系统测试来测试这个检查并且是几乎可以保证通过,如果我们调用 HyperLogLog 的代码是正确的?被测系统是不确定的,因为一方面它是多线程的。

我的第一个想法是,编写对这个用例可靠的集成测试的正确方法是“放弃我们的标准”。那么,要发布到端点以确保 HyperLogLog 将估计项目总数大于 N(例如 >= 0.999999 的概率)的足够数量的项目 (M) 是多少?

或者有更好的方法吗?

标准错误界限是可配置的,但这并不能直接告诉我们偶尔可能会看到的最大错误界限——这是我关心的,以避免在 master 上随机失败的 CI 构建导致浪费时间和头发拉扯!

我还担心我们在测试中生成随机数据的方式可能不会在相关方面生成均匀分布的随机数据,这可能会对概率计算产生重大影响。

【问题讨论】:

  • 您是否能够插入带有每个桶“高度”/“前导零数”的“假货”?
  • @GregoryNisbet 我认为没有 API 方法可以做到这一点。

标签: integration-testing approximation hyperloglog


【解决方案1】:

让我们稍微分解一下。您希望测试两种主要行为:

  1. Twitter HyperLogLog 实现正确执行,即它可以很好地估计项目数。

  2. 使用 HyperLogLog 结构(例如计数器)的代码会在适当的时候递增它们。

请注意,行为 #2 很容易在构建时使用单元测试而不是集成测试进行测试。这是可取的,并且可以解决大多数问题。

案例#1也可以分为三种情况:

A,当项数为0时;

B,当项数较少时(5、100或1000);

C,当项目数量很大(百万/十亿)时。

同样,案例 A 和 B 可以而且应该在构建时使用单元测试进行测试。您应该根据您的应用程序决定可接受的错误范围,并让 UT 断言估计在这些范围内 - 您选择 HyperLogLog 作为基础估计方法并不重要,测试应该将估计器视为黑匣子.作为一个大概,我会说 10% 的错误对于大多数用途来说是合理的,但这实际上取决于您的特定应用程序。这些界限应该代表您的应用程序可以承受的最差精度。例如,严重错误的计数器可能根本无法处理任何估计错误,因此使用 HyperLogLog 应该会破坏单元测试。不同用户数量的计数器可能会承受高达 50% 的估计误差 - 这取决于您。

因此,我们只剩下最后一种情况了——测试 HyperLogLog 实现是否可以很好地估计大量项目。这不可能在构建时进行测试,实际上集成测试是要走的路。但是,根据您对 Twitter 的 HyperLogLog 实现的信任程度,您可能会考虑完全不测试 - Twitter 应该已经这样做了。这似乎与最佳实践有所不同,但考虑到可能与集成测试相关的开销,在您的情况下这可能是值得的。

如果您确实选择编写集成测试,则需要对生产中的预期流量进行建模并从多个来源生成它,因为您将生成数百万/数十亿个请求。您可以保存真实生产流量的样本并将其用于测试(可能是最准确的方法),或者计算出您的流量是什么样子并生成外观相似的测试流量。同样,应根据应用选择误差范围,并且您应该能够在不破坏测试的情况下将估计方法换成更好的方法。

【讨论】:

  • 我不理解您的观点,即“严重错误的计数器可能根本无法处理任何估计错误,因此使用 HyperLogLog 应该会破坏单元测试”。您肯定会在单元测试中使用模拟或伪造来代替实际的 HLL,因此单元测试不会解决这个问题吗?
  • 对,不清楚。我在谈论如何确定要测试的错误范围,关键是它实际上取决于应用程序 - 我试图给出的示例是依赖于精确估计的关键计数器的代码不应该能够在不破坏测试的情况下使用 HyperLogLog。无论如何,我想你明白了:)
猜你喜欢
  • 2014-10-29
  • 1970-01-01
  • 2012-07-23
  • 2016-11-11
  • 2014-09-26
  • 1970-01-01
  • 2018-10-31
  • 2013-04-07
  • 2019-12-17
相关资源
最近更新 更多