南大通用GBase 8a 数据库集群常用优化手段建议方法

GBase 8a数据库集群,提供了多种优化手段,来协助用户提供业务性能。常用优化手段建议方法包括:规避数据库的劣势,选择合适的表分布策略,更高效的加载策略等手段。

1.    列存特性

GBase是纯列存,100个列,在磁盘上是按照100个列,分别保存的,会生成100个数据文件。也就是说,只入库一行,磁盘也要读取100次,追加新数据,写入100次来更新数据。所以查询的列越多,从磁盘读取的越多。而行存是一行数据,连续写到磁盘位置,理论上只需要一次IO请求就可以了,无论多少列。

GBase保存数据最小单位是DC(DataCell),每个DC包含65536行,压缩也是DC级别。最后一个DC有可能是不满的,后续新数据要先补充不满65536行的最后一个DC,再生成新的DC。

查询结果行数越多,如果数据集中在几个DC里,那么一个IO就可以读出65536行,性能会很高。但如果数据分散到多个DC里,那么随着命中DC数的增加,性能接近线性下降。该信息可以从前面的章节:【开启SQL执行跟踪日志】查看到。

2.    复制表和分布表的选择

复制表,是表的数据,在每个节点上,都有完整的一份,会额外占用空间。

分布表,是表的数据,分散保存到不同节点上。

对于判读的,可以先建成分布表,后期根据性能测试结果,看这类表对性能的影响。

2.1.            选择复制表的场景

提示:查询复制表时,集群调度是随机选择1个计算节点执行,尽量平均分配负载

  • 维度表、参数表、公参表

这类表,其内容几乎不会变动。能长时间使用几个月甚至几年。其数据量一般在万以内,最大也不会超过千万。典型的是民族,省份,终端类型,用户套餐分类,上网方式等。

  • 变动极少的基础表

这类表的数据量较大,比如用户基础信息表。每个省可能有几千万到1个亿,全国应用有几十亿行。

这类表信息不是实时更新的,都是每天,每周甚至每月批量更新一次。每次变动的数据量与原有数据量的比例可以忽略。

这类表一般用于被关联的位置(left join 基础表)。一般用于查询其它业务信息时,附带查询的信息。

如果这类表是主表,那么不适合做成复制表,而是分布表。

这类表的使用频率高。各类业务查询都会使用到这个基础表。

  • 数据量极少的频繁访问表

比如一些汇总结果表,一般数据量低于10万,每天变动次数和量都很少,但并发使用率很高。

2.2.            选择分布表的场景

  • 主表,数据量超大的表

比如明细表(detail),事实表(fact),流水表等核心业务表。是入库数据量最大的表,每天几亿到上千亿都有可能。他们占用最大量的磁盘空间,必须采用分布存储方式。

这类数据一般由于空间因素,保存周期是最短的。

  • 数据量中等,访问量一般,保存周期长

每天在几千万到几个亿,但用户量不是很大,性能要求不高,磁盘占用中等。

比如天汇总,月汇总表。每个批次在几千万。

这类数据保存周期较长,几个月到几年都有。

如果使用频率极高,那么建议用复制表,用空间来换时间,否则一般用分布表。

3.    分布表的分布策略

随机分布表:数据没有任何规律的随机分散到所有节点上,数据库尽量按行数平均。

HASH分布表:按照某列的hash值,分散到不同节点上。相同的数据肯定落在一个节点上。当前hash算法为crc32。

3.1.            选择HASH分布的场景

该表有大量的group,join操作。且数据量较大,须多节点并行执行才能满足性能要求。

3.2.            选择合适的HASH列

如果没有合适的HASH列,那么还是采用随机分布表。

  • 数据无明显倾斜

该列数据hash分布后,不会出现节点间的磁盘使用率有极大的差距(比如超过1倍),且会导致长期使用后,部分节点磁盘已经满,而另外一些很空闲。

该测试要尽量在接近真实节点数或分片数下测试。在86版集群,可以在安装时增加分片数量参数 p,常用的是1,来在一个节点创建多个分片。观察数据倾斜情况是否在能接受的范围内。

  • 唯一值多

这个与数据无明显倾斜原理一样。如果该列只有20个不同的值,那么在节点数超过20的环境下,部分节点肯定不会有任何数据。

一般建议用手机号码,IMSI,身份证号等有明显标识作用的列。

  • 被频繁group的列

经常作为group后面第一个字段出现。

  • 被频繁JOIN时的条件列

经常出现在join的on条件里面。

4.    加载

在相同的数据量下,加载次数越少,系统消耗的资源越少。要尽量避免小文件频繁加载,比如每次1行,每秒加载1次,要选择合适的实效性,来调整加载频率。

根据表数量和实效性要求,调整加载并发数量。

4.1.            加载实效性

在客户允许的最大查询延迟的前提下,尽量增大加载间隔。比如业务要求15分钟必须能查到,那么每5分钟加载一次就可以满足要求了。

每次加载,即使只加载100行,系统也要走完整的流程,读写磁盘。而目前操作系统足校的数据块是4K,RAID卡的最小的条带是64K,所以每次写很少的数据量,将增加磁盘的IOPS负载。

4.2.            加载文件大小

相同的文件总量,文件越小,则文件数量越多,则磁盘操作,网络操作次数越多,会明显影响加载性能。比如1G的数据文件,对比100万个1K的文件。

根据工程经验,单个文件超过1G,区别已经不是很大了。

在能接受的前提下,文件大小越大越好,考虑到管理成本和加载报错的成本,建议单个文件不要超过1T。

4.3.            多表并行加载

并行越高,不同表,不同列都在随机读写,对磁盘的IOPS要求越高。而且非常高的并发写入,产生磁盘碎片的几率增加,对后续查询性能有影响。

并发高,磁盘使用率高,也会影响前台查询性能。

一般建议,加载并发的表数量,在5个以内。单表列越多,建议并发的表越少。具体以数据库的系统资源监控结果为准。

5.    hint 优化

如果某些SQL需要在特定系统参数下性能最佳,又不想修改集群参数而影响其它SQL,可以通过hint方式设置当前SQL的参数。

hint 仅对当前SQL有效。

session设置(set)对当前连接有效。

session全局设置(set global) 对所有新开始的连接有效(不包括自己和正在执行中的SQL)

配置文件对所有连接有效。

5.1.            使用方法:

select /*+ _gbase_parallel_aggr_mode(2) */ ci,count(*) from t1 group by ci;

  • 多个参数用逗号分隔开。
  • 属性只对本SQL有效。
  • 用gccli执行,必须增加-c -q参数,否则  /* */之间会当成注释自动忽略掉。

5.2.            first_rows

select /*+ first_rows(10) */ ci,count(*) from t where id=1234 limit 100;

  • 不能有offset参数。
  • 不能有order,groug等本身就需要多节点并行操作的语法。
  • 随机分布表
  • 不支持union,但支持union all

如果完全并行,每个节点都返回100行,那么10个节点将返回1000行,而最终有900行被抛弃,会造成资源浪费。而默认优化方案是:逐个节点串行查询,直到行数符合要求。最佳结果是第一个节点就满足要求,最差结果是全部节点串行查询完。

这个参数是让所有节点全部参与查询,每次只返回指定的行数行,如总数已经达到limit要求,则会内部中断后续的数据扫描和传输。一般设置为limit的行数除以节点数量,比如100行,10个节点,则这个参数建议写10。

如有更多疑问,可以访问官方论坛 http://www.gbase8a.com/forum.php

数据库入门,请参考 http://www.gbase8.cn/491