开发者学堂课程【《实时数仓入门课程》:Hologres 性能调优实践】学习笔记,与课程紧密联系,让用户快速学习知识。
课程地址:https://developer.aliyun.com/learning/course/807/detail/13889
Hologres 性能调优实践
内容简介:
一、 Hologres 建表最佳实践
二、 Hologres 性能问题分析与优化
一、 Hologres 建表最佳实践
(一)建表优化的必要性
1.性能提升一个量级:好的建表性能和差的建表性能会有数量级上的性能差异。
2.减少数据重复导入:许多表结构上的改动需要重新建表导数据。
3.节约成本:好的建表不仅能优化性能,还能减少物理存储,帮用户省钱。
(二)业务建模是性能优化的前提
1.场景区分:分析型场 OR 在线服务场景。
2.结合 Hologers 产品优势:Hologres 适合实时分析和在线服务,并不适合 ETL 和海量数据拖取。
3.减少计算复杂度:做好灵活度和性能之间的取舍
(三)存储方式的选择
行存
l 按主键进行高 QPS 查询
l 一次查询读取大量列口
l Blink 维表必须采用行存
列存
l 复杂的关联、聚合查询
l 过滤场景复杂
l 覆盖场景多,更为通用优化
(四)优化 shard 数
Shard_ count Shard 实现了物理分表的效果多个 Shard 并行服务查询,增加 Shard 可以增加查询的分布式并行度,更多 Shard 不一定查询更快,也会带来并发查询的调度开销。集群扩容时,最好同时修改 Shard count。建议: Shard 数和 CPU Core对应,减少资源抢占,效率最高。
(五)优化 Distribution Key
l Distribution
_
key:
均衡地分发数据到多个 shard 中,令查询负载更均衡,查询时直接定位到对应 shard 如果创建了 Primary Key 索引(用于数据更新) ,默认为distribution
_
key,
l Distribution key 如果为空,默认是 Random,
l Distribution_ key 需是 Primary Key 的子集,
l Distribution_ key 设置多列时需和查询一一对应, 否则无法准确命中 Shard。
l 同个 TableGroup,所有 Table 的 Shard 数相同,不同 TG 建议按照业务规模,设计不同的
l Shard 数,同一个 Shard 内可以连接,可以 local join。
l 需要连接的表,可以把 Join 关系设为 distribution key
Select from TableA left join Table B
on Aaid= B bid
l 可以分别将 aid 和 bid 分别设置为 distribution_key
l Table 按照业务关系,划分为多个 TG
l TG 增加时,建议扩容,避免 CPU 资源竞争
l Distribution key 设计不合理时,在 Join 时,可能引起大量的 Data Shuffle,影响效率
l 需要连接的表,可以把 Join 关系设为 distribution key,实现 Table 在同一个 Shard 内 Local Join
(六)优化分区表
1.分区表:也是物理表,具备-样的 shard 能力,但多了一个根据分区键进行 Table Pruning 的能力。
Select count(1) from TableA where
partition_ column=0102
2.快速定位到 TableA _0102 表, 略过其他表,实现逻辑上的路白优化。
3.通常将日期列等基数低(小于一万)的字段用于做分区字段, 如果分区表过多,而查询时不带有分区过滤条件,性能会下降。
(七)优化 Segment Key
1.Shard 是个逻辑数据单位,物理上是组文件(分发到同一个 shard 的 多个表,以及对应的索引) 。
2.数据先更新到内存。
3.内存写满了,异步 Flush 到文件,Append Ony 写入,写入效率最高。
4.因为写入时为了性能,没有全局排序和单文件更新,文件之间存在 Overap。
Select count(*)from
TableA1 where
segment_ key> XXX
5.系统后台进行文件块的合并,基于 segment. key 排序,让文件之间尽量没有overtap。
6.Segment_ key 用于文件块的边界划分,查询时基于 Segment key 可以快速定位数据所在文件块,Segment key 多列时,按照左对齐。
(八)优化 ClusteringKey
1.Clustering_ key, 文件内聚簇布局,表示排序信息,和 MySQL 的聚簇索引不同,Hologres 用来布局数据,不是布局索引,因此修改 Clustering,需要重新数据导入,且只有一个 Custering_ key ,排序操作在内存中完成生成SST。
2.如果 Date是Clustering key,因为有序,不能 Null
3.如果 Class, Date 是 Clustering key,Clustering_key 具备最左匹配原则,所以a,b,c 的 Clustering 可以匹配 a,b,但不能匹配 b,c。
(九)优化字典编码
1.字典码对于字符串类型可以有效压缩,特别是基数小的列,编码值可以加快比较操作,对于 group by, filter 有好处,Holo 在 0.9 之后自动设置。
2.Gender 列字典:查询时,需要对过滤条件进行编码,对结果进行解码。
3.CardNo 列字典:基数高的列(比如一列里一半值都不相同),字典编码会带来更多额外的编码、解码开销,对性能有损伤,不建议使用。
(十)优化位图索引
1.位图索引,对于等值过滤场最有明显的优化效果,多个等值过滤条件,通过向量比较计算。
2.Bitmap 索引基于 roaming bitmap 技术,高效存储压缩、计算"交"差。
3.基数过多的列,在位图索引编码时,会形成稀疏数组(列很多,值很少),对查询性能改善影响小。
(十一)物理拓扑
l 找对逻辑对象 Table
l 找对物理节点 Shard
l 找对实际文件 File
l 找对实际文件区间
l 找对实际存储 Block
二、 Hologres 性能问题分析与优化
(一)性能白皮书
l 实时写入:单 Core5000 QPS
l 离线写入:单 Core 5W QPS
l OLAP查询:单 core 处理 200 万数据量
l 点查:单 core 1 万 QPS
(二)实时写入与点查
1.检查建表
l Distribution Key 和查询条件一致
l 行存表
l Pk.Clustering Key 和查询条件一致
2.优化查询写入代码
Preparestmt
Batch
Holo Client
3.其他
l 尽可能使用 VPC 域名
(三)离线写入与查询常见问题
l 统计信息缺失
l 建表不优
l 联邦查询
(四)查看执行计划
执行计划的好坏对于查询性能影响非常大。Hologres 的查询优化器会根据 Cost 选择执行耗时最低的查询计划来执行用户的查询,不过难免会出现一些查询计划不优的情况。用户可以通过 Explain 命令来查询执行计划。执行计划中一般包含以下算子:
l 数据扫描算子: Seq Scan、Table Scan 及 Index Scan 等。
l 连接算子: Hash Join 及 Nested Loop。
l 聚合算子: Hash Aggregate 及 Streaming Aggregate。
l 数据移动算子: Redistribute Motion、 Broadcast Motion 及 GatherMotion 等。
l 其他算子: Hash、Sort、Limit 及 Append 等。
(五)统计信息缺失
统计信息缺失会导致 Hogres 的优化器无法很精确的统计每个算子的执行耗时,进而导致生成比较差的执行计划。容易出现的问题:
l 跑查询 OOM
l 写入性能差
(六)更新统计信息
l 通过 Analyze 命令,用户可以更新统计信息
analyze tmp;
analyze tmp1
(七)选择合适的分布列
如果用户不设置分布列,在进行关联查询时,Hologres 需要将 2 个表的数据根据join key shuffle 到一起,保证数据的正确性。如果 shuffhe 的数据 量很大,会造成很高的查询延迟。
通过设置分布列为 join key,
begin;
create table tmp(a int, b int, c int);
call set _table property( tmp', 'distnbution _key, 'a);
commit,
begin;
create table tmpl(a int, b int, c int);
call set table_ property('tmp1', 'distribution_key 'b');
commit;
(八)判断是否用上 Clustering Key
对于查询:explain select * from tmp where
a
> 1;
(九)判断是否用上 Bitmap
对于查询:explain select * from tmp where
c= 1;
(十)联邦查询优化
l Holo 计算引擎
l 自主研发
l 性能卓越
l 部分 Postgres 功能缺失
l Postgres 计算引擎
l 开源生态
l 相比自研性能劣势
l 完全兼容 Postgres 功能
(十一)优化联邦查询
1.Hologres 自研引擎不支持 not in,对于查询:explain select from tmp where a not in (select a from tmp1);
2.通过 not in 改为 not exist:
e
xplain select * from tmp where not exists(select a from tmpl wherea = tmp.a);