阿里云E-MapReduce Trino专属集群外连引擎及权限控制踩坑实践

本文涉及的产品
对象存储 OSS,20GB 3个月
云服务器 ECS,每月免费额度200元 3个月
云数据库 RDS MySQL Serverless,0.5-2RCU 50GB
简介: 本文以云厂商售后技术支持的角度,从客户的需求出发,对于阿里云EMR-Trino集群的选型,外连多引擎的场景、Ldap以及Kerberos鉴权等问题进行了简要的实践和记录,模拟客户已有的业务场景,满足客户需求的同时对过程中的问题点进行解决、记录和分析,包括但不限于Mysql、ODPS、Hive connector的配置,Hive、Delta及Hudi等不同表格式读取的兼容,aws s3、阿里云 oss协议访问异常的解决等。

1. 专属Olap集群-Trino/Presto

1.1. 客户需求

EMR-Trino集群,连接Ack集群上的Hive-metastore、Mysql以及ODPS。

其中最为复杂的为自建hive connector的相关配置:

  1. 从表类型方面看包含普通hive表以及delta表
  2. 从存储方面看包含hdfs本地以及深圳region的oss
  3. 从协议上来看,客户hive读写oss数据使用的是aws s3协议

1.2. 集群选型

  1. Hadoop-Commen和Trino为必选
  2. Hive、Yarn、Spark等组件可选,根据自身业务需要
  3. DLF:如果集群同时配置了Hive服务组件,则hive、iceberg、hudi、delta lake连接器将会默认配置好DLF相关参数,可以直接使用。如果集群不需要配置Hive服务组件,也可以直接在创建EMR集群时勾选「TRINO与数据湖构建(DLF)自动连接」,也可以修改hive.metastore=DLF并辅以DLF相关信息来手动配置,参考文档:DLF手动配置
  4. Knox:通过外网代理访问Trino UI的时候则需要部署该服务
  5. Kerberos:只能在创建集群的时候开启,创建后不能开启或关闭

1.3. 高可用

不支持,默认仅在master-1-1节点上部署Coordinator,所以如果作为Trino的专属集群并没有部署其他服务组件的话,可以不选择master的节点高可用来节省成本。

2. 外连引擎及基础使用

2.1. 网络问题

需保证集群之间ip+端口互通。测试样例EMR-Trino集群与自建Hive metastore或mysql等处于同VPC下,放行了交换机下所有内网IP的1/65536端口,可以通过实例白名单或者集群安全组进行操作。

2.2. Hive

  1. 参考文档:
  1. 阿里云官方文档:https://help.aliyun.com/zh/emr/emr-on-ecs/user-guide/hive-connector-1?spm=a2c4g.11186623.0.0.693d28e5RnAjZ4
  2. 开源文档:https://trino.io/docs/current/connector/hive.html
  1. hive连接器配置
  1. hive.properties。如果集群未混部Hive或者配置DLF的情况下,可以直接修改这个配置文件,更改 hive.metastore.uri 为目标集群的 hive metastore 的地址即可,如果不必须访问HDFS,可以不用配置hive.config.resources。 image.png
  2. connectorX.properties(阿里云EMR-Trino服务在控制台上预留了5个connector的配置)。如果集群存在Hive服务或者配置了DLF,可以在EMR预制的connectorX的几个配置文件中,依次配置connector.name、hive.metastore.uri和hive.config.resources。这里需要注意修改配置connector.name从memory改为hive。否则trinoserver初始化的时候插件加载的将会是io.trino.plugin.memory.MemoryConnectorFactory.create而不是io.trino.plugin.hive.InternalHiveConnectorFactory.createConnector。不同connector所校验的参数不同,Trino对于配置项校验非常严格,如果某个配置项有问题会导致整个trinoserver一直无法正常启动。
ERROR   main    io.trino.server.Server  Configuration is invalid
ERROR main  io.trino.server.Server  Configuration errors:
1) Error: Configuration property '<conf>' was not used
io.airlift.bootstrap.ApplicationConfigurationException: Configuration errors:

image.png

