【问题标题】:Best data structure for large dataset that changes frequently经常变化的大型数据集的最佳数据结构
【发布时间】:2018-07-09 23:56:52
【问题描述】:

这是场景:

  1. 我们有一个包含 > 2,000,000 个数据点的大型数据模型。
  2. 每个数据包括:测量值(int 或 float)、时间戳、质量枚举(好、坏、未知)和唯一 ID。
  3. 测量值更新通过 Kafka 进行,每秒更新大约 20% 的测量值。
  4. 每隔几秒,就会针对当前测量模型运行一个算法。此时内存中的快照被锁定
  5. 算法完成后,测量模型会随着等待 kafka 总线的更改进行更新。

用于测量模型的内存快照的最佳数据结构(对于性能)是什么?

谢谢

【问题讨论】:

  • 您如何访问这些元素?凭身份证?
  • 按ID,是的。
  • 您可能会使用在std::mapstd::unordered_map 中实现的二叉搜索树或哈希表。
  • 数据集的长度是固定的还是可以增长/缩小? - 你需要或有一个int vs float的标志吗? - ID 是什么类型,ID 是否连续(或者您仍然可以更改类型)? - 数据被锁定了多长时间(在这段时间内,同一 ID 是否可以有多个挂起的更新)? - 数据以什么形式到达(json、二进制)?
  • 时间戳的分辨率是多少?

标签: c++ performance data-structures apache-kafka bigdata


【解决方案1】:

所以你的每个数据(基本上)都是以下结构:

struct datum {
    unsigned char guid[16];
    enum { Int, Float } measurement_kind;
    union {
        int i;
        float f;
    } measurement;
    time_t timestamp;
    enum { Good, Bad, Unknown } quality;
};

大小为 40 字节。如果您有 200 万个这样的数据,那么总计将达到大约 80 兆字节。即使您的数据结构有 4 倍的开销,这也不是完全“大”数据。一些 Xeon CPU 几乎可以将其放入其 L3 缓存中


至少,您需要一个具有快速 ID 查找功能的数据结构。所以哈希表 (std::unordered_map) 是显而易见的选择。但是,您可能可以利用一些东西来帮助您推出自己的哈希表实现,它的性能可能会更好。

  1. 如果您的 ID 是连续的(而不是我假设的 Guid),那么您可以使用 数组,而不是哈希表,它的明显优势是不需要哈希功能。只需使用索引即可。
  2. 如果您有固定(或有限)数量的数据点,您可以将实际数据点存储在连续内存中。使用具有固定负载因子的开放寻址哈希表 (unlike std::unordered_map) 也可能更快。测试将指向元素的指针和元素本身存储在表中。
  3. 如果您可以拥有 Kafka 结果的所有权,那么复制指针而不是完整结构可能会更好。内存碎片可能会使这变慢,但也可能不会。
  4. 如果您知道某些度量值变得“热”(即经常更新),那么在连续存储和哈希表链中对它们重新排序可能会改善您的缓存局部性。
  5. 如果您知道在更新期间不会更改哈希表,那么您可以对更新进行分区并简单地并行化它们,而无需锁定。

在所有情况下,您都应该根据标准库实现测试这些潜在的改进(如果适用)。如果不衡量性能,就不可能给出确定的答案。

【讨论】:

  • 这正是我想要的。谢谢你。我显然会测试 std::map,但我想我可以推出自己的解决方案来提高性能。
  • 很高兴您发现我的回答很有用:)
  • "40 bytes in size" 使用什么序列化?阿夫罗? Protobuf?
  • @cricket_007 - 大小为 40 字节,使用 sizeof(struct datum)。这是一个估计值。
  • 我计划根据这篇文章中的一些建议来测试性能。我会用结果更新票证
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-11-27
  • 2020-01-13
  • 1970-01-01
  • 2010-11-22
  • 1970-01-01
  • 1970-01-01
  • 2015-04-18
相关资源
最近更新 更多