25.4.3.13 数据节点内存管理
数据节点的所有内存分配都在节点启动时进行。这样可以确保数据节点可以稳定运行,不使用交换内存,从而使NDB
适用于低延迟(实时)应用程序。数据节点启动时分配的内存类型包括:
-
数据内存
-
共享全局内存
-
redo日志缓冲区
-
作业缓冲区
-
发送缓冲区
-
磁盘数据记录的页面缓存
-
架构事务内存
-
事务内存
-
undo日志缓冲区
-
查询内存
-
块对象
-
架构内存
-
块数据结构
-
长信号内存
-
共享内存通信缓冲区
NDB内存管理器,负责管理大多数数据节点内存,处理以下内存资源:
-
数据内存(
DataMemory
) -
redo日志缓冲区(
RedoBuffer
) -
作业缓冲区
-
发送缓冲区(
SendBufferMemory
,TotalSendBufferMemory
,ExtraSendBufferMemory
) -
磁盘数据记录页缓存(
DiskPageBufferMemory
,DiskPageBufferEntries
) -
事务内存(
TransactionMemory
) -
查询内存
-
磁盘访问记录
-
文件缓冲区
每个资源都设置了保留内存区域和最大内存区域。保留内存区域只能由该资源使用,不能与其他资源共享;给定的资源永远不能分配超过其允许的最大内存。没有最大内存的资源可以扩展以使用所有共享内存管理器中的内存。
这些资源的全局共享内存大小由SharedGlobalMemory
配置参数(默认值:128 MB)控制。
数据内存总是保留的,永远不会从共享内存中获取任何内存。它可以使用DataMemory
配置参数来控制,最大值为16384 GB。DataMemory
是记录存储的位置,包括哈希索引(约15个字节每行)、有序索引(10-12个字节每行每个索引)和行头(16-32个字节每行)。
redo日志缓冲也只使用保留内存;这可以通过RedoBuffer
配置参数来控制,该参数设置每个LDM线程的redo日志缓冲大小。这意味着实际使用的内存量是该参数值乘以数据节点中的LDM线程数量。
作业缓冲只使用保留内存;该内存的大小由NDB
根据各种线程类型的数量进行计算。
发送缓冲有保留部分,但也可以分配共享全局内存的另外25%。发送缓冲保留大小在两个步骤中进行计算: (请注意,翻译后的HTML结构与原始结构基本保持一致)
-
使用数据节点的
TotalSendBufferMemory
配置参数(无默认值)或所有个体连接到数据节点的发送缓冲区总和。数据节点连接到所有其他数据节点、所有 API 节点和所有管理节点。这意味着,在具有 2 个数据节点、2 个管理节点和 10 个 API 节点的集群中,每个数据节点都有 13 个节点连接。由于数据节点连接的默认值为SendBufferMemory
为 2 MByte,这将总共占用 26 MB。 -
为了获得发送缓冲区的总保留大小,需要将
ExtraSendBufferMemory
配置参数的值,如果存在(默认值 0),添加到前一步骤中获得的值。
换言之,如果已经设置了TotalSendBufferMemory
,则发送缓冲区大小为TotalSendBufferMemory + ExtraSendBufferMemory
;否则,发送缓冲区的大小等于([
。number of node connections
] * SendBufferMemory) + ExtraSendBufferMemory
磁盘数据记录的页面缓存使用的是保留资源,只有这个资源的大小由DiskPageBufferMemory
配置参数控制(默认64MB)。磁盘页面条目(32KB)也分配内存,条目的数量由DiskPageBufferEntries
配置参数控制(默认10)。
事务内存有一个保留部分,这个部分可以由NDB
计算,也可以使用TransactionMemory
配置参数设置事务内存;事务内存也可以使用共享全局内存的无限资源。事务内存用于处理所有操作资源,包括事务、扫描、锁定、扫描缓冲区和触发器操作。此外,它还将更新的表行保存在内存中,直到下一个提交写入数据内存。
资源从公共事务内存资源中分配,也可以使用共享全局内存中的资源。这个资源的大小可以使用单个TransactionMemory
配置参数控制。
可以使用InitialLogFileGroup
配置参数设置undo日志缓冲区的保留内存。如果在CREATE LOGFILE GROUP
SQL语句中创建了undo日志缓冲区,内存将来自事务内存。
Disk Data资源的元数据相关资源也没有保留部分,只使用共享全局内存。共享全局内存因此被send缓冲区、事务内存和Disk Data元数据共享。
如果TransactionMemory
未设置,它将根据以下参数计算:
当TransactionMemory
被设置为明确值时,以下配置参数将不用于计算内存大小。此外,参数MaxNoOfConcurrentIndexOperations
、MaxNoOfFiredTriggers
、MaxNoOfLocalOperations
和MaxNoOfLocalScans
与TransactionMemory
不兼容,不能同时设置它们;如果TransactionMemory
被设置,并且在config.ini
配置文件中也设置了这四个参数之一,则管理服务器无法启动。
参数MaxNoOfConcurrentIndexOperations
、MaxNoOfFiredTriggers
、MaxNoOfLocalOperations
和MaxNoOfLocalScans
都已弃用,您应该预期它们将在未来的MySQL NDB集群版本中被删除。
事务内存资源包含大量的内存池。每个内存池表示一个对象类型,并包含一组对象;每个池包括在启动时分配给池的保留部分;这部分保留内存永远不会返回到共享全局内存中。保留记录使用单级数据结构进行快速检索,这意味着每个池中的记录数应该被保留。每个池中的保留记录数量对性能和保留内存分配有影响,但通常只在某些非常复杂的用例中需要设置保留大小。
可以通过以下配置参数来控制保留部分的大小:
对于上述参数中未设置的任何一个,保留设置将被计算为对应最大设置的25%。例如,如果未设置,则ReservedConcurrentIndexOperations
将被计算为MaxNoOfConcurrentIndexOperations
的25%,ReservedLocalScans
将被计算为MaxNoOfLocalScans
的25%。
如果ReservedTransactionBufferMemory
未设置,则将被计算为TransactionBufferMemory
的25%。
每个数据节点都有保留记录数;这些记录将被分配给每个节点上的线程(LDM和TC线程)。在大多数情况下,设置TransactionMemory
单独使用,并允许池中的记录数量由其值控制。
MaxNoOfConcurrentScans
限制了每个TC线程中可以活动的并发扫描数量。这对防止集群过载非常重要。
MaxNoOfConcurrentOperations
限制了在更新事务中可以同时活动的操作数量。 (简单读取不受这个参数影响。) 这个数字需要被限制,因为它是为了预分配节点故障处理所需的内存,并且在与节点故障竞争时,必须为每个TC线程预留资源。必须确保所有节点上的MaxNoOfConcurrentOperations
设置相同(可以通过将其设置为一次值,在config.ini
全局配置文件的[ndbd default]
部分)。虽然可以使用滚动重启(见第25.6.5节,“NDB集群的滚动重启”)增加其值,但在这种情况下减少它是不可靠的,因为可能会在滚动重启期间出现节点故障。
可以通过MaxDMLOperationsPerTransaction
参数限制NDB集群中的单个事务大小。如果没有设置这个参数,那么一个事务的大小将被MaxNoOfConcurrentOperations
限制,因为这个参数限制了每个TC线程的总共并发操作数量。
Schema内存大小由以下配置参数集控制:
节点数和LDM线程数对架构内存的大小也产生了很大的影响,因为每个表和每个分区(及其副本)都需要在架构内存中被表示。
此外,在启动时还会分配一些其他记录。这些记录相对较小。每个线程中的每个块包含块对象,这些对象使用的内存大小也通常较小,相比于其他数据节点内存结构。