2.2.1. 兼容s3协议读取oss上的delta表

2.2.1.1. delta表读取异常,Cannot query Delta Lake table

Caused by: io.trino.spi.TrinoException: Cannot query Delta Lake table 'schema.table_name'
  at io.trino.plugin.hive.HiveMetadata.getTableHandle(HiveMetadata.java:497)
  at io.trino.plugin.hive.HiveMetadata.getTableHandle(HiveMetadata.java:339)
  at io.trino.spi.connector.ConnectorMetadata.getTableHandle(ConnectorMetadata.java:122)
  at io.trino.plugin.base.classloader.ClassLoaderSafeConnectorMetadata.getTableHandle(ClassLoaderSafeConnectorMetadata.java:1074)
  at io.trino.tracing.TracingConnectorMetadata.getTableHandle(TracingConnectorMetadata.java:142)
  at io.trino.metadata.MetadataManager.lambda$getTableHandle$5(MetadataManager.java:282)
  at java.base/java.util.Optional.flatMap(Optional.java:289)
  at io.trino.metadata.MetadataManager.getTableHandle(MetadataManager.java:276)
  at io.trino.metadata.MetadataManager.getRedirectionAwareTableHandle(MetadataManager.java:1579)
  at io.trino.metadata.MetadataManager.getRedirectionAwareTableHandle(MetadataManager.java:1571)
  at io.trino.tracing.TracingMetadata.getRedirectionAwareTableHandle(TracingMetadata.java:1291)
  at io.trino.sql.analyzer.StatementAnalyzer$Visitor.getTableHandle(StatementAnalyzer.java:5444)
  at io.trino.sql.analyzer.StatementAnalyzer$Visitor.visitTable(StatementAnalyzer.java:2218)
  at io.trino.sql.analyzer.StatementAnalyzer$Visitor.visitTable(StatementAnalyzer.java:488)
  at io.trino.sql.tree.Table.accept(Table.java:60)
  at io.trino.sql.tree.AstVisitor.process(AstVisitor.java:27)
  at io.trino.sql.analyzer.StatementAnalyzer$Visitor.process(StatementAnalyzer.java:505)

原因:针对Iceberg、Hudi和Delta Lake,Trino分别提供了单独的连接器。建议您使用各自的独立连接器来执行查询。如果您的作业必须使用Hive连接器,请使用提供的Table Redirection功能将查询转发到相应的独立连接器上。

参考文档:

  1. 阿里云官方文档:https://help.aliyun.com/zh/emr/emr-on-ecs/user-guide/faq-about-trino?spm=a2c4g.11186623.0.i42#fcb9df207ch3q
  2. 开源文档:https://trino.io/docs/current/connector/hive.html

更改配置:

hive connecor添加配置:

hive.delta-lake-catalog-name=delta

delta.properties添加配置:

connector.name=delta-lake(默认)
hive.hdfs.impersonation.enabled=false
hive.metastore.uri=thrift://<自建集群地址>:9083
hive.config.resources=<core-site.xml>,<hdfs-site.xml>

2.2.1.2. 鉴权异常报错,Unable to load AWS credentials

Caused by: com.amazonaws.SdkClientException: Unable to load AWS credentials from any provider in the chain: [EnvironmentVariableCredentialsProvider: Unable to load AWS credentials from environment variables (AWS_ACCESS_KEY_ID (or AWS_ACCESS_KEY) and AWS_SECRET_KEY (or AWS_SECRET_ACCESS_KEY)), SystemPropertiesCredentialsProvider: Unable to load AWS credentials from Java system properties (aws.accessKeyId and aws.secretKey), WebIdentityTokenCredentialsProvider: You must specify a value for roleArn and roleSessionName, com.amazonaws.auth.profile.ProfileCredentialsProvider@6f048d2a: profile file cannot be null, com.amazonaws.auth.EC2ContainerCredentialsProviderWrapper@10c6141b: Failed to connect to service endpoint: ]

