Presto FAQ

本文汇总了使用DLA Presto的常见问题及解决方案。

高频问题

在哪些情况下,共享集群(Public)不计费?

DDL是不收费的,其它情况按照扫描量收费,详情请参见按扫描量付费

共享集群(Public)的算力是多大?

共享集群(Public)是一个所有用户共享使用的集群,每个用户的算力大致等价于一个10Core的集群。

在控制台执行SELECT语句为什么会有Limit 500的限制?能够突破这个限制吗?

原因:太多的数据展示导致页面崩溃,为了保障控制台页面的稳定性,设置了行数500的限制。

解决方案:您可以通过MySQL客户端连接DLA来突破这个限制。

RAM用户可以在哪里执行SQL?

当前DLA控制台都是使用主账号执行SQL的。RAM用户只能通过在DLA控制台生成DLA的子账号(用户名+密码),使用DMS执行SQL。

什么是异步执行?如何使用?

异步执行主要针对ETL类SQL(INSERT...SELECT....), 这种SQL耗时较长,如果使用同步执行,那么这段时间客户端与服务器端之间的连接会始终被占用,如果有网络异常还会导致查询失败。而异步执行则是提交SQL之后立即返回一个ID,后续只需使用SHOW QUERY_TASK语句去监控这个查询的状态即可。

异步查询的提交:

/*+ run-async=true*/ SELECT * FROM tbl;

异步查询的状态查询:

SHOW QUERY_TASK WHERE ID = '.....'

控制台上异步执行如何拿到执行结果?

先执行异步执行,控制台会显示ASYNC_TASK_ID,用这个ID在同步执行里面运行show query_task where id = 'xxxx',返回结果里面的result_file_oss_file字段为结果所在OSS的路径。

注意

只有当SQL执行完成后,result_file_oss_file才会有值。

多个Hint如何一起使用?

您可以参考如下代码。

/*+ cluster=public,run-async=true */ 
SELECT * FROM tbl

虚拟集群问题

如何设置DLA Presto默认集群?

如果需要所有的查询默认都提交到某个指定的集群,那么您可以通过以下菜单路径进行设置:系统设置 > 设置Presto引擎的默认集群

如何设置链接级别的默认虚拟集群?

您可以通过在用户名后面加上@<集群标识>的方法来指定链接的集群。

如何把DLA Presto提交到指定的虚拟集群?

当您创建虚拟集群后(假设命名为dladw),您可以通过如下方式把SQL提交到指定的虚拟集群。

  • 通过在SQL中指定hint的方式把SQL提交到指定的虚拟集群执行,例如:/*+cluster=dladw*/SELECT * FROM tbl;

  • 通过链接用户名指定虚拟集群:支持在用户名后面加上@<集群标识>的方法来指定链接的集群。

说明

您可以在集群详情页面查看集群标识。

  • 设置默认集群为dladw。

元数据/DDL相关问题

为什么执行MSCK REPAIR TABLE加载不了分区?

MSCK的命令只能对目录名字符合XXX=XXX的格式加载分区。例如:oss://abc/yyy/action/year=2018/。

如何处理建库报错:Generate vpc reverse access mapping ip & mapping port failed, please check your vpc_id(vpc-xxxx) and instance_id(rm-xxx)!?

此时报错的可能原因和解决方案如下。

  • 原因:您的VPC ID和Instance ID填写错误。
    解决方案:请正确进行填写。
  • 原因:您的RDS实例做过数据迁移,页面显示的实例ID不是真实的ID。

    解决方案:您可以添加一个属性USE_VPC_CLOUD_INSTANCE_ID = 'true'。示例代码如下。

    CREATE SCHEMA `test_db` WITH DBPROPERTIES (   
    CATALOG = 'mysql',   
    LOCATION = 'jdbc:mysql://rm-xxx.mysql.rds.aliyuncs.com:3306/dla_test',  
    USER='dla_test',   PASSWORD='xxxxx',   INSTANCE_ID = 'rm-xxx',   
    VPC_ID = 'vpc-xxxx',   
    USE_VPC_CLOUD_INSTANCE_ID = 'true' );

如何查看表的分区数目?

您可以通过如下命令查看表的分区数目。

select count(distinct <partition_key>) from tbl;

OSS/Hive数据源相关问题

如何通过SQL查询一个OSS表里面的文件数?

您可以通过如下命令进行查询。

select count(distinct `$path`) from tbl;
注意

上面的SQL语句中您只需要修改tbl为您真实的表名,其它部分不用修改。

如何查询CSV文件的中文出现乱码问题?

原因:在Linux中使用file命令查看文件编码,之后建表的时候使用LazySimpleSerDe作为Serde

解决方案:如果原始编码为ISO-8859,您可以进行如下配置serialization.encoding=gbk

使用Insert类型的SQL语法时,如何减小输出的文件数?

您可以通过Hint调整以下两个参数的取值。

  • table_write_worker_count:输出Task的并行度。

  • task_writer_count:每个Task写文件的并行度。

输出文件数一般等于table_write_worker_count*task_writer_count。如果需要减小输出文件数,您可以把table_write_worker_count取值调整为10,task_writer_count取值调整为2。

