一键部署 Presto 基于 Docker 及 Java 和 Python 客户端连接指南

一键部署 Presto 基于 Docker 及 Java 和 Python 客户端连接指南

Presto 是一个分布式 SQL 查询引擎,设计用于在大数据环境中执行高速查询。本文将详细介绍如何使用 Docker 一键部署 Presto,并展示如何通过 Java 和 Python 客户端连接 Presto 进行数据查询。

目录

  1. 前言
  2. 一键安装 Presto 脚本
  3. 部署 Presto
  4. 通过 Java 连接 Presto
  5. 通过 Python 连接 Presto
  6. 常见问题及解决方案

前言

Presto 是由 Facebook 开发的开源分布式 SQL 查询引擎,能够对各种数据源进行高速查询。无论是数据仓库还是大数据存储,Presto 都能高效地执行复杂查询。借助 Docker,您可以快速部署 Presto 环境,并通过 Java 和 Python 客户端进行数据操作和分析。

一键安装 Presto 脚本

为了简化 Presto 的部署过程,我们提供了一个一键安装脚本 install_presto.sh。该脚本将自动完成以下任务:

  1. 创建必要的目录结构
  2. 生成配置文件 (config.propertiesjvm.config)
  3. 创建 catalog 目录
  4. 生成启动脚本 (presto-start.sh)
  5. 启动 Presto Docker 容器
  6. 进行基本的启动测试

install_presto.sh 脚本内容

将以下脚本内容保存为 install_presto.sh 文件:

#!/bin/bash

# 一键安装 Presto 基于 Docker 的部署及 Connector 配置脚本
# 发布日期:2024-08-10
# 作者:天真美少女

set -e

# 定义变量
PRESTO_DIR="presto-docker"
CONFIG_FILE="$PRESTO_DIR/config.properties"
JVM_CONFIG_FILE="$PRESTO_DIR/jvm.config"
CATALOG_DIR="$PRESTO_DIR/catalog"
START_SCRIPT="$PRESTO_DIR/presto-start.sh"
DOCKER_CONTAINER_NAME="some-presto"
DOCKER_IMAGE="prestodb/presto:latest" # 使用最新版本
HOST_PORT=8080
TIMEZONE="Asia/Shanghai"

# 检查是否安装了 Docker
if ! command -v docker &> /dev/null
then
    echo "错误:Docker 未安装。请先安装 Docker 后重试。"
    exit 1
fi

# 创建目录结构
echo "创建目录结构..."
mkdir -p "$CATALOG_DIR"

# 生成 config.properties
echo "生成 config.properties 文件..."
cat > "$CONFIG_FILE" <<EOL
coordinator=true
node-scheduler.include-coordinator=true
http-server.http.port=$HOST_PORT
discovery-server.enabled=true
discovery.uri=http://localhost:$HOST_PORT
EOL

# 生成 jvm.config
echo "生成 jvm.config 文件..."
cat > "$JVM_CONFIG_FILE" <<EOL
-server
-Xmx2G
-XX:+UseG1GC
-XX:G1HeapRegionSize=32M
-XX:+UseGCOverheadLimit
-XX:+ExplicitGCInvokesConcurrent
-XX:+HeapDumpOnOutOfMemoryError
-XX:+ExitOnOutOfMemoryError
-Djdk.attach.allowAttachSelf=true
EOL

# 生成启动脚本 presto-start.sh
echo "生成启动脚本 presto-start.sh..."
cat > "$START_SCRIPT" <<EOL
#!/bin/bash

# 启动 Presto Docker 容器

# 获取脚本所在目录
cd "\$(dirname "\$0")"
ROOT_DIR=\$(pwd)

# 检查是否已经有同名容器在运行
if [ "\$(docker ps -aq -f name=^/${DOCKER_CONTAINER_NAME}$)" ]; then
    echo "检测到已有容器名为 ${DOCKER_CONTAINER_NAME},尝试停止并移除..."
    docker stop ${DOCKER_CONTAINER_NAME} || { echo "停止容器失败"; exit 1; }
    docker rm ${DOCKER_CONTAINER_NAME} || { echo "移除容器失败"; exit 1; }
fi

# 启动 Presto 容器
docker run -d \
  --name ${DOCKER_CONTAINER_NAME} \
  -p ${HOST_PORT}:8080 \
  -e TZ=${TIMEZONE} \
  -v "\${ROOT_DIR}/config.properties:/opt/presto-server/etc/config.properties" \
  -v "\${ROOT_DIR}/jvm.config:/opt/presto-server/etc/jvm.config" \
  -v "\${ROOT_DIR}/catalog:/opt/presto-server/etc/catalog" \
  ${DOCKER_IMAGE}

