【问题标题】:Suggestions for large nested map in ScalaScala中大型嵌套地图的建议
【发布时间】:2018-11-07 11:24:45
【问题描述】:

我需要根据两个标准聚合大量记录。举个例子,记录说一个人每天在哪个城市。

我需要在硬件非常有限且没有云的情况下进行此聚合。我不想为此将原始数据上传到数据库,原始数据确实很大(想想数十亿条记录)

我最初的想法是用一个人的ID来构建一个地图,它会是几百万,价值是一个地图,其中关键是城市,价值是他们在那个城市度过的天数。这是一个包含数百万个键的映射,每个值具有映射十分之几(少于 100 个)条目。

我想运行一些基准测试,并且我需要一些帮助来列出我可以使用的映射类型:可变/不可变、哈希/树...我还需要平衡性能和内存使用量。 任何帮助将不胜感激!

【问题讨论】:

  • 听起来您的问题是每次启动应用程序时都会摄取数十亿条记录,而不是存储数据的方式。
  • 正确,原始记录在聚合后被丢弃。在“真实”系统上会有所不同,但在这里我需要处理非常有限的硬件。
  • 我想我会分享我的发现,截至 2018 年 11 月,scala.collection.mutable.HashMap[K, V] 对于单线程来说已经足够好了,对于多线程,我们正在检查 import java .util.concurrent.ConcurrentHashMap(作为 Scala)。
  • 最后的编辑,对于我的问题,我发现使用不可变映射和嵌套映射的尾递归函数的工作速度基本上与使用可变数据结构的迭代方法一样快。我很惊喜

标签: scala dictionary hashmap mutability


【解决方案1】:

如果性能很关键,您应该考虑在聚合过程中使用可变数据结构,因为 Scala 中的不变性,尤其是在大型记录的情况下,可能会导致性能显着下降。您可以查看这篇文章,也有针对不同集合的基准: https://medium.com/@hussachai/scalas-immutable-collections-can-be-slow-as-a-snail-da6fc24bc688

此外,您应该考虑使用并行集合来加速记录处理: https://alvinalexander.com/scala/how-to-use-parallel-collections-in-scala-performance

但是,内存使用可能是问题所在。您可能希望实现流式解决方案或使用例如 Apache Spark,而不是一次将所有数据保存在内存中,如果数据超过内存限制,您可以将数据保存在磁盘上

【讨论】:

  • 我已经准备了第一个使用可变结构的实现,我对它的速度印象深刻。现在内存是限制,你能给我一些关于流式方法的建议吗?
  • 我更新了我的答案,尝试使用 Apache Spark - 它针对处理大量数据进行了优化,并且能够在超过内存限制时自动将数据缓存在磁盘上。此外,它针对并行执行进行了优化,因此即使在具有多核处理器的单个节点上,它也能有效利用所有内核
  • 不幸的是,在这种特殊情况下,Spark 不是我们的选择。
猜你喜欢
  • 2015-02-11
  • 2015-04-18
  • 1970-01-01
  • 1970-01-01
  • 2018-03-15
  • 1970-01-01
  • 2018-02-01
  • 2016-03-27
  • 1970-01-01
相关资源
最近更新 更多