My Postgres在负载(500MB)下达到最大允许内存并运行14个进程。一旦加载结束,Postgres仍然保留分配的内存并运行14个进程。由于我在同一台机器上运行Apache和Tomcat,我想Postgresql释放分配的内存。有可能吗?
谢谢!
答案 0 :(得分:5)
基本上,您需要以两种方式查看系统内存,尤其是Postgres内存。
第一个是运行应用程序所需的内存。这实际上是所有应用程序在生产中运行时的静态内存负载。如果在所需负载下没有足够的内存,则说明内存不足。现代系统可以在“危机”时使用交换,但这就是全部。简单地说,如果你使用交换,你会遇到内存危机,你应该希望它很快就会消失。
一旦你拥有应用程序所需的基本内存,所有剩余的系统内存基本上都专用于磁盘缓存。
使用托管Postgres的系统,您有两种磁盘缓存。你有内核文件系统缓存,并且你有Postgres内部缓存。
Postgres内部缓存不会被释放。这不是它的工作原理。你在配置中告诉它,它可以使用XXX量的RAM用于它的目的,它会保留它。在这种状态下,Postgres并不关心系统中还有什么。
如果缓存是内核缓存,并且文件系统活动突然出现不是Postgres,那么内核将缓存最近的页面并刷新旧页面。内核缓存将看到整个系统,而Postgres只看到DB活动。
所以
在Postgres世界观中,内核缓存正在与它的缓冲区缓存竞争。考虑这种情况。 Postgres要求一块磁盘。内核抓取阻塞并缓存它。与此同时,Postgres抓取从内核中取出该块,并缓存它。现在,该块被冗余地缓存。如果内核更好地使用该缓存内存块,它会将其刷新到Postgres块中,然后加载新块。与此同时,Postgres将在其内部缓存中保留该块。
如果你有一台专门的Postgres机器,没有什么理由可以有很多内核缓存。由于所有磁盘I / O都是Postgres I / O,因此内核缓存比Postgres缓存冗余且效率低。当Postgres缓存一个块时,它必须封送字节,更新它的内部结构以及它所做的任何其他事情。缓存后,它不再需要执行任何操作。因此,以这种方式,Postgres缓存的块比内核缓存的块更有效,因为将块从内核缓存移动到Postgres有一些费用。
但是,如果你有一个混合使用的机器,那么内核和Postges缓存必须要解决它。如果你有一个足够小的数据库,可以将大部分日常操作数据放入RAM中,那么你应该有足够的缓冲空间来处理Postgres中的内存,因此大部分操作都来自内存。以这种方式,Postgres将加载其正常的“忙”页面一次,并缓存它们,然后再也不要向内核询问它们。完成后,内核可以使用其缓冲区缓存来处理所有辅助的其他系统请求。
在另一个极端,你给Postgres很少的专用缓冲区缓存,并且它只依赖于内核缓存。通过这种方式,每次来自内核缓存的每个块都要贵一些,但它每次都比从磁盘读取它要便宜得多。通过这种方式,内核可以判断哪些进程更值得缓存注意。
在实践中,为Postgres决定一个良好的操作稳定状态并将其留在那里。任何活动高峰(比如报表或其他任何内容的大表扫描)都会被内核缓存减轻,当峰值结束时,内核可以恢复该内存用于其他用途。
所以,底线,Postgres不会回馈任何记忆。只要你付出尽可能多的奉献精神。
答案 1 :(得分:2)
除了一些常见的进程外,PostgreSQL每个连接都会运行进程,因此您可能应该查看应用程序(或连接池)设置 - 如果连接在未使用一段时间后被释放。
但我不认为这会在内存环境中帮助你很多因为PG分配内存的主要部分是共享缓冲区而且这部分内存永远不会被释放。
答案 2 :(得分:0)
所以一般来说,你希望postgresql的缓存能够快速预热并留在内存中。
话虽这么说,你当然也需要内存来运行你的其他应用程序。您可以通过减少连接池上的最大连接数来减少每个请求的内存消耗。这反过来将限制postgres启动以处理请求并存储基于临时数据的会话的进程数。
您当然可以调低较小缓存的共享缓冲区。
另一种方法是减少允许Apache和tomcat处理的并发请求数。如果您的响应时间很快,那么您可以通过较少的并发请求获得更高的吞吐量,并在apache中排队请求。然后,您可以限制整个堆栈中的内存消耗,并通过在负载上设置上限,您将保持请求处理时间相对恒定。
答案 3 :(得分:0)
在理想的设置中,您的数据库永远不会位于Web服务器和应用程序服务器上。就此而言,这些系统中的每一个都可能位于自己的服务器上。