echo "Presto 容器已启动,访问 http://localhost:${HOST_PORT} 进行验证。"
EOL

# 赋予启动脚本可执行权限
chmod +x "$START_SCRIPT"

# 启动 Presto 容器
echo "启动 Presto 容器..."
bash "$START_SCRIPT"

# 等待几秒钟以确保容器启动
sleep 5

# 检查容器状态
if [ "$(docker ps -q -f name=^/${DOCKER_CONTAINER_NAME}$)" ]; then
    echo "Presto 已成功启动。"
else
    echo "错误:Presto 启动失败,请检查容器日志。"
    docker logs ${DOCKER_CONTAINER_NAME} || true
    exit 1
fi

# 基本启动测试
echo "进行基本的启动测试..."
docker exec ${DOCKER_CONTAINER_NAME} presto-cli --execute "SHOW CATALOGS;"
docker exec ${DOCKER_CONTAINER_NAME} presto-cli --execute "SHOW SCHEMAS FROM system;"
docker exec ${DOCKER_CONTAINER_NAME} presto-cli --execute "SHOW TABLES FROM system.metadata;"
docker exec ${DOCKER_CONTAINER_NAME} presto-cli --execute "SELECT * FROM system.metadata.catalogs;"

echo "一键安装完成!您可以通过浏览器访问 http://localhost:${HOST_PORT} 来使用 Presto。"

使用说明

  1. 保存脚本

    将上述脚本内容复制并保存为 install_presto.sh 文件。例如,在您的主目录下创建该文件:

    nano install_presto.sh
    

    然后粘贴上述内容并保存。

  2. 赋予执行权限

    chmod +x install_presto.sh
    
  3. 运行脚本

    ./install_presto.sh
    

    脚本将自动执行以下操作:

  4. 检查 Docker 是否已安装。
  5. 创建所需的目录结构。
  6. 生成配置文件 (config.propertiesjvm.config)。
  7. 创建 catalog 目录。
  8. 生成并执行启动脚本 (presto-start.sh) 以启动 Presto 容器。
  9. 进行基本的启动测试,验证 Presto 是否正常运行。
  10. 访问 Presto

    安装完成后,打开浏览器访问 http://localhost:8080 以确认 Presto 已成功启动。

部署 Presto

