【问题标题】:Caching huge data in Process memory在进程内存中缓存大量数据
【发布时间】:2011-07-13 05:45:32
【问题描述】:

我在金融行业工作。我们希望推出数据库命中以进行数据处理。这是非常昂贵的。所以我们计划采用按需缓存逻辑。 [运行时插入和运行时查找]

是否有人为超过 1000 万条记录实施缓存逻辑?每条记录大约 160 - 200 字节。

我用不同的方法面临以下缺点。

  1. 无法使用 stl std::map 来实现密钥库缓存注册表。 在 200000 条记录之后插入和查找非常慢。
  2. 共享内存或内存映射文件是缓存数据的一种开销, 因为这些数据不会跨进程共享
  3. 可以使用 sqlite3 内存和平面文件应用程序数据库 值得。但在 2-3 百万条记录之后,它的查找速度也很慢。
  4. 进程内存可能对其自身的内核内存消耗有一些限制。我的 假设是 32 位机器上 2 gig 和 64 位机器上 4 gig。

如果您遇到此问题并通过任何方式解决,请给我一些建议。

谢谢

【问题讨论】:

  • 数据库索引通常通过 BTrees 实现,而不是 std::map(R&B 二叉树)。 BTrees 对于你所说的尺度更有效。
  • 您可以在进程之间使用共享内存和内存映射文件。至少在linux上。您使用的是什么操作系统?
  • 这是一个键值对存储还是更复杂的东西?
  • std::unordered_map 怎么样?如果您的密钥可以很好地散列,则预期的查找时间为 O(1)。
  • @YI_H ....我们正在使用solaris平台。它只是一个键值存储。只是为了存储和检索数据。从存储中检索数据后,我们会进行复杂的计算。

标签: c++


【解决方案1】:

如果你的缓存是一个简单的键值存储,你不应该使用std::map,它有O(log n) 查找,而是std::unordered_map ,它具有 O(1) 查找。如果你需要排序,你应该只使用std::map

听起来你追求的是性能,所以你可能想看看Boost Intrusive。您可以轻松组合unordered_maplist 来创建高效的LRU。

【讨论】:

    【解决方案2】:

    将所有内容读入内存并为密钥访问创建 R&B 树。

    http://www.mit.edu/~emin/source_code/cpp_trees/index.html

    在最近的一个项目中,我们有大约 10s M 记录的数据库,并且正在使用这种策略。

    您的数据权重为 2GB,来自您的帖子。有了开销,它会说双倍。任何 64 位架构都没有问题。

    【讨论】:

    • @Daniel.... std::map 在内部仅使用红黑树。数据也无法立即获得。缓存随着时间呈指数增长。早上它可能没有记录,但在一天结束时,它可能有 10 条记录。
    • 读取和插入需要什么时间?另外,您需要某种迭代器吗?
    • 还要考虑这一点:插入时间并不重要,因为它会被吃掉,因为数据将来自“外部”,所以无论如何获取都会很慢。所以你需要专注于阅读。我相信你 std::map 使用 RB 树,但我知道我们的实现在几微秒内从我们的数据结构中返回了 1000 条记录。
    【解决方案3】:

    我最近更改了我们产品(3D 医疗卷查看器)的内存分配,以使用良好的旧内存映射文件。

    优点是:

    • 如果我愿意,我可以分配所有物理 RAM(我的 32 位应用有时需要在 64 位机器上超过 4 gig)
    • 如果您只映射部分,则您的地址空间在很大程度上可供您的应用程序使用,从而提高了可靠性。
    • 如果您的内存不足,事情只会变慢,不会崩溃。

    就我而言,它只是数据(主要是只读的)。如果你有一个更复杂的数据结构,这将比使用“普通”对象做更多的工作。

    您实际上可以跨进程共享这些(如果它们由真实文件支持)。这可能表现不同,我没有这方面的经验。

    【讨论】:

      猜你喜欢
      • 2015-01-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-06-17
      • 1970-01-01
      • 1970-01-01
      • 2015-10-30
      • 2017-10-27
      相关资源
      最近更新 更多