本文介绍SQL增强的实现原理和操作步骤,帮助您快速掌握其核心能力。
实现原理
背景信息
日志服务将存储与计算分离:存储层抽象为分区(Shard),负责数据存储和管理;计算层抽象为SQL,提供查询分析能力。
要提升SLS的分析性能,关键是增强存储层和计算层的能力。以下是几种常见方案及其对比。
方案一:分裂Shard
通过手动分裂Shard实现存储层能力扩展,间接提升计算吞吐量。
方案局限:
仅对新写入数据生效。
活跃Shard持续产生租用费用(详见费用说明)。
单查询受并发数/数据量限制。
需人工介入分裂/合并操作。
方案二:查询分治
将大查询拆解为多个子查询,通过二次聚合获取最终结果。
方案局限:
需维护二次聚合逻辑与中间结果存储(可通过定时SQL实现)。
分析维度变更导致聚合逻辑重构。
数据量级过大时仍存在计算瓶颈。
方案三:SQL增强
开启SQL增强后,日志服务会根据数据规模自动扩展存储和计算资源,加速分析过程。
对比维度 | 方案一(分裂Shard) | 方案二(查询分治方案) | 方案三(SQL增强) |
资源隔离性 | 存储资源独立,共享计算资源 | 存储资源独立,共享计算资源 | 存储资源独立,提供弹性独享资源 |
扩展粒度 | 存储层扩展 | 计算层扩展 | 存储+计算层弹性伸缩 |
运维成本 | 需人工干预 | 大查询拆解为多个子查询 | 全自动调度 |
查询复杂度 | 原生SQL支持 | 需二次开发 | 原生SQL支持 |
前提条件
已创建Standard Logstore。具体操作,请参见创建Logstore。
已采集日志。具体操作,请参见数据采集。
已配置索引。具体操作,请参见配置索引。
操作步骤
日志服务支持如下两种开启SQL增强方式。
单次开启:仅当前Logstore下的查询和分析操作,使用SQL增强。
默认开启:当前Project下的所有查询和分析操作(包括告警、仪表盘等),都使用SQL增强。
控制台
单次开启SQL增强
登录日志服务控制台。
在Project列表区域,单击目标Project。
在
页签中,单击目标Logstore。单击
。
默认开启SQL增强
登录日志服务控制台。
在Project列表区域,单击目标Project。
单击
图标。
将鼠标悬浮在SQL独享版CU数上,然后单击设置。
在编辑SQL独享版CU数面板中,打开是否默认开启的开关,然后单击确定。
API
单次开启SQL增强
以下两个参数设置一个即可。
参数
powerSql
:设置为true,表示当前查询使用SQL增强。设置为false(默认值),使用SQL普通版。参数
query
:例如查询分析语句为* | select count(*) as pv
,在分析语句中增加set session parallel_sql=true;
,表示使用SQL增强。查询分析语句为:* | set session parallel_sql=true; select count(*) as pv
。
GetLogsV2(返回结果压缩后传输) - 查询Logstore中的日志数据
以下两个参数设置一个即可。
参数
powerSql
:设置为true,表示当前查询使用SQL增强。设置为false(默认值),使用SQL普通版。参数
query
:例如查询分析语句为* | select count(*) as pv
,在分析语句中增加set session parallel_sql=true;
,表示使用SQL增强。查询分析语句为:* | set session parallel_sql=true; select count(*) as pv
。
默认开启SQL增强
CreateSqlInstance - 创建SQL独享实例 接口参数useAsDefault=true
,为Project默认开启SQL增强。
SDK
此处以Java SDK为例。
前提条件
单次开启SQL增强
GetLogs()方法
以下两个参数设置一个即可。
参数
powerSql
:设置为true,表示当前查询使用SQL增强。设置为false(默认值),使用SQL普通版。参数
query
:例如查询分析语句为* | select count(*) as pv
,在分析语句中增加set session parallel_sql=true;
,表示使用SQL增强。查询分析语句为:* | set session parallel_sql=true; select count(*) as pv
。
import com.aliyun.openservices.log.Client; import com.aliyun.openservices.log.exception.LogException; import com.aliyun.openservices.log.response.GetLogsResponse; import java.util.Date; public class CreateSqlInstance { public static void main(String[] args) throws LogException { // 本示例从环境变量中获取AccessKey ID和AccessKey Secret。 String accessId = System.getenv("ALIBABA_CLOUD_ACCESS_KEY_ID"); String accessKey = System.getenv("ALIBABA_CLOUD_ACCESS_KEY_SECRET"); // 设置日志服务的服务接入点。此处以杭州为例,其它地域请根据实际情况填写。 String host = "https://cn-beijing.log.aliyuncs.com"; // 创建日志服务Client。 Client client = new Client(host, accessId, accessKey); // 输入Project名称。 String projectName = "aliyun-project-test"; // logstore名称 String logstore = "request_log"; // 是否使用SQL增强,默认为false boolean useAsDefault = true; // SQL查询分析语句 String query = "* | select count(1)"; // 仅当 query 参数为查询语句时,该参数有效,表示请求返回的最大日志条数。最小值为 0,最大值为 100,默认值为 100。 int line = 3; // 仅当 query 参数为查询语句时,该参数有效,表示查询开始行。默认值为 0。 int offset = 0; // 用于指定返回结果是否按日志时间戳降序返回日志,精确到分钟级别。 // true:按照日志时间戳降序返回日志。 // false(默认值):按照日志时间戳升序返回日志。 boolean reverse = false; // 是否使用 SQL 增强。 // true:使用 SQL 增强。 // false(默认值):使用 SQL 普通版。 boolean powerSql = true; int from = (int) (new Date().getTime() / 1000 - 600); int to = (int) (new Date().getTime() / 1000); GetLogsResponse getLogsResponse = client.GetLogs(projectName, logstore, from, to, "", sql, line, offset, reverse, powerSql); System.out.println(getLogsResponse.getCpuSec()); } }
默认开启SQL增强
接口参数boolean useAsDefault = true
,为Project默认开启SQL增强。
import com.aliyun.openservices.log.Client;
import com.aliyun.openservices.log.exception.LogException;
import com.aliyun.openservices.log.request.CreateOrUpdateSqlInstanceRequest;
public class CreateSqlInstance {
public static void main(String[] args) throws LogException {
// 本示例从环境变量中获取AccessKey ID和AccessKey Secret。
String accessId = System.getenv("ALIBABA_CLOUD_ACCESS_KEY_ID");
String accessKey = System.getenv("ALIBABA_CLOUD_ACCESS_KEY_SECRET");
// 输入Project名称。
String projectName = "aliyun-test-project";
// 设置日志服务的服务接入点。此处以杭州为例,其它地域请根据实际情况填写。
String host = "https://cn-beijing.log.aliyuncs.com";
// 创建日志服务Client。
Client client = new Client(host, accessId, accessKey);
int cu = 100;
boolean useAsDefault = true;
client.createSqlInstance(new CreateOrUpdateSqlInstanceRequest(projectName, cu, useAsDefault));
}
}
常见问题
如何获取CPU时间?
执行查询和分析操作后,将鼠标悬浮在分析结果上,查看CPU时间,如下图所示。
使用一次SQL独享版的费用是多少?
在不同的数据量中执行不同的查询和分析语句,会产生不同的SQL独享版费用,案例如下表所示。
查询和分析语句
数据量(行)
平均每次的费用(元)
* | select avg(double_0) from stress_s1_mil1
40亿
0.030
* | select avg(double_0), sum(double_0), max(double_0), min(double_0), count(double_0) from stress_s1_mil1
40亿
0.044
* | select avg(double_0), sum(double_1), max(double_2), min(double_3), count(double_4) from stress_s1_mil1
40亿
0.092
* | select key_0 , avg(double_0) as pv from stress_s1_mil1 group by key_0 order by pv desc limit 1000
40亿
0.080
* | select long_0, avg(double_0) as pv from stress_s1_mil1 group by long_0 order by pv desc limit 1000
40亿
0.075
* | select long_0, long_1, avg(double_0) as pv from stress_s1_mil1 group by long_0,long_1 order by pv desc limit 1000
3亿
0.073
* | select avg(double_0) from stress_s1_mil1 where key_0='key_987'
40亿
0.0005