YugabyteDB内存调整和优化
Valerie Parham-Thompson [hudson译]
2022年8月1日
想知道如何为YSQL优化YugabyteDB内存调优吗?请继续阅读!
像大多数数据库软件一样,YugabyteDB提供了缺省的内存配置。应该针对特定用例和工作负载评估这些默认值。
内存利用率的三个主要方面是:
- tserver进程
- Master进程
- postgres进程
并非群集中的所有节点都有Master进程。
本博客概述了这些主要方面中的每一个,并提供了使用YSQL工作负载优化内存的最佳实践和注意事项。
默认配置
默认情况下,tserver 服务器进程配置为最多使用85%的可用RAM。
该进程中有几个子进程和一些结构。这些包括块缓存、各种读取缓冲区、tablet的内存表和日志(预写日志或WAL)缓存。
默认情况下,Master进程配置为在类似子进程中使用10%的RAM。
这为YSQL和操作系统留下了5-15%的可用空间。
调整Tserver内存利用率
预调整大小
如果您正在为universe(等同一个YugabyteDB集群)预调整内存设置大小以测试ysql工作负载,则可以将tserver的 default_memory_limit_to_ram_ratio 更改为.5(占可用ram总量的50%)。
这个经验法则允许postgres进程使用更多可用RAM,同时使tserver进程在生产中观察到的RAM平均比率保持不变。
但是,请查看内存细分(见下文)root部分中的服务器内存利用率和日志,以确保50%足够。
运行universe的内存分解
如果你有一个正在运行的universe,请检查每个服务器的内存细分,以找到内存当前和最大利用率的,并进行正确调整。
可以在UI界面中每个服务器Utilities下找到内存分解明细。
内存组件包括:
- root(所有tserver进程允许的总内存)
- BlockBasedTable(块缓存)
- 读取缓冲区
- Tablets/memtables
- 日志缓存(WAL)
注意:您可能会发现,tserver进程没有使用全部内存,其他进程(如postgres)可能会使用多余的内存。为了说明这一点,配置的内存比率并没有预先分配给服务器进程。但是,最好调整配置,以避免内存竞争导致的内存不足事件。
Root
如果希望将允许的服务器内存设置为特定值,可以设置memory_limit_hard_bytes,这将覆盖default_memory_limit_to_ram_ratio。
为了避免达到这两个限制中的任何一个,当内存利用率达到配置的memory_limit_soft_percentage(默认为允许的服务器内存的85%)时,将对新请求施加反压力,以允许完成运行的请求。
块缓存
块缓存是Tserver 进程内存的最大用户,在内存细分中显示为BlockBasedTable。这该内存用于存储热/温数据,以优化读取。配置(db_block_cache_size_percentage)默认为50%,并在服务器上运行的所有RocksDB实例之间共享。
如果需要特定值,可以改为设置db_block_cache_size_bytes。如果通过“缓存命中与未命中”图观察到块缓存未命中率很高,请考虑增加块缓存设置。
Memtables
每个tablet都有一个内存存储(memstore),用于在刷新到磁盘上的SST文件之前缓冲写操作。当memstore达到配置的memstore_size_mb(默认128M)后,维护线程将刷新它。
如果memstore正在被主动写入,并且/或者维护线程尚未到达,则memstore可能会增长到大于此配置值。对于繁重的写入工作负载,请考虑将其调高,但要注意tablet的数量,因为这是按每个tablet调整的。另外,也要考虑更大的刷新与频繁的刷新对磁盘i/o容量的影响。
memstore使用的内存总量通过global_memstore_size_percentage(默认为tserver内存的10%)控制,硬限制为global_memsstore_size_mb_max(默认值 2g)。对于繁重的写工作负载,请考虑将其调得更高。
日志缓存
日志缓存(log_cache_size_limit_mb)按每个tablet设置,默认为128M。此缓存存放尚未复制到追随者的共识条目。 总上限通过global_log_cache_size_limit_mb设置(默认1G)。通过观察WAL Stats/Node*图表,如果发现经常达到限制,请考虑将此值调高(并确定节点之间延迟的原因)。
读取缓冲区
各种读缓冲区共享通过read_buffer_memory_limit(默认为tserver内存的5%)分配的内存。正常的读取缓冲区会始终使用。 如果启用了RPC压缩,则使用压缩的读取缓冲区。如果启用了TLS,则使用加密的读取缓冲。
调整Master内存利用率
Master进程的内存配置类似,并且适用类似的调整注释。然而,Master进程没有tserver进程拥有的大量tablet。因此其 default_memory_limit_to_ram_ratio 设置为较低10%。
调整YSQL内存利用率
首先Tserver(和Master)进程调整VM内存大小,因为这些进程对于性能良好的分布式系统至关重要。增加postgres进程的可用内存可能需要提升VM上的RAM大小。 从查询分析开始,确保您的查询得到很好的调整,并明智地使用资源。对于不同工作负载的内存使用情况,也值得考虑以下几点:
- max_connections的默认值为300(每个节点)。即使在空闲时,连接也会占用大约6MB的内存。较大的系统目录(更多的表,因此更多的tablet)也需要更多的内存开销。
- 对于活动连接,编译好的语句和点查询占用的内存更少。
- 聚合查询比点查询占用更多内存,因为work_mem是按每个查询中的排序操作(order by、distinct、merge join)或哈希操作(哈希连接、基于哈希的聚合、节点的结果缓存和基于哈希处理的IN子查询)分配的。 hash_mem_multiplier work_mem仅用于哈希查询,默认值为1,设置后会增加 work_mem,。
- 如果启用了autocommit(默认情况下,除非发出事务性语句,否则它是启用的),那么在将结果返回给客户端之前,结果集将完全在内存中构建。 超过配置的work_mem的查询操作将写入磁盘上的临时文件。 使用的所有临时文件的大小都是通过temp_file_limit配置的,默认情况下不受限制。如果限制此其大小,则查询使用的临时文件高于此设置将失败。 如果不受限制,请考虑通过log_temp_files启用临时文件日志记录,并监视磁盘利用率,以确保不会超过磁盘空间。
总结
通过YugabyteDB的各种可观察性窗口观察内存利用率,并为tserver、master和ysql进程正确调整内存大小,可以确保工作负载的最佳性能,并避免内存不足事件。