采用资源队列管理内存和资源
采用资源队列管理内存和资源
避免内存错误,管理Greenplum数据库资源。
Greenplum数据库集群中,内存管理对性能有显著的影响。默认设置适合于大部分环境。不要更改默认设置,除非 理解系统上的内存特点和使用方法。
解决内存不足错误
Out of memory (seg27 host.example.com pid=47093) VM Protect failed to allocate 4096 bytes, 0 MB available
- 集群上可用的系统内存(RAM)不足
- 内存参数配置不当
- segment级别有数据倾斜
- 查询级别有操作性倾斜
下面是内存不足情况的可用解决方案:
- 调优查询以要求较少的内存
- 使用资源队列降低查询并发
- 在数据库级别上验证gp_vmem_protect_limit配置参数。最大安全设置的计算请见 为Greenplum数据库配置内存。
- 在资源队列上设置内存限额以限制资源队列中执行的查询所使用的内存
- 使用会话设置来降低特定查询使用的statement_mem
- 在数据库级别降低statement_mem
- 降低Greenplum集群中每台主机上的Segment数量。该操作要求重新出实话集群并重新加载数据。
- 如果可能,增加主机上的内存。(要求增加额外的硬件。)
向集群中增加segment主机本身不会缓解内存不足问题。每个查询使用的内存由statement_mem 参数决定,并且在查询被调用时会设置它。不过,如果增加更多的主机允许每台主机上的segment数量降低,那么 gp_vmem_protect_limit中分配的内存量就可以上升。
低内存查询
SET statement_mem='2MB';
为Greenplum数据库配置内存
如果合理地管理内存,大部分内存不足的情况是可以避免的。
一直增加系统内存是不可能的,客户可以通过配置资源组来管理可预期的工作负载,这样能够避免 内存溢出的情况发生。
当您配置资源组内存时,提前考虑出现segment实例或segment主机宕机时,镜像segment变成 主segment对系统内存的占用。
下面是推荐的操作系统以及Greenplum数据库内存设置:
- 不要启用操作系统大页配置
-
vm.overcommit_memory
该Linux内核参数在/etc/sysctl.conf文件中设置,用来指定操作系统 分配给系统进程使用多少内存的方法。vm.overcommit_memory在 Greenplum数据库所在的机器上必须设置为2。
-
vm.overcommit_ratio
该Linux内核参数在/etc/sysctl.conf文件中设置,用来执行应用进程 可以使用的内存百分比;剩余的内存留给操作系统。操作系统默认值(Red Hat上默认是50)。
把vm.overcommit_ratio设置得太高可能会导致没有为操作系统保留足够的内存, 进而导致segment主机故障或者数据库故障。将这个值设置得太低会降低并发量和通过降低Greenplum 数据库可用内存量能运行的查询复杂度。当增加这一设置时,有必要记住总是为操作系统活动保留一些内存。
有关计算vm.overcommit_ratio值的步骤,请见资源队列的segment内存配置。
-
gp_vmem_protect_limit
使用gp_vmem_protect_limit设置实例能够为在每个segment数据库中完成的所有 工作分配的最大内存。不要把这个值设置得高于系统上的物理RAM。如果gp_vmem_protect_limit 太高,有可能耗尽系统上的内存并且正常的操作可能会失败,导致segment故障。如果gp_vmem_protect_limit 被设置为一个安全的较低值,系统上真正的内存耗尽就能避免。查询可能会因为达到限制而失败,但是系统崩溃和 segment故障可以避免,这也是我们想要的行为。
有关计算gp_vmem_protect_limit安全值的步骤,请见 资源队列的segment内存配置。
-
runaway_detector_activation_percent
失控查询终止在Greenplum数据库4.3.4中被引入,它能防止内存不足的问题。 runaway_detector_activation_percent系统参数控制触发查询终止的 gp_vmem_protect_limit内存利用率。默认它被设置为90%。如果一个segment 利用的gp_vmem_protect_limit memory内存的百分比超过指定的值,Greenplum 数据库会基于内存使用终止查询,从消耗内存量最大的查询开始。查询会被挨个终止直至 gp_vmem_protect_limit的利用率重新低于指定的百分比。
-
statement_mem
使用statement_mem分配每个segment数据库中一个查询所使用的内存。如果要求额外的内存, 将会溢出到磁盘。按照下面的方式为statement_mem设置最优值:
(vmprotect * .9) / max_expected_concurrent_queries
statement_mem的默认值是125MB。例如,一个使用默认statement_mem 值运行在Dell EMC DCA V2系统上的查询将在每台segment服务器上使用1GB内存(8个Segment ⨉ 125MB)。 为要求额外内存完成的特定查询在会话级别上设置statement_mem。在并发性低的集群上这种 设置可以很好地管理查询内存。对于高并发的集群还是要使用资源队列来控制在系统上运行什么以及运行多少。
-
gp_workfile_limit_files_per_query
设置gp_workfile_limit_files_per_query以限制每个查询允许使用的临时溢出文件 (工作文件)的最大数量。当查询要求的内存比它能分配的更多时,它将创建溢出文件。当上述限制被超过时,查询 会被中止。默认值为零,允许无限多的溢出文件并且可能会填满文件系统。
-
gp_workfile_compression
如果有很多溢出文件,则设置gp_workfile_compression来压缩这些溢出文件。 压缩溢出文件可能有助于避免IO操作导致磁盘子系统过载。
配置资源队列
Greenplum数据库的资源队列为管理集群负载提供了一种强有力的机制。队列可以被用来限制活动查询的数量以及 队列中查询可使用的内存量。当查询被提交给Greenplum数据库时,它会被加入一个资源队列,资源队列会决定该查询 是否应该被接受并且何时有资源可用来执行它。
-
为所有用户分配预定义好的资源队列。
每个登录用户(角色)都被关联到单个资源队列,任何该用户提交的查询都由关联的资源队列处理。如果没有为 用户的查询明确地分派一个队列,则会由默认队列pg_default处理。
-
不要用gpadmin角色或者其他超级用户角色运行查询。
超级用户会被从资源队列限制中排除,因此超级用户的查询运行不会考虑在其所属队列上设置的限制。
-
使用ACTIVE_STATEMENTS资源队列参数来限制特定队列成员能够并发运行的活动查询数量。
-
使用MEMORY_LIMIT参数控制通过队列运行的查询可以利用的内存总量。通过组合 ACTIVE_STATEMENTS和MEMORY_LIMIT属性,管理员可以完全控制 从一个给定资源队列发出的活动。
分配按如下方式进行:假定资源队列sample_queue的ACTIVE_STATEMENTS 被设置为10,而MEMORY_LIMIT被设置为2000MB。这限制该队列在每个segment上使用大约2GB内存。 对于每台服务器有8个segment的集群,sample_queue在每台服务器上的总用量是16GB (2GB * 8 Segment/服务器)。如果segment服务器有64GB内存,系统中可以有不超过四个这种资源队列, 再多就会内存不足(4队列 * 16GB/队列)。
注意通过使用STATEMENT_MEM,运行在队列中的个体查询能够分配超过其内存“份额”的内存, 从而降低队列中其他查询可用的内存。
-
资源队列优先级可以被用来排列具有预期结果的负载。带有MAX优先权的队列会扼杀所有 其他队列中的活动,直至MAX队列完成所有查询的运行。
-
根据负载和现状动态修改资源队列以匹配队列的实际需求。用户可以把这些更改写成脚本并且增加 crontab项来执行这些脚本。
-
使用gptoolkit查看资源队列使用以及理解队列如何工作。