【问题标题】:Storing a large number of geolocation records in cached ArrayList or always query them from MongoDB?将大量地理定位记录存储在缓存的 ArrayList 中还是总是从 MongoDB 中查询它们?
【发布时间】:2024-01-20 08:46:01
【问题描述】:

我正在开发一个地理定位应用程序。这个应用程序在正确索引的 MongoDB 中保存了大约 500K 记录。每行都有自己的纬度和经度记录值。因此,客户端必须从这 500k 行中恢复 200 个最近的点。我担心性能。起初,我想将所有记录(纬度/经度信息)保存在缓存管理器或内存数据库中。之后,可以将给定的点(纬度/经度)与缓存中的那些值进行比较。这一刻,我的疑惑产生了。

最好将所有这些记录存储在缓存管理器中的 ArrayList 中,然后将记录的地理位置与 ArrayList 中的地理位置进行比较以计算距离?

通过这种方法,我可以防止 MongoDB 中的大量查询,另一方面,通过在 ArrayList 中保留大约 500K 记录(地理位置)然后获取该列表以检索最近的 200 个,这可能是错误的。如果没有错,至少我认为这是性能损失。

我该如何处理这个问题?

提前致谢。

【问题讨论】:

  • 每条记录有多大?持有几百兆字节的排序地图将/应该是微不足道的。
  • 每条记录有2个字符串和1个UUID(经度、纬度、UUID)。
  • 是的,在内存中存储一​​个非常大的列表是完全可行的,只要您知道自己正在这样做。计算预期大小以查看它有多大。请记住,在大多数情况下,JVM 启动时的可用内存并不多。您需要使用 Xms 和 Xmx 命令行参数将其指定为更大。在将所有内容添加到列表之前,您可能需要使用Runtime.getRuntime().freeMemory() 检查可用内存以确保。确保用户知道有内存要求。
  • ArrayList 没有针对搜索进行优化。尝试使用 HashMap 进行精确搜索或使用 TreeMap 进行范围搜索。

标签: java mongodb caching arraylist geolocation


【解决方案1】:

将数据保存在内存中可能会提高性能。但是,当您在 ArrayList 中有 500k 条记录并且想要搜索最接近给定点的 200 条记录时,这意味着必须针对每个请求检查 500k 条记录中的每一条记录。这需要一段时间。可能比 MongoDB 花费的时间要长得多。

但是您可以通过 MongoDB 对其地理索引执行相同的操作来提高性能:使用针对搜索优化的更智能的数据结构。例如,R-Tree。在平衡良好的 R-Tree 中,搜索给定区域中的所有记录是一个运行时复杂度为 log n 而不是数组列表的 n 的操作。对于 50 万个条目,这将是几个数量级的改进。

【讨论】:

  • 感谢您的回复。我正在考虑将所有 500k 记录存储在 R-Tree 结构中,然后执行搜索。 500k 条记录需要大约 20 Gb 的内存。我对吗?每条记录是一个具有三个属性(2 个字符串和 1 个 UUID)的对象。
  • @blackjack 取决于字符串的大小。字符串需要每个 ASCII 字符一个字节(对于 unicode 字符更多)加上一些字节用于元信息。但请注意,Java 会自动进行字符串池,因此当您有重复项时,它们不会占用双倍内存。当我们假设每个对象 1kByte 时,这将是 500MB 的内存。
最近更新 更多