Go:处理过多内存应用的最佳方法? Mmap,内存还是缓存?

时间:2015-04-06 08:35:09

标签: caching memory-management go mmap

我有一个Go应用程序需要大约600GB的内存。将运行的机器有128GB的RAM。我正在努力决定如何最好地处理这个问题。

选项包括:

  1. 只需将所有内容加载到内存中(假装我拥有600GB RAM)并让操作系统将不经常访问的内存部分分页到虚拟内存中。我喜欢这个想法,因为我不必在代码中做任何特殊的事情,操作系统只会处理所有事情。但是,我不确定这是个好主意。

  2. 将数据存储在磁盘上并使用mmap(内存映射文件),我猜这与上面的类似,但需要更多编码。此外,它似乎意味着数据必须存储为[]byte,然后每次我需要使用它时进行解析,而不是已经处于实际计算所需的任何类型。

    < / LI>
  3. 构建一个缓存系统,其中数据保存在HDD上,然后在需要时加载它,最常访问的数据保存在内存中,并且每当超出内存限制时,最不频繁访问的数据被清除

  4. 这些有哪些优点和缺点?如果可能的话,我宁愿选择(1),因为它的简单性......这有什么不妥吗?

1 个答案:

答案 0 :(得分:1)

这一切都取决于数据访问的性质。这些600GB的访问是否均匀分布?如果情况并非如此,那么将内容缓存在内存中并将其余部分保留在内存中的解决方案可能已足够,因为您有足够的RAM来缓存超过20%的数据。将所有内容保存在虚拟内存空间中可能会带来令人惊讶的缺点,例如需要大量的交换分区。

要将数据缓存在磁盘上,您可以使用Dave建议的数据库引擎,因为他们通常可以很好地缓存最常访问的内容。您还可以使用memcached,一个库和客户端来缓存内存中的内容。

最重要的是,在不知道确切的使用模式的情况下优化性能很难。幸运的是,有了Go,你不必猜测。你可以测试和测量。

您可以定义类似于

的界面
type Index interface{
    Lookup(query string) Result
}

然后尝试所有解决方案,从最简单的方法开始。

type inMemoryIndex struct {...}

func (*inMemoryIndex) Lookup(query string) Result {...}

type memcachedIndex struct {...}

type dbIndex struct {...}

然后,您可以使用Go's builtin benchmarking tools对应用程序进行基准测试,看看它是否符合您的标准。您甚至可以使用真实数据和模拟用户查询在该计算机上进行基准测试。

你认为mmap需要更多编码是正确的,所以我会保存它,直到我尝试了所有其他选项。