说明
  • 由于集群规模、实际数据分布等因素都会影响输出的文件数,因此控制输出的文件数比较复杂。

  • 只有CU版本才支持输出文件数的相关配置。

支持基于.gz压缩的数据吗?

支持。目前支持GZIP和SNAPPY两种压缩算法。

能同时处理相同目录下的压缩文件和非压缩文件吗?

可以。

DLA的表默认会递归读取表目录下的所有子目录和文件吗?

是的。

为什么同一个SQL从HDFS同步数据到OSS,在DLA中查询是11万数据量,自建的集群查询是19万数据量?

原因:大部分情况是同步数据到OSS存在问题。
解决方案:您可以查看自己的OSS的数据是否正常同步。

性能相关问题

如何解决查询报错:“Query exceeded distributed user memory limit of 2.00TB or Query exceeded per-node user memory limit of xxGB”?

DLA Presto中一个查询能使用的单个节点的内存以及整个集群的总内存是有限制的,您可以通过如下方式进行解决。

  • 优化JOIN以减少对于内存的需求。例如把数据量大的放在左边,数据量小的放在右边。

  • 对数据进行分区。

  • 分拆计算,把一个大SQL拆成多个小SQL。

文件格式是ORC,为什么看扫描量是扫描了整个文件,而不是只扫描SQL里面指定的列?

分析型的查询往往只会获取一个表里面少数几列的数据,这样执行引擎比如Presto在实际扫描底层数据的时候只需要扫描需要的列的数据。而这种节省扫描量的效果只有当底层的数据是以列存的形式存储才能达到。示例代码如下。
SELECT col1 FROM tbl1 WHERE col2 = 'hello;

但是在实际使用过程中,如果文件不是很大,或者文件不小但是表的列很多的情况,节省扫描量的效果会不起作用,因为ORC_TINY_STRIPE_THRESHOLD参数会控制Presto只扫描单个列还是整个文件。示例代码如下。

dataSizeSessionProperty(         
    ORC_TINY_STRIPE_THRESHOLD,         
    "ORC: Threshold below which an ORC stripe or file will read in its entirety",           
    hiveClientConfig.getOrcTinyStripeThreshold(),         
    false);

ORC_TINY_STRIPE_THRESHOLD参数的默认值是8MB,所以如果您的Stripe太小,Presto会读取整个文件,而不是读取一个个Stripe。如果每个Stripe太小,一次次地读取Stripe花费在网络上的开销可能比直接读取整个文件的开销还要大。

如何开启大查询功能?

当您查询的数据需要消耗比较多的内存导致一直失败时,您可以开启虚拟集群的大查询功能。开启方法,在查询中添加HINT,示例如下。

/*+big_query=true*/insertintotable1SELECT*FROMtable2;
说明
  • 大查询功能只支持CU版本,不支持扫描量版本。

  • 大查询功能并不能让您查询任意大小的数据量和任意复杂的SQL,如果big_query还解决了不了您的问题请联系DLA答疑同学。

  • Schema的Catalog类型必须是Hive,否则会出现如下报错:big_query only support hive catalog ...。

如何调整查询RDS类数据源的并发度?

以RDS为例,使用DLA扫描线上数据时,如果RDS实例规格比较小,可能无法支撑默认的JDBC Connector并发度。您可以在DLA中引入Hint/*+jdbc-scan-splits=2*/,指定扫描一个数据表时的JDBC Connector并发度。
mysql> /*+jdbc-scan-splits=2*/select count(*) from customer; 
+----------+ 
| count(*) | 
+----------+ 
| 15000002 |

上述customer表对应RDS MySQL数据库中的customer表。DLA扫描RDS MySQL的customer表时,会使用两个线程同时扫描数据。

注意
  • 待扫描目标表必须有一个自增主键,否则无法使用Hint调整查询并发度。对于有自增主键的表,您可以按照自增主键把一个查询切分成多个子查询提高查询并发度。示例代码如下。

-- 原始SQL   
select * from customer;   
-- 切分成如下的子查询   
select * from customer where id >=0 and id <=10000;   
select * from customer where id >=10000 and id <=20000;
  • DLA最大并发度是500,默认并发度是1,对于一些规格配置较低或者复杂数据库,可以将默认并发度适当调低。

其它问题

如何处理报错:because '3.00199E9' in colum n '4' is outside valid range for the datatype INTEGER?

原因:底层对应的数据超出了DLA中INT类型能表示的最大范围。

解决方案:您可以使用BIGINT类型来映射。

如何处理报错:Application was streaming results when the connection failed. Consider raising value of ‘net_write_timeout’ on the server.?

原因:读取MySQL数据源的数据时,由于默认的net_write_timeout取值设置较小,数据还没有读取完毕,MySQL数据源就关闭了连接。

解决方案:您可以在MySQL数据源把net_write_timeout参数的取值适当调高。

如何处理向OTS写数据时报错:Code: OTSParameterInvalid, Message: Invalid update row request: missing cells in request?

原因:OTS属性列为空。

解决方案:您需要手动过滤掉属性列为空的记录。