相较于MySQL和Oracle等主流关系型数据库,TDengine的内存估算要复杂的多。
从使用分类上来讲,TDengine的内存使用分为三部分:
- 数据写入内存
- WAL写入内存
- 查询内存
1、数据写入内存
这部分是最好计算的,由数据库参数控制
blocks ##每个Vnode占用的内存块个数,建议为3的倍数,默认为6。
cache ##单个内存块大小,默认16MB,不建议修改。
写入内存=vnode_num x blocks x cache
示例:
vnode数量为8,其他参数为默认,则写入内存需要768MB【8x6x16】
vnode 数量估算
vnode的数量受多个参数影响:
minTablesPerVnode ##每个vnode最少表数量
maxTablesPerVnode ##每个vnode最多表数量
tableIncStepPerVnode ##创建每个表步长
maxVgroupsPerDb ##每个数据库最多vnode数量,默认为64,如果不设置,则为逻辑CPU个数
示例:
服务器逻辑cpu数量为8个
设置参数如下
minTablesPerVnode 100
maxTablesPerVnode 1000000
tableIncStepPerVnode 100
如果创建1000 张表,则创建步骤如下:
a.先创建8个vnode,每个vnode100张表;
b.从第一个vnode开始,每个表创建100张表,直到创建完成。
则最后的结果如下
vnode id | 表数量 |
---|---|
1 | 200 |
2 | 200 |
3 | 100 |
4 | 100 |
5 | 100 |
6 | 100 |
7 | 100 |
8 | 100 |
2、WAL写入内存
WAL使用操作系统缓存,因此WAL能够使用的内存大小受操作系统参数控制。
vm.dirty_background_ratio
vm.dirty_ratio
详情见 一张图解释dirty_background_ratio与dirty_ratio
以上说明了WAL能够使用的内存大小,那么应该预留多少内存给WAL呢?
我在 TDengine写入性能估算中提到过写入瓶颈。如果数据传入服务器的速度小于磁盘的写入速度,那么可以不考虑缓存问题。
但在大多数场景中,数据并不是匀速写入的,而是集中在某个时刻集中写入,此时的数据量可能会超过磁盘写入速度。
示例:
高峰时,数据量在200MB/s,持续时间为5分钟。而磁盘的写入速度为100MB/s。
那么为了保证写入不被阻塞,需要操作系统的缓存大于29GB【(200-100)x(5x60)/1024】
此时至少需要操作系统可用内存大于96GB 【29/vm.dirty_ratio (vm.dirty_ratio 默认为 30%)】
3、查询内存
提到查询内存,不得不说TDengine没有对查询内存进行限制,如果前期没有预留足够的内存,进程很容易被OOM。进程是如何被OOM杀掉的
如果不清楚查询语句的具体内容和频率,查询内存的估算非常非常困难。
如果已知查询语句和频率,那么查询内存的大小就是查询出数据的大小。