以下结论皆为沟通学习的结果,如有错误的地方,欢迎指出。、
HDFS(Hadoop Distributed File System)
特点
分布式存储,高容错,高效率,多节点并发访问、处理
存储方式
NameNode按照配置块的大小将文件分割成块,拷贝2份后,平均分布在每个DataNode上,重新组合。
NameNode中的数据字典用于存储 DataNode 和 块的物理地址
访问方式
当一个SQL查询发起,会直接访问NameNode,NameNode收到查询请求,会从数据字典中查询出文件存储的节点(DataNode)和 对应的物理地址,DataNode收到查询命令,所有的DataNode并发进行查询操作。
数据倾斜
由于数据存储的问题,HDFS分块无法将数据平均分布,容易发生数据倾斜.
举个极端的例子:
一张EMP表共600条数据
假设集群共有1个NameNode和6个DataNode节点(1-6),且emp表中的empno是顺序存储,那么极端情况下数据分布如下
DataNode1: empno = [0,100]
DataNode2: empno = [101,200]
DataNode3: empno = [201,300]
DataNode4: empno = [301,400]
DataNode5: empno = [401,500]
DataNode6: empno = [501,600]
当发生如下查询时:
select empno || ' ' ||empname from emp where empno < 200;
所有满足条件的数据可能都会存储在DataNode1和2中,而不是均匀分布在所有的DataNode中,所以6台DataNode只用到了2台
数据倾斜导致资源空闲。
如果empno < 200的数据均匀分布在6台机器上,那么使用的资源,就会从2台变成6台。
分区
传统文件系统和RDBMS的分区请看我另一篇文章 《Oracle SQL优化基础》之分区
基于HDFS的存储特性,SQL on Hadoop上的分区就变成了和传统数据库完全不一样一个概念
传统数据库分区是为了将大表分成一个个的小表,读表时 减少 所读取的数据量,降低I/O
而HDFS的分区则变相成为了协助负载均衡的一种方式:为了让数据均匀的存储在所有的DataNode上,以此来最大程度的使用所有资源。
所以一般我们是在业务上有唯一约束的列上做Hash分区,Actian VectorH的分区个数建议不大于Nodes * CPU * Cores / 4