执行 install_presto.sh 脚本后,Presto 将在 Docker 容器中运行。以下是脚本执行过程的简要说明:

  • 目录结构:所有配置文件和目录将创建在 presto-docker 目录下。
  • 配置文件
  • config.properties:配置 Presto 的基本参数,如协调器设置和端口号。
  • jvm.config:配置 JVM 参数,以优化 Presto 的性能和稳定性。
  • 启动脚本presto-start.sh 将负责启动 Docker 容器,并处理可能存在的同名容器。
  • 基本测试:脚本在启动后会执行一些基本的 Presto CLI 查询,以验证安装是否成功。
  • 通过 Java 连接 Presto

    要通过 Java 连接 Presto,您需要使用 Presto 提供的 JDBC 驱动程序。以下是详细的步骤:

    1. 添加 Presto JDBC 依赖

    如果您使用 Maven 管理项目依赖,可以在 pom.xml 中添加以下依赖:

    <dependency>
        <groupId>io.prestosql</groupId>
        <artifactId>presto-jdbc</artifactId>
        <version>0.269</version> <!-- 请根据实际版本调整 -->
    </dependency>
    

    如果使用 Gradle,则添加以下内容到 build.gradle

    dependencies {
        implementation 'io.prestosql:presto-jdbc:0.269' // 请根据实际版本调整
    }
    

    2. Java 连接代码示例

    以下是一个简单的 Java 程序,用于连接 Presto 并执行查询:

    import java.sql.Connection;
    import java.sql.DriverManager;
    import java.sql.ResultSet;
    import java.sql.Statement;
    
    public class PrestoJavaExample {
        public static void main(String[] args) {
            // Presto 服务器的 URL
            String url = "jdbc:presto://localhost:8080";
            String user = "user"; // 替换为您的 Presto 用户名
    
            try {
                // 加载 Presto JDBC 驱动
                Class.forName("io.prestosql.jdbc.PrestoDriver");
    
                // 建立连接
                Connection connection = DriverManager.getConnection(url, user, null);
                Statement stmt = connection.createStatement();
    
                // 执行查询
                String sql = "SELECT * FROM system.runtime.nodes";
                ResultSet rs = stmt.executeQuery(sql);
    
                // 处理结果
                while (rs.next()) {
                    System.out.println("Node ID: " + rs.getString("node_id"));
                    System.out.println("Host: " + rs.getString("host"));
                    System.out.println("Port: " + rs.getInt("http_uri"));
                    System.out.println("-------------------------------");
                }
    
                // 关闭连接
                rs.close();
                stmt.close();
                connection.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
    

    3. 运行 Java 程序

    确保 Presto 容器正在运行,并执行以下步骤:

    1. 编译 Java 程序

      javac PrestoJavaExample.java
      
    2. 运行 Java 程序

      java PrestoJavaExample
      

      您应该会看到类似以下的输出,显示 Presto 节点的信息:

      Node ID: node1
      Host: localhost
      Port: 8080
      -------------------------------
      

    注意事项

  • 用户认证:如果您的 Presto 配置了用户认证(如账号密码或 Kerberos),需要在连接时提供相应的认证信息。
  • JDBC URL:确保 JDBC URL 中的主机名和端口号正确指向您的 Presto 服务器。
  • 通过 Python 连接 Presto

    要通过 Python 连接 Presto,您可以使用 prestodb 库或 PyHive 库。以下是使用 prestodb 库的示例。

    1. 安装 Presto Python 客户端

    使用 pip 安装 prestodb 库:

    pip install prestodb
    

    2. Python 连接代码示例

    以下是一个简单的 Python 脚本,用于连接 Presto 并执行查询:

    import prestodb
    
    # 连接到 Presto 服务器
    conn = prestodb.dbapi.connect(
        host='localhost',
        port=8080,
        user='user',  # 替换为您的 Presto 用户名
        catalog='system',
        schema='runtime',
    )
    
    cur = conn.cursor()
    
    # 执行查询
    cur.execute('SELECT * FROM nodes')
    
    # 获取并打印结果
    rows = cur.fetchall()
    for row in rows:
        print(f"Node ID: {row[0]}, Host: {row[1]}, HTTP URI: {row[2]}")
    

    3. 运行 Python 脚本

    确保 Presto 容器正在运行,并执行以下步骤:

    1. 保存脚本

      将上述代码保存为 presto_python_example.py

    2. 运行脚本

      python presto_python_example.py
      

      您应该会看到类似以下的输出,显示 Presto 节点的信息:

      Node ID: node1, Host: localhost, HTTP URI: http://localhost:8080
      

    注意事项

  • 用户认证:如果您的 Presto 配置了用户认证,需要在连接时提供相应的认证信息。
  • Catalog 和 Schema:确保在连接时指定正确的 catalogschema
  • 常见问题及解决方案

    1. Docker 镜像拉取失败

    问题描述:运行安装脚本时,Docker 无法拉取 Presto 镜像,提示连接超时。

    解决方案

  • 检查网络连接:确保服务器能够访问互联网,尤其是 Docker Hub。

    ping -c 4 google.com
    
  • 配置代理(如果适用):如果您的网络环境需要代理,配置 Docker 代理设置。

    sudo mkdir -p /etc/systemd/system/docker.service.d
    sudo nano /etc/systemd/system/docker.service.d/http-proxy.conf
    

    添加以下内容(替换为您的代理地址):

    [Service]
    Environment="HTTP_PROXY=http://proxy.example.com:8080/"
    Environment="HTTPS_PROXY=http://proxy.example.com:8080/"
    Environment="NO_PROXY=localhost,127.0.0.1"
    

    然后重启 Docker 服务:

    sudo systemctl daemon-reload
    sudo systemctl restart docker
    
  • 手动拉取镜像:尝试手动拉取 Presto 镜像。

    docker pull prestodb/presto:latest
    
  • 2. 端口被占用

    问题描述:预定的端口(默认 8080)已被其他服务占用,导致 Presto 容器无法启动。

    解决方案

  • 检查端口占用情况

    sudo lsof -i:8080
    
  • 修改安装脚本中的端口:如果端口被占用,可以在 install_presto.sh 中修改 HOST_PORT 变量为其他未使用的端口,如 8081。

    HOST_PORT=8081
    
  • 重新运行脚本

    ./install_presto.sh
    
  • 3. 连接失败

    问题描述:无法通过 Java 或 Python 客户端连接 Presto,提示连接被拒绝或超时。

    解决方案

  • 检查 Presto 容器状态

    docker ps -f name=some-presto
    

    确保容器正在运行。

  • 检查防火墙设置:确保服务器的防火墙未阻止预定的端口。

    sudo ufw allow 8080
    
  • 验证 Presto 服务是否正常:在浏览器中访问 http://localhost:8080,应能看到 Presto 的 Web 界面。

  • 作者:青草珍珠和太阳

    物联沃分享整理
    物联沃-IOTWORD物联网 » 一键部署 Presto 基于 Docker 及 Java 和 Python 客户端连接指南

    发表回复