看报错抛出的异常为aws鉴权验证异常,了解客户的具体表信息后得知,客户自建ack的hadoop集群,delta表存储在ali oss,但是使用的是aws s3的协议访问,相关信息如下图所示(desc formatted table_name)。初步判断trino集群没有相关的鉴权配置。

|Location                    |s3a://<oss-bucket>/path/<tablename>                                      |       |
|Provider                    |delta                                                                                    |       |
|Owner                       |185                                                                                      |       |
|External                    |true                                                                                     |       |
|Table Properties            |[delta.minReaderVersion=1,delta.minWriterVersion=2]                                      |       |
2.2.1.2.1. 问题复现

emr集群配置aws s3兼容协议读取oss,创建测试表

  1. 获取aws s3的相关jar包。EMR集群上在如下路径为我们提供了当前版本对应的相关jar包,我们将该路径添加到HADOOP_CLASSPATH中。(hadoop-aws-3.2.1.jar,aws-java-sdk-bundle-1.11.375.jar)
export HADOOP_CLASSPATH=$HADOOP_CLASSPATH:/opt/apps/HADOOP-COMMON/hadoop-common-current/share/hadoop/tools/lib/*
  1. 修改hadoop-common中关于s3a的实现类,endpoint和ak

image.png

fs.s3a.impl=org.apache.hadoop.fs.s3a.S3AFileSystem
fs.AbstractFileSystem.s3a.impl=org.apache.hadoop.fs.s3a.S3A
fs.s3a.access.key=<aliyun_access_id>
fs.s3a.secret.key=<aliyun_access_key>
fs.s3a.aws.credentials.provider=org.apache.hadoop.fs.s3a.SimpleAWSCredentialsProvider
fs.s3a.endpoint=oss-cn-hangzhou-internal.aliyuncs.com
  1. 使用spark创建delta表并使用s3a的兼容协议写到oss bucket的路径下
spark-sql --conf spark.hadoop.fs.s3a.impl=org.apache.hadoop.fs.s3a.S3AFileSystem \
--conf fs.s3a.aws.credentials.provider=org.apache.hadoop.fs.s3a.SimpleAWSCredentialsProvider \
--conf spark.hadoop.fs.s3a.endpoint=oss-cn-hangzhou-internal.aliyuncs.com \
--conf spark.hadoop.fs.s3a.access.key=<aliyun_access_id> \
--conf spark.hadoop.fs.s3a.secret.key=<aliyun_access_key> \
--conf spark.hadoop.fs.s3a.path.style.access=false \
--jars /opt/apps/HADOOP-COMMON/hadoop-common-current/share/hadoop/tools/lib/hadoop-aws-3.2.1.jar,/opt/apps/HADOOP-COMMON/hadoop-common-current/share/hadoop/tools/lib/aws-java-sdk-bundle-1.11.375.jar
create table s3_table4(name string) using delta location "s3a://<oss_bucket_name>/<path>/s3_table4/";
insert into s3_table4 values('zhangsan');
  1. trino查询指定catalog下的该表,复现该问题

image.png

2.2.1.2.2. 问题解决

参考开源文档:https://trino.io/docs/current/object-storage/legacy-s3.html

配置trino hive connector相关参数,重启trino server

hive.s3.aws-access-key=<aliyun_access_id>
hive.s3.aws-secret-key=<aliyun_access_key>
hive.s3.endpoint=oss-cn-hangzhou-internal.aliyuncs.com
hive.s3.path-style-access=false

查询成功

image.png

2.2.1.2.3. 踩坑记录
  1. 尝试过在trino hive connector中配置hive.config.resources为自定义的core-site.xml,并在其中配置aws s3在hadoop fs上的实现类、鉴权类、ak以及endpoint,无效。
  2. 尝试过根据堆栈抛错,使用emr脚本执行的功能在所有的master和core节点上通过修改/etc/profile修改linux环境变量,export AWS_ACCESS_KEY_ID=xxx,无效。
  3. 具体无效原因可能需要参考堆栈报错的逻辑结合源码进行分析。

2.3. Mysql

  1. 参考文档:
  1. 阿里云官方文档:https://help.aliyun.com/zh/emr/emr-on-ecs/user-guide/mysql-connector?spm=a2c4g.11186623.0.0.ca8628e57wfWMQ
  2. 开源文档:https://trino.io/docs/current/connector/mysql.html
  1. 配置样例:

image.png

2.4. Odps

  1. 配置样例:

image.png

2.5. trino命令行基础使用

trino --server master-1-1:9090
# 切换catalog和schema
use <catalog>.<schema>;
show tables;
select * from <table_name>;
  1. trino - hive metastore查询

image.png

  1. trino - mysql查询

image.png

  1. trino - odps查询

image.png

3. 开源LDAP权限管控

参考文档:

  1. 阿里云官方文档:https://help.aliyun.com/zh/emr/emr-on-ecs/user-guide/manage-ldap-authentication-20?spm=a2c4g.11186623.0.0.253b673bvi12cH
  2. 开源文档:https://trino.io/docs/current/security/ldap.html

3.1. 用户创建

可以在EMR集群-用户管理-添加用户来创建用户

image.png

3.2. 开启TrinoLDAP

image.png

3.3. 登录信息获取

  1. 所需信息
  1. 端口从9090变为7778,原9090端口在开启ldap后会报错如下
Error running command: Error starting query at http://master-1-1:9090/v1/statement returned an invalid response: JsonResponse{statusCode=403, headers={cache-control=[must-revalidate,no-cache,no-store], content-length=[422], content-type=[text/html;charset=iso-8859-1]}, hasValue=false} [Error: <html>
<head>
<meta http-equiv="Content-Type" content="text/html;charset=ISO-8859-1"/>
<title>Error 403 Forbidden</title>
</head>
<body><h2>HTTP ERROR 403 Forbidden</h2>
<table>
<tr><th>URI:</th><td>/v1/statement</td></tr>
<tr><th>STATUS:</th><td>403</td></tr>
<tr><th>MESSAGE:</th><td>Forbidden</td></tr>
<tr><th>SERVLET:</th><td>org.glassfish.jersey.servlet.ServletContainer-2ebd6a0d</td></tr>
</table>
</body>
</html>
]
  1. hosts换为域名:master-1-1.<集群id>..emr.aliyuncs.com。本地连接则还需要在/etc/hosts中对于该域名进行ip解析的配置,仅在url里配置ip则可能会有如下的CN认证问题
Hostname 120.xx.xx.x not verified:
    certificate: sha256/QRPpmNxxxxxxxxxxWIlc1iUQWGn/CBLxxxxxn81WY=
    DN: CN=master-1-1.c-7101xxxxxc3d1.cn-hangzhou.emr.aliyuncs.com
    subjectAltNames: []
  1. keystore-path与keystrore-password查看方式:目前EMR管控上查询不到相关参数,需要登录到节点上查看(预期行为?) image.png
  2. 创建用户时指定的user和password

3.4. 集群命令行登录

trino \
--server https://master-1-1.c-71015d6c35d9c3d1.cn-hangzhou.emr.aliyuncs.com:7778 \
--keystore-path /etc/taihao-apps/trino-conf/keystore \
--keystore-password <keystore_secret> \
--user syf373586 \
--password

3.5. 本地dbeaver

连接之前需要通过scp命令从master上将keystore的文件下载到执行环境,并更改SSLTrustStorePath的路径

jdbc:trino://master-1-1.c-7101xxxxxx3d1.cn-hangzhou.emr.aliyuncs.com:7778/hive/sunyf_meta_test?SSL=true&SSLTrustStorePath=/Users/adamsun/keystore&SSLTrustStorePassword=32d14510xxxxxxxxa9244e

image.png

3.6. 本地java

package org.example;
import java.sql.*;
import java.util.Properties;
public class TrinoTest01 {
    public static void main(String[] args) throws SQLException {
        String url = "jdbc:trino://master-1-1.c-71015d6c35d9c3d1.cn-hangzhou.emr.aliyuncs.com:7778/hive/sunyf_meta_test";
        Properties properties = new Properties();
        properties.setProperty("user", "user");
        properties.setProperty("password", "");
        properties.setProperty("SSL", "true");
        properties.setProperty("SSLTrustStorePath", "/Users/adamsun/keystore");
        properties.setProperty("SSLTrustStorePassword", "32d14510xxxxxxxxa9244e");
        Connection connection = DriverManager.getConnection(url, properties);
        // 创建Statement对象
        Statement statement = connection.createStatement();
        // 执行查询
        ResultSet resultSet = statement.executeQuery("select count(*) as cnt from sunyf_test_table");
        Integer index = 1;
        // 处理查询结果
        while (resultSet.next()) {
            System.out.println(resultSet.getInt(1));
            index++;
            //            System.out.println(resultSet);
        }
        // 关闭资源
        resultSet.close();
        statement.close();
        connection.close();
    }
}

4. kerberos权限管控

参考文档:

  1. 阿里云官方文档:https://help.aliyun.com/zh/emr/emr-on-ecs/user-guide/access-trino-by-using-the-cli?spm=a2c4g.11186623.0.0.37d5673bSk3BRe#db81fb8081p8k
  2. 开源文档:https://trino.io/docs/current/client/cli.html#kerberos-authentication

4.1. 用户创建

# 登录
kadmin.local
# 添加test用户,并指定密码
addprinc test
# 为test用户生成keytab,后续再生成keytab需指定-norandkey,避免重新随机导致之前的key失效
xst -norandkey -k  /root/test.keytab test@EMR.<CLUSTER_ID>.COM

image.png

4.2. 集群命令行登录

trino \
--server https://master-1-1.<CLUSTER_ID>.cn-hangzhou.emr.aliyuncs.com:7778 \
--krb5-config-path /etc/krb5.conf \
--krb5-keytab-path /root/test.keytab \
--keystore-path /etc/emr/trino-conf/keystore \
--keystore-password <keystore_secret> \
--krb5-principal test@EMR.<CLUSTER_ID>.COM \
--krb5-remote-service-name trino \
--user test

4.3. 本地dbeaver

4.3.1. kdc认证超时,Receive timed out

报错堆栈:

Exception in thread "main" java.sql.SQLException: Kerberos error for [trino@master-1-1.c-13d43d0f090df583.cn-hangzhou.emr.aliyuncs.com]: Receive timed out
  at io.trino.jdbc.TrinoStatement.internalExecute(TrinoStatement.java:284)
  at io.trino.jdbc.TrinoStatement.execute(TrinoStatement.java:240)
  at io.trino.jdbc.TrinoStatement.executeQuery(TrinoStatement.java:77)
  at org.example.TrinoTest02.main(TrinoTest02.java:25)
Caused by: io.trino.jdbc.$internal.client.ClientException: Kerberos error for [trino@master-1-1.c-13d43d0f090df583.cn-hangzhou.emr.aliyuncs.com]: Receive timed out
  at io.trino.jdbc.$internal.client.auth.kerberos.SpnegoHandler.generateToken(SpnegoHandler.java:157)
  at io.trino.jdbc.$internal.client.auth.kerberos.SpnegoHandler.authenticate(SpnegoHandler.java:123)
  at io.trino.jdbc.$internal.client.auth.kerberos.SpnegoHandler.authenticate(SpnegoHandler.java:111)
  at io.trino.jdbc.$internal.okhttp3.internal.http.RetryAndFollowUpInterceptor.followUpRequest(RetryAndFollowUpInterceptor.kt:223)
  at io.trino.jdbc.$internal.okhttp3.internal.http.RetryAndFollowUpInterceptor.intercept(RetryAndFollowUpInterceptor.kt:108)
  at io.trino.jdbc.$internal.okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:109)
  at io.trino.jdbc.$internal.client.auth.kerberos.SpnegoHandler.intercept(SpnegoHandler.java:98)
  at io.trino.jdbc.$internal.okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:109)
  at io.trino.jdbc.$internal.client.OkHttpUtil.lambda$userAgent$0(OkHttpUtil.java:70)
  at io.trino.jdbc.$internal.okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:109)
  at io.trino.jdbc.$internal.okhttp3.internal.connection.RealCall.getResponseWithInterceptorChain$okhttp(RealCall.kt:201)
  at io.trino.jdbc.$internal.okhttp3.internal.connection.RealCall.execute(RealCall.kt:154)
  at io.trino.jdbc.$internal.client.JsonResponse.execute(JsonResponse.java:113)
  at io.trino.jdbc.$internal.client.StatementClientV1.<init>(StatementClientV1.java:119)
  at io.trino.jdbc.$internal.client.StatementClientFactory.newStatementClient(StatementClientFactory.java:28)
  at io.trino.jdbc.TrinoConnection.startQuery(TrinoConnection.java:757)
  at io.trino.jdbc.TrinoStatement.internalExecute(TrinoStatement.java:252)
  ... 3 more
Caused by: javax.security.auth.login.LoginException: Receive timed out
  at com.sun.security.auth.module.Krb5LoginModule.attemptAuthentication(Krb5LoginModule.java:812)
  at com.sun.security.auth.module.Krb5LoginModule.login(Krb5LoginModule.java:617)
  at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
  at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
  at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
  at java.lang.reflect.Method.invoke(Method.java:498)
  at javax.security.auth.login.LoginContext.invoke(LoginContext.java:755)
  at javax.security.auth.login.LoginContext.access$000(LoginContext.java:195)
  at javax.security.auth.login.LoginContext$4.run(LoginContext.java:682)
  at javax.security.auth.login.LoginContext$4.run(LoginContext.java:680)
  at java.security.AccessController.doPrivileged(Native Method)
  at javax.security.auth.login.LoginContext.invokePriv(LoginContext.java:680)
  at javax.security.auth.login.LoginContext.login(LoginContext.java:587)
  at io.trino.jdbc.$internal.client.auth.kerberos.LoginBasedSubjectProvider.refresh(LoginBasedSubjectProvider.java:118)
  at io.trino.jdbc.$internal.client.auth.kerberos.SpnegoHandler.createGssCredential(SpnegoHandler.java:182)
  at io.trino.jdbc.$internal.client.auth.kerberos.SpnegoHandler.getGssCredential(SpnegoHandler.java:174)
  at io.trino.jdbc.$internal.client.auth.kerberos.SpnegoHandler.generateToken(SpnegoHandler.java:135)
  ... 19 more
Caused by: java.net.SocketTimeoutException: Receive timed out
  at java.net.PlainDatagramSocketImpl.peekData(Native Method)
  at java.net.DatagramSocket.receive(DatagramSocket.java:787)
  at sun.security.krb5.internal.UDPClient.receive(NetClient.java:206)
  at sun.security.krb5.KdcComm$KdcCommunication.run(KdcComm.java:404)
  at sun.security.krb5.KdcComm$KdcCommunication.run(KdcComm.java:364)
  at java.security.AccessController.doPrivileged(Native Method)
  at sun.security.krb5.KdcComm.send(KdcComm.java:348)
  at sun.security.krb5.KdcComm.sendIfPossible(KdcComm.java:253)
  at sun.security.krb5.KdcComm.send(KdcComm.java:229)
  at sun.security.krb5.KdcComm.send(KdcComm.java:200)
  at sun.security.krb5.KrbAsReqBuilder.send(KrbAsReqBuilder.java:335)
  at sun.security.krb5.KrbAsReqBuilder.action(KrbAsReqBuilder.java:488)
  at com.sun.security.auth.module.Krb5LoginModule.attemptAuthentication(Krb5LoginModule.java:780)
  ... 35 more
Process finished with exit code 1

问题分析:

  1. 根据堆栈报错可以看到客户端在请求emr trino集群的kdc进行认证,获取tgt的时候抛出的异常
  2. 查看krb5.conf配置,kdc服务端口为88,通过主节点的kdc进程也可以看出 image.png image.png
  3. 在emr安全组配置本地ip访问88端口的白名单后,报错依旧
  4. 仔细观察堆栈发现:at sun.security.krb5.internal.UDPClient.receive(NetClient.java:206),客户端使用的是UDPClient,通过krb5kdc的进程监听也可以发现有udp的监听,但是安全组仅放行了tcp的端口
  5. EMR安全组放行udp88端口后正常访问

4.3.2. 连接示例

image.png

jdbc:trino://master-1-1.c-13d43d0f090df583.cn-hangzhou.emr.aliyuncs.com:7778/connector1/sunyf_db?SSL=true&SSLTrustStorePath=/Users/adamsun/trino_cluster2_conf/keystore&SSLTrustStorePassword=<keystore_secret>&KerberosConfigPath=/Users/adamsun/trino_cluster2_conf/krb5.conf&KerberosKeytabPath=/Users/adamsun/trino_cluster2_conf/test.keytab&KerberosPrincipal=test@EMR.C-13D43D0F090DF583.COM&KerberosRemoteServiceName=trino

4.4. 本地java

package org.example;
import java.sql.*;
import java.util.Properties;
public class TrinoTest02 {
    public static void main(String[] args) throws SQLException {
        String url = "jdbc:trino://master-1-1.c-13d43d0f090df583.cn-hangzhou.emr.aliyuncs.com:7778/connector1/sunyf_db";
        Properties properties = new Properties();
        properties.setProperty("user", "test");
//        properties.setProperty("password", "");
        properties.setProperty("SSL", "true");
        properties.setProperty("SSLTrustStorePath", "/Users/adamsun/trino_cluster2_conf/keystore");
        properties.setProperty("SSLTrustStorePassword", "<keystore_secret>");
        properties.setProperty("KerberosConfigPath","/Users/adamsun/trino_cluster2_conf/krb5.conf");
        properties.setProperty("KerberosKeytabPath","/Users/adamsun/trino_cluster2_conf/test.keytab");
        properties.setProperty("KerberosPrincipal","test@EMR.C-13D43D0F090DF583.COM");
        properties.setProperty("KerberosRemoteServiceName","trino");
        Connection connection = DriverManager.getConnection(url, properties);
        // 创建Statement对象
        Statement statement = connection.createStatement();
        // 执行查询
        ResultSet resultSet = statement.executeQuery("select count(*) as cnt from flink_window_test01");
        Integer index = 1;
        // 处理查询结果
        while (resultSet.next()) {
            System.out.println(resultSet.getInt(1));
            index++;
//            System.out.println(resultSet);
        }
        // 关闭资源
        resultSet.close();
        statement.close();
        connection.close();
    }
}
相关实践学习
数据湖构建DLF快速入门
本教程通过使⽤数据湖构建DLF产品对于淘宝用户行为样例数据的分析,介绍数据湖构建DLF产品的数据发现和数据探索功能。
快速掌握阿里云 E-MapReduce
E-MapReduce 是构建于阿里云 ECS 弹性虚拟机之上,利用开源大数据生态系统,包括 Hadoop、Spark、HBase,为用户提供集群、作业、数据等管理的一站式大数据处理分析服务。 本课程主要介绍阿里云 E-MapReduce 的使用方法。
相关文章
|
29天前
|
SQL 存储 API
阿里云实时计算Flink的产品化思考与实践【下】
本文整理自阿里云高级产品专家黄鹏程和阿里云技术专家陈婧敏在 FFA 2023 平台建设专场中的分享。
110821 99
阿里云实时计算Flink的产品化思考与实践【下】
|
25天前
|
消息中间件 Kubernetes Kafka
Terraform阿里云创建资源1分钟创建集群一键发布应用Terraform 创建 Kubernetes 集群
Terraform阿里云创建资源1分钟创建集群一键发布应用Terraform 创建 Kubernetes 集群
18 0
|
1月前
|
弹性计算 网络协议 关系型数据库
网络技术基础阿里云实验——企业级云上网络构建实践
实验地址:&lt;https://developer.aliyun.com/adc/scenario/65e54c7876324bbe9e1fb18665719179&gt; 本文档指导在阿里云上构建跨地域的网络环境,涉及杭州和北京两个地域。任务包括创建VPC、交换机、ECS实例,配置VPC对等连接,以及设置安全组和网络ACL规则以实现特定服务间的互访。例如,允许北京的研发服务器ECS-DEV访问杭州的文件服务器ECS-FS的SSH服务,ECS-FS访问ECS-WEB01的SSH服务,ECS-WEB01访问ECS-DB01的MySQL服务,并确保ECS-WEB03对外提供HTTP服务。
|
1月前
|
云安全 人工智能 安全
|
1月前
|
弹性计算 算法 应用服务中间件
倚天使用|Nginx性能高27%,性价比1.5倍,基于阿里云倚天ECS的Web server实践
倚天710构建的ECS产品,基于云原生独立物理核、大cache,结合CIPU新架构,倚天ECS在Nginx场景下,具备强大的性能优势。相对典型x86,Http长连接场景性能收益27%,开启gzip压缩时性能收益达到74%。 同时阿里云G8y实例售价比G7实例低23%,是Web Server最佳选择。
|
1月前
|
Ubuntu JavaScript 关系型数据库
在阿里云Ubuntu 20.04服务器中搭建一个 Ghost 博客
在阿里云Ubuntu 20.04服务器上部署Ghost博客的步骤包括创建新用户、安装Nginx、MySQL和Node.js 18.x。首先,通过`adduser`命令创建非root用户,然后安装Nginx和MySQL。接着,设置Node.js环境,下载Nodesource GPG密钥并安装Node.js 18.x。之后,使用`npm`安装Ghost-CLI,创建Ghost安装目录并进行安装。配置过程中需提供博客URL、数据库连接信息等。最后,测试访问前台首页和后台管理页面。确保DNS设置正确,并根据提示完成Ghost博客的配置。
在阿里云Ubuntu 20.04服务器中搭建一个 Ghost 博客
|
1月前
|
存储 分布式计算 网络协议
阿里云服务器内存型r7、r8a、r8y实例区别参考
在阿里云目前的活动中,属于内存型实例规格的云服务器有内存型r7、内存型r8a、内存型r8y这几个实例规格,相比于活动内的经济型e、通用算力型u1实例来说,这些实例规格等性能更强,与计算型和通用型相比,它的内存更大,因此这些内存型实例规格主要适用于数据库、中间件和数据分析与挖掘,Hadoop、Spark集群等场景,本文为大家介绍内存型r7、r8a、r8y实例区别及最新活动价格,以供参考。
阿里云服务器内存型r7、r8a、r8y实例区别参考
|
1月前
|
SQL 弹性计算 安全
购买阿里云活动内云服务器之后设置密码、安全组、增加带宽、挂载云盘教程
当我们通过阿里云的活动购买完云服务器之后,并不是立马就能使用了,还需要我们设置云服务器密码,配置安全组等基本操作之后才能使用,有的用户还需要购买并挂载数据盘到云服务器上,很多新手用户由于是初次使用阿里云服务器,因此并不知道这些设置的操作流程,下面给大家介绍下这些设置的具体操作流程。
购买阿里云活动内云服务器之后设置密码、安全组、增加带宽、挂载云盘教程
|
1月前
|
弹性计算
阿里云3M带宽云服务器并发多大?阿里云3M带宽云服务器测评参考
在探讨云服务器3M带宽能支持多大并发这一问题时,我们首先要明白一个关键点:并发量并非仅由带宽决定,还与网站本身的大小密切相关。一般来说,一个优化良好的普通网站页面大小可能只有几K,为便于计算,我们可以暂且假定每个页面大小为50K。
822 1
|
1天前
|
存储 小程序 数据库
阿里云学生云服务器申请,阿里云送每个大学生一台云服务器
2024年,阿里云为学生提供免费7个月的学生服务器,包括2核2G配置、1M带宽和独立IP。学生需通过学信网认证,完成任务可额外获得6个月免费时长。申请流程包括注册阿里云账号、实名认证和学生认证。此外,学生可免费领取300元无门槛优惠券,在阿里云高校计划中使用。学生服务器可用于建站、部署等多种场景。详细信息和申请入口见官方链接。
21 0

热门文章

最新文章