Presto 支持多种操作模式,可以通过 Presto Cli、JDBC、HUE,以及 Airflow 等方式,连接至 Presto 进行 SQL 查询分析。
说明
EMR Presto 默认启用 LDAP 认证,因此您在操作 Presto 时需要携带必要的认证信息。如果您需要关闭 LDAP 认证(不推荐),可以在控制台“集群详情 > 服务列表 > Presto > 服务参数” 页面将 presto.ldap-enabled
配置项设置为 false,并重启 Presto 服务即可。
已创建 E-MapReduce(EMR)集群,并包含 Presto、Hue、Airflow 组件服务。详见创建集群。
若 Presto web ui 访问链接不能点击,请检查 Presto 所在 ECS 实例是否绑定弹性公网IP,详见访问链接。
需要在集群详情 > 访问链接 > 配置服务端口中,给源地址和对应端口添加白名单才可继续访问。
如果希望通过 Presto Cli 访问操作 Presto,您需要先登录到目标集群,然后执行如下命令进入 Presto 交互终端:
集群登录操作详见:登录集群。
$ presto --user <username> --password
说明
EMR Presto 默认会从配置目录读取 default-cli.properties 配置文件,并使用该配置文件内容填充命令行缺失的参数。当然,您也可以主动在命令行中进行参数设置,在命令行中指定的参数优先级高于 default-cli.properties 配置文件。
在完成登录到 Presto Cli 交互终端后,接下来您可以在终端中输入需要执行的 SQL 语句执行查询任务,例如:
presto> select * from tpch.sf1.nation; nationkey | name | regionkey | comment -----------+----------------+-----------+-------------------------------------------------------------------------------------------------------------------- 0 | ALGERIA | 0 | haggle. carefully final deposits detect slyly agai 1 | ARGENTINA | 1 | al foxes promise slyly according to the regular accounts. bold requests alon 2 | BRAZIL | 1 | y alongside of the pending deposits. carefully special packages are about the ironic forges. slyly special 3 | CANADA | 1 | eas hang ironic, silent packages. slyly regular packages are furiously over the tithes. fluffily bold 4 | EGYPT | 4 | y above the carefully unusual theodolites. final dugouts are quickly across the furiously regular d 5 | ETHIOPIA | 0 | ven packages wake quickly. regu 6 | FRANCE | 3 | refully final requests. regular, ironi 7 | GERMANY | 3 | l platelets. regular accounts x-ray: unusual, regular acco 8 | INDIA | 2 | ss excuses cajole slyly across the packages. deposits print aroun 9 | INDONESIA | 2 | slyly express asymptotes. regular deposits haggle slyly. carefully ironic hockey players sleep blithely. carefull 10 | IRAN | 4 | efully alongside of the slyly final dependencies. 11 | IRAQ | 4 | nic deposits boost atop the quickly final requests? quickly regula 12 | JAPAN | 2 | ously. final, express gifts cajole a 13 | JORDAN | 4 | ic deposits are blithely about the carefully regular pa 14 | KENYA | 0 | pending excuses haggle furiously deposits. pending, express pinto beans wake fluffily past t 15 | MOROCCO | 0 | rns. blithely bold courts among the closely regular packages use furiously bold platelets? 16 | MOZAMBIQUE | 0 | s. ironic, unusual asymptotes wake blithely r 17 | PERU | 1 | platelets. blithely pending dependencies use fluffily across the even pinto beans. carefully silent accoun 18 | CHINA | 2 | c dependencies. furiously express notornis sleep slyly regular accounts. ideas sleep. depos 19 | ROMANIA | 3 | ular asymptotes are about the furious multipliers. express dependencies nag above the ironically ironic account 20 | SAUDI ARABIA | 4 | ts. silent requests haggle. closely express packages sleep across the blithely 21 | VIETNAM | 2 | hely enticingly express accounts. even, final 22 | RUSSIA | 3 | requests against the platelets use never according to the quickly regular pint 23 | UNITED KINGDOM | 3 | eans boost carefully special requests. accounts are. carefull 24 | UNITED STATES | 1 | y final packages. slow foxes cajole quickly. quickly silent platelets breach ironic accounts. unusual pinto be (25 rows) Query 091124_00003_5sscg, FINISHED, 2 nodes Splits: 32 total, 32 done (100.00%) [Latency: client-side: 0:02, server-side: 0:02] [25 rows, 0B] [11 rows/s, 0B/s]
使用 JDBC 方式操作 Presto 需要引入 presto-jdbc 依赖,您可以通过 maven 方式下载公共版本(如下),也可以获取由 EMR 编译生成的 presto-jdbc 依赖包(位于集群 /usr/lib/emr/current/presto
目录)。
<dependency> <groupId>com.facebook.presto</groupId> <artifactId>presto-jdbc</artifactId> <version>${latest_version}</version> </dependency>
以 Java 语言为例,如果您需要在您的程序代码中使用 JDBC 访问 Presto,可以参考如下示例程序,区分是否启用 LDAP 认证。
启用 LDAP 认证
Properties props = new Properties(); // username 和 password 来自在用户管理中导入或创建的用户 props.setProperty("user", "<username>"); props.setProperty("password", "<password>"); props.setProperty("SSL", "true"); // keystore 路径,对应 http-server.https.keystore.path 配置项 props.setProperty("SSLKeyStorePath", "<keystore_path>"); // keystore 密码,对应 http-server.https.keystore.key 配置项 props.setProperty("SSLKeyStorePassword", "<keystore_password>"); /* * 连接地址模板为 jdbc:presto://<host>:<port>,其中: * - port 在启用 LDAP 认证时为 8085,未启用 LDAP 认证时为 8084; * - host 为 Coordinator 所在的主机名,例如 emr-xxxxxx-master-1 */ String url = "jdbc:presto://<coordinator_host>:8085"; try (Connection connection = DriverManager.getConnection(url, props); Statement statement = connection.createStatement()) { ResultSet resultSet = statement.executeQuery("select * from tpch.sf1.nation"); // ... }
关闭 LDAP 认证
Properties props = new Properties(); // username 来自在用户管理中导入或创建的用户 props.setProperty("user", "<username>"); /* * 连接地址模板为 jdbc:presto://<host>:<port>,其中: * - port 在启用 LDAP 认证时为 8085,未启用 LDAP 认证时为 8084; * - host 为 Coordinator 所在的主机名,例如 emr-xxxxxx-master-1 */ String url = "jdbc:presto://<coordinator_host>:8084"; try (Connection connection = DriverManager.getConnection(url, props); Statement statement = connection.createStatement()) { ResultSet resultSet = statement.executeQuery("select * from tpch.sf1.nation"); // ... }
上述程序编译成 jar 包之后可以在您的 EMR 集群上运行。如果您是在 EMR 集群之外运行则需要注意:
您需要将集群上的 keystore 文件下载到您程序运行所在的位置,并修改 keystore_path
参数指向您本地的 keystore 文件。
您需要保证程序运行所在节点与 EMR 集群 Presto Coordinator 节点的连通性,包括 host 连通性和 port 连通性。
通过 JDBC 方式也支持您在本地使用数据库管理工具连接访问 Presto,本小节以 DBeaver 为例介绍如何配置 Presto 数据库连接。本地访问 EMR 集群 Presto 服务通常需要您为 Presto Coordinator 所在节点绑定公网 IP,同时区分是否启用了 LDAP 认证。
启动 LDAP 认证
master-1-1.emr-d2bc787xxx.cn-beijing.emr-volces.com
确认本地对于 Presto 服务端口 8085 的连通性,如果 Presto Coordinator 所在节点未对本地出网 IP 开放端口,可以在 ECS 安全组中进行配置。
将集群上 Presto 的 keystore 文件复制到本地。集群上的 keystore 文件位置可以通过控制台侧 Presto 服务参数中 http-server.https.keystore.path
配置项获取。
在 DBeaver 中配置 Presto 数据库连接,如下图所示:
除了填写基本的主机、端口、用户名,以及密码信息外,还需要编辑驱动属性,添加如下配置项:
参数 | 说明 |
---|---|
SSL | 启用 SSL 连接,值始终设置为 true |
SSLKeyStorePath | 对应下载到本地的 keystore 文件路径 |
SSLKeyStorePassword | 对应 keystore 证书密钥,可以通过控制台侧 Presto 服务参数中 http-server.https.keystore.key 配置项获取 |
通过在控制台侧“集群详情 - 节点管理”查看获取 Presto Coordinator 所在节点的 DNS 信息,例如 master-1-1.emr-d2bc7871c917fb2410de.cn-beijing.emr-volces.com
;
确认本地对于 Presto 服务端口 8084 的连通性,如果 Presto Coordinator 所在节点未对本地出网 IP 开放端口,可以在 ECS 安全组中进行配置;
在 DBeaver 中配置 Presto 数据库连接,如下图所示:
关闭 LDAP 认证场景下连接 Presto 服务相对要简单很多,只需要配置主机、端口,以及用户名即可。
您可以通过 Hue 界面提交 Presto SQL 语句进行查询分析,执行 SQL 的用户即为登录 Hue 的用户。EMR Hue 默认会依据 Presto 配置项进行自动化配置,做到开箱即用,但当存在以下情况时需要您在控制台手动重启 Hue 服务以感知 Presto 配置项的变化:
Presto 配置项发生变更,例如在控制台修改了 Presto 的配置参数。
Presto 安装顺序在 Hue 之后,因为 Presto 是可选服务,手动添加安装时无法保证二者的安装顺序。
当您在登录并进入 Hue 交互页面后,可以按照如下操作步骤运行 Presto SQL 查询:
在 Hue Editor 界面选择 Presto;
在 SQL 编辑器中输入 Presto SQL 语句,并提交运行;
查看运行结果。
通过 Airflow 操作 Presto 需要您事先编辑好 DAG 文件,并上传至 Airflow 的 DAGs 目录中,具体可以参考 EMR Airflow 使用说明。需要注意的是:
EMR Airflow 已为 Presto 做了自动化集成,添加了 ID 为 presto 的 connection 配置,您编写的 Presto DAG 脚本中需指定 conn_id=presto
。
如果您变更了 Presto 的服务配置,则需要重启 Airflow WebServer 以感知 Presto 变更的配置项。
Presto DAG 脚本示例:
from datetime import timedelta import airflow from airflow.hooks.presto_hook import PrestoHook from airflow.operators.python_operator import PythonOperator default_args = { 'owner': 'airflow', 'presto_conn_id': 'presto', 'depends_on_past': False, 'start_date': airflow.utils.dates.days_ago(0), 'email': ['airflow@example.com'], 'email_on_failure': True, 'email_on_retry': False, 'retries': 3, 'retry_delay': timedelta(minutes=15), } dag = airflow.DAG('presto-demo', default_args=default_args, description='Presto Demo', schedule_interval=timedelta(minutes=30) ) ph = PrestoHook(presto_conn_id='presto', catalog='hive', schema='default', port=8080 ) def presto_create_table(**context): sql = """CREATE TABLE IF NOT EXISTS tb_airflow_demo(id int, name varchar)""" data = ph.get_records(sql) return True def presto_insert_data(**context): sql = """INSERT INTO tb_airflow_demo SELECT 1, 'name1' """ data = ph.get_records(sql) return True def presto_select_data(**context): sql = """SELECT * FROM tb_airflow_demo LIMIT 20""" data = ph.get_records(sql) return True presto_create_table_task = PythonOperator( task_id='presto-create_table', provide_context=True, python_callable=presto_create_table, dag=dag ) presto_insert_data_task = PythonOperator( task_id='presto_insert_data', provide_context=True, python_callable=presto_insert_data, dag=dag ) presto_select_data_task = PythonOperator( task_id='presto_select_data', provide_context=True, python_callable=presto_select_data, dag=dag ) presto_create_table_task >> presto_insert_data_task >> presto_select_data_task if __name__ == "__main__": dag.cli()
将上述脚本上传到 Airflow 的 DAGs 目录下之后,您可以在 Airflow 的管理页面看到对应的 DAG 任务,如下图所示: