部署 Presto

安裝 Presto

下載 Presto 伺服器 tarball,presto-server-0.289.tar.gz,並將其解壓縮。 tarball 將包含單個頂層目錄 presto-server-0.289,我們將其稱為安裝目錄。

Presto 需要一個資料目錄來儲存記錄等。我們建議在安裝目錄之外建立一個資料目錄,這樣可以在升級 Presto 時輕鬆保留它。

設定 Presto

在安裝目錄內建立一個 etc 目錄。這將保存以下設定

  • 節點屬性:特定於每個節點的環境設定

  • JVM 設定:Java 虛擬機的命令列選項

  • 組態屬性:Presto 伺服器的組態。有關可用的組態屬性,請參閱屬性參考

  • 目錄屬性:連接器(資料來源)的組態。連接器的可用目錄組態屬性在各個連接器文件中說明。

節點屬性

節點屬性檔案 etc/node.properties 包含特定於每個節點的組態。節點是機器上 Presto 的單個已安裝執行個體。此檔案通常在首次安裝 Presto 時由部署系統建立。以下是一個最小的 etc/node.properties

node.environment=production
node.id=ffffffff-ffff-ffff-ffff-ffffffffffff
node.data-dir=/var/presto/data

上述屬性說明如下

  • node.environment:環境的名稱。叢集中的所有 Presto 節點都必須具有相同的環境名稱。

  • node.id:此 Presto 安裝的唯一識別碼。每個節點都必須是唯一的。此識別碼應在 Presto 的重新啟動或升級中保持一致。如果在單一機器上執行 Presto 的多個安裝(也就是說,在同一機器上的多個節點),則每個安裝都必須具有唯一的識別碼。

  • node.data-dir:資料目錄的位置(檔案系統路徑)。 Presto 會在此處儲存記錄和其他資料。

JVM 設定

JVM 設定檔案 etc/jvm.config 包含用於啟動 Java 虛擬機的命令列選項清單。檔案的格式是每個選項一行。這些選項不由 Shell 解釋,因此包含空格或其他特殊字元的選項不應加上引號。

以下是建立 etc/jvm.config 的良好起點

-server
-Xmx16G
-XX:+UseG1GC
-XX:G1HeapRegionSize=32M
-XX:+UseGCOverheadLimit
-XX:+ExplicitGCInvokesConcurrent
-XX:+HeapDumpOnOutOfMemoryError
-XX:+ExitOnOutOfMemoryError

因為 OutOfMemoryError 通常會使 JVM 處於不一致的狀態,所以我們會在發生這種情況時寫入堆積傾印(用於偵錯)並強制終止進程。

組態屬性

組態屬性檔案 etc/config.properties 包含 Presto 伺服器的組態。每個 Presto 伺服器都可以充當協調器和工作者,但是將單一機器專用於僅執行協調工作可以在較大的叢集上提供最佳效能。

以下是協調器的最小組態

coordinator=true
node-scheduler.include-coordinator=false
http-server.http.port=8080
query.max-memory=50GB
query.max-memory-per-node=1GB
discovery-server.enabled=true
discovery.uri=http://example.net:8080

這是工作者的最小組態

coordinator=false
http-server.http.port=8080
query.max-memory=50GB
query.max-memory-per-node=1GB
discovery.uri=http://example.net:8080

或者,如果您要設定一個同時充當協調器和工作者的單一機器進行測試,請使用此組態

coordinator=true
node-scheduler.include-coordinator=true
http-server.http.port=8080
query.max-memory=5GB
query.max-memory-per-node=1GB
discovery-server.enabled=true
discovery.uri=http://example.net:8080

如果單一協調器不夠,請使用分散式協調器設定,該設定支援使用以下最小組態的多個協調器

  • 資源 管理員

叢集至少需要一個資源管理員,並且可以將更多資源管理員新增至叢集,每個資源管理員都充當主要資源管理員。

resource-manager=true
resource-manager-enabled=true
coordinator=false
node-scheduler.include-coordinator=false
http-server.http.port=8080
thrift.server.port=8081
query.max-memory=50GB
query.max-memory-per-node=1GB
discovery-server.enabled=true
discovery.uri=http://example.net:8080 (Point to resource manager host/vip)
thrift.server.ssl.enabled=true
  • 協調器

叢集可以具有協調器集區。每個協調器將在叢集中執行查詢的子集。

coordinator=true
node-scheduler.include-coordinator=false
http-server.http.port=8080
query.max-memory=50GB
query.max-memory-per-node=1GB
discovery.uri=http://example.net:8080 (Point to resource manager host/vip)
resource-manager-enabled=true
  • 工作者

叢集可以具有工作者集區。他們會將其訊號脈衝傳送至資源管理員。

coordinator=false
http-server.http.port=8080
query.max-memory=50GB
query.max-memory-per-node=1GB
discovery.uri=http://example.net:8080 (Point to resource manager host/vip)
resource-manager-enabled=true

這些屬性需要一些說明

  • resource manager:匯總來自協調器和工作者的資料,並建構叢集的全域檢視。如需更多詳細資訊,請參閱概念

  • coordinator:允許此 Presto 執行個體充當協調器(接受來自用戶端的查詢並管理查詢執行)。

  • node-scheduler.include-coordinator:允許在協調器上排程工作。對於較大的叢集,由於機器的資源無法用於排程、管理和監控查詢執行的關鍵工作,因此在協調器上處理工作可能會影響查詢效能。

  • http-server.http.port:指定 HTTP 伺服器的連接埠。Presto 使用 HTTP 進行所有通訊,包括內部和外部通訊。

  • query.max-memory:查詢可能使用的分散式記憶體最大量。

  • query.max-memory-per-node:查詢可能在任何一台機器上使用的使用者記憶體最大量。

  • discovery-server.enabled:Presto 使用 Discovery 服務來尋找叢集中的所有節點。每個 Presto 執行個體都會在啟動時向 Discovery 服務註冊自己。為了簡化部署並避免執行其他服務,Presto 協調器可以執行 Discovery 服務的內嵌版本。它與 Presto 共用 HTTP 伺服器,因此使用相同的連接埠。

  • discovery.uri:Discovery 伺服器的 URI。由於我們已在 Presto 協調器中啟用內嵌版本的 Discovery,因此這應該是 Presto 協調器的 URI。請取代 example.net:8080 以符合 Presto 協調器的的主機和連接埠。此 URI 不能以斜線結尾。

以下旗標可以協助調整分散式協調器叢集的資源群組以達到所需的連貫性

  • concurrency-threshold-to-enable-resource-group-refresh (預設值: 1.0)

    如果正在執行的查詢達到設定的限制,請設定協調器等待下一個資源群組更新,然後再允許在任何給定的資源群組上執行更多查詢。

    預設值為 1.0。這表示一旦任何資源群組執行其允許的最大查詢次數,協調器必須等待資源管理員的更新,然後再允許在給定的資源群組上執行新查詢。若要達到更強的連貫性,請將百分比降低至較低的值。

  • resource-group-runtimeinfo-refresh-interval (預設值: 100 毫秒)

    此組態有助於調整協調器從資源管理員定期輪詢叢集層級資源群組使用情況的間隔。

您也可以設定下列屬性

  • jmx.rmiregistry.port:指定 JMX RMI 登錄的連接埠。JMX 用戶端應連線至此連接埠。

  • jmx.rmiserver.port:指定 JMX RMI 伺服器的連接埠。Presto 會匯出許多可用於透過 JMX 監控的指標。

另請參閱資源群組

記錄層級

選用的記錄層級檔案 etc/log.properties 允許設定具名記錄器階層的最小記錄層級。每個記錄器都有一個名稱,通常是使用該記錄器的類別的完整名稱。記錄器具有基於名稱中點的階層(類似 Java 套件)。例如,請考慮以下記錄層級檔案

com.facebook.presto=INFO

這會將 com.facebook.presto.servercom.facebook.presto.hive 的最低日誌層級設為 INFO。預設的最低層級為 INFO。(因此,以上範例實際上不會變更任何設定)共有四個層級:DEBUGINFOWARNERROR

Catalog 屬性

Presto 通過連接器存取資料,這些連接器會掛載在 Catalog 中。連接器提供 Catalog 內的所有綱要和表格。例如,Hive 連接器會將每個 Hive 資料庫映射到一個綱要,因此如果 Hive 連接器掛載為 hive Catalog,且 Hive 在 web 資料庫中包含一個 clicks 表格,則該表格在 Presto 中會以 hive.web.clicks 的方式存取。

Catalog 會透過在 etc/catalog 目錄中建立 Catalog 屬性檔案來註冊。例如,建立 etc/catalog/jmx.properties,其中包含以下內容,以將 jmx 連接器掛載為 jmx Catalog

connector.name=jmx

請參閱連接器以取得有關設定連接器的更多資訊。

執行 Presto

安裝目錄在 bin/launcher 中包含啟動腳本。Presto 可以透過執行以下命令作為守護程序啟動

bin/launcher start

或者,它可以在前景中執行,並將日誌和其他輸出寫入 stdout/stderr(如果使用 daemontools 等監督系統,則應擷取這兩個串流)

bin/launcher run

執行帶有 --help 的啟動器,以查看支援的命令和命令行選項。特別是,--verbose 選項對於偵錯安裝非常有用。

啟動後,您可以在 var/log 中找到日誌檔案

  • launcher.log:此日誌由啟動器建立,並連接到伺服器的 stdout 和 stderr 串流。它將包含在伺服器日誌初始化時發生的一些日誌訊息,以及 JVM 產生的任何錯誤或診斷訊息。

  • server.log:這是 Presto 使用的主要日誌檔案。如果伺服器在初始化期間失敗,它通常會包含相關資訊。它會自動輪換和壓縮。

  • http-request.log:這是 HTTP 請求日誌,其中包含伺服器接收到的每個 HTTP 請求。它會自動輪換和壓縮。

在筆記型電腦上查詢 S3 的範例部署

本節說明如何執行 Presto 連接到單一筆記型電腦上的 Hive MetaStore,以查詢 S3 儲存貯體中的資料。

設定 Hive MetaStore

下載並解壓縮 Hive 的二進位 tarball。例如,下載並解壓縮 apache-hive-<VERSION>-bin.tar.gz

您只需要啟動 Hive Metastore 以服務 Presto Catalog 資訊,例如表格綱要和分割區位置。如果是第一次啟動 Hive Metastore,請準備好對應的組態檔案和環境。同時初始化新的 Metastore

export HIVE_HOME=`pwd`
cp conf/hive-default.xml.template conf/hive-site.xml
mkdir -p hcatalog/var/log/
bin/schematool -dbType derby -initSchema

如果您要存取 AWS S3,請在 conf/hive-env.sh 中附加以下幾行。Hive 需要對應的 jar 才能存取具有 s3a:// 位址的檔案,以及存取 S3 儲存貯體的 AWS 認證(即使它是公開的)。這些 jar 可以在 Hadoop 發行版中找到(例如,在 ${HADOOP_HOME}/share/hadoop/tools/lib/ 下),或從 maven central repository 下載。

export HIVE_AUX_JARS_PATH=/path/to/aws-java-sdk-core-<version>.jar:$/path/to/aws-java-sdk-s3-<version>.jar:/path/to/hadoop-aws-<version>.jar
export AWS_ACCESS_KEY_ID=<Your AWS Access Key>
export AWS_SECRET_ACCESS_KEY=<Your AWS Secret Key>

啟動一個 Hive Metastore,它將在背景中執行並在連接埠 9083 (預設值) 上接聽

hcatalog/sbin/hcat_server.sh start

輸出類似於以下內容

Started metastore server init, testing if initialized correctly...
Metastore initialized successfully on port[9083].

若要驗證 Metastore 是否正在執行,請檢查 hcatalog/var/log/ 中的 Hive Metastore 日誌

設定 Presto

根據 Config Properties 建立組態檔案 etc/config.properties。例如,依照最低組態在您的筆記型電腦上執行 Presto

coordinator=true
node-scheduler.include-coordinator=true
http-server.http.port=8080
discovery-server.enabled=true
discovery.uri=https://127.0.0.1:8080

根據 JVM Config 建立 etc/jvm.config,並根據 Node Properties 建立 etc/node.properties

最後,在 etc/catalog/hive.properties 中設定 Presto Hive 連接器,指向剛啟動的 Hive Metastore 服務。如果 Presto 需要從 S3 讀取輸入檔案,請再次在此處包含 AWS 認證。

connector.name=hive-hadoop2
hive.metastore.uri=thrift://127.0.0.1:9083
hive.s3.aws-access-key=<Your AWS Access Key>
hive.s3.aws-secret-key=<Your AWS Secret Key>

執行 Presto 伺服器

./bin/launcher start

使用 Docker 的範例部署

讓我們看看如何為 Presto 組裝 Docker 映像。我們可以在下面看到啟動並執行 Presto 相對容易。為了示範,此組態是單節點 Presto 安裝,其中排程器會將協調器包含為 Worker。我們將設定一個 Catalog,TPCH

對於 Dockerfile,我們下載 Presto,將本機 etc 目錄中的一些組態檔案複製到映像中,並指定一個執行伺服器的進入點。

FROM openjdk:8-jre

# Presto version will be passed in at build time
ARG PRESTO_VERSION

# Set the URL to download
ARG PRESTO_BIN=https://repo1.maven.org/maven2/com/facebook/presto/presto-server/${PRESTO_VERSION}/presto-server-${PRESTO_VERSION}.tar.gz

# Update the base image OS and install wget and python
RUN apt-get update
RUN apt-get install -y wget python less

# Download Presto and unpack it to /opt/presto
RUN wget --quiet ${PRESTO_BIN}
RUN mkdir -p /opt
RUN tar -xf presto-server-${PRESTO_VERSION}.tar.gz -C /opt
RUN rm presto-server-${PRESTO_VERSION}.tar.gz
RUN ln -s /opt/presto-server-${PRESTO_VERSION} /opt/presto

# Copy configuration files on the host into the image
COPY etc /opt/presto/etc

# Download the Presto CLI and put it in the image
RUN wget --quiet https://repo1.maven.org/maven2/com/facebook/presto/presto-cli/${PRESTO_VERSION}/presto-cli-${PRESTO_VERSION}-executable.jar
RUN mv presto-cli-${PRESTO_VERSION}-executable.jar /usr/local/bin/presto
RUN chmod +x /usr/local/bin/presto

# Specify the entrypoint to start
ENTRYPOINT ./opt/presto/bin/launcher run

etc/ 資料夾中有四個檔案用於設定 Presto,並在 etc/catalog/ 中有一個 Catalog。Catalog 定義連接器的組態,而 Catalog 會以檔案名稱命名(減去 .properties 副檔名)。每個 Presto 安裝可以有多個 Catalog,包括使用相同連接器的多個 Catalog;它們只需要不同的檔案名稱。這些檔案是

etc/
├── catalog
│   └── tpch.properties  # Configures the TPCH connector to generate data
├── config.properties    # Presto instance configuration properties
├── jvm.config           # JVM configuration for the process
├── log.properties       # Logging configuration
└── node.properties      # Node-specific configuration properties

以上說明了 etc 底下的四個檔案(使用 config.properties 的單節點協調器組態)。名為 etc/catalog/tpch.properties 的檔案用於定義 tpch Catalog。每個連接器都有其自己的一組特定於連接器的組態屬性。您可以找到連接器的組態屬性和連接器一起記載。TPCH 連接器沒有特殊的組態,因此我們只會為 Catalog 指定連接器的名稱,也是 tpch

etc/catalog/tpch.properties

connector.name=tpch

現在我們準備好建置我們的 Docker 容器,指定版本,然後啟動 Presto。Presto 的最新版本目前為 0.289。

docker build --build-arg PRESTO_VERSION=<see releases for latest version> . -t prestodb:latest
docker run --name presto prestodb:latest

您會看到一系列日誌,因為 Presto 會啟動,並以 SERVER STARTED 結尾,表示它已準備好接收查詢。我們將使用 Presto CLI 來連線到我們使用另一個終端機視窗放置在映像中的 Presto。

docker exec -it presto presto

我們現在可以針對 tpch Catalog 執行查詢。

presto> SELECT
     ->   l.returnflag,
     ->   l.linestatus,
     ->   sum(l.quantity)                                       AS sum_qty,
     ->   sum(l.extendedprice)                                  AS sum_base_price,
     ->   sum(l.extendedprice * (1 - l.discount))               AS sum_disc_price,
     ->   sum(l.extendedprice * (1 - l.discount) * (1 + l.tax)) AS sum_charge,
     ->   avg(l.quantity)                                       AS avg_qty,
     ->   avg(l.extendedprice)                                  AS avg_price,
     ->   avg(l.discount)                                       AS avg_disc,
     ->   count(*)                                              AS count_order
     -> FROM
     ->   tpch.sf1.lineitem AS l
     -> WHERE
     ->   l.shipdate <= DATE '1998-12-01' - INTERVAL '90' DAY
     -> GROUP BY
     ->   l.returnflag,
     ->   l.linestatus
     -> ORDER BY
     ->   l.returnflag,
     ->   l.linestatus;
 returnflag | linestatus |   sum_qty   |    sum_base_price     |    sum_disc_price     |      sum_charge       |      avg_qty       |     avg_price     |       avg_disc       | count_order
------------+------------+-------------+-----------------------+-----------------------+-----------------------+--------------------+-------------------+----------------------+-------------
 A          | F          | 3.7734107E7 |  5.658655440072982E10 | 5.3758257134869644E10 |  5.590906522282741E10 | 25.522005853257337 | 38273.12973462155 |  0.04998529583846928 |     1478493
 N          | F          |    991417.0 |  1.4875047103800006E9 |  1.4130821680540998E9 |   1.469649223194377E9 | 25.516471920522985 | 38284.46776084832 |  0.05009342667421586 |       38854
 N          | O          |  7.447604E7 | 1.1170172969773982E11 | 1.0611823030760503E11 | 1.1036704387249734E11 |  25.50222676958499 | 38249.11798890821 |   0.0499965860537345 |     2920374
 R          | F          | 3.7719753E7 |   5.65680413808999E10 |  5.374129268460365E10 |  5.588961911983193E10 |  25.50579361269077 | 38250.85462609959 | 0.050009405830198916 |     1478870
(4 rows)

Query 20200625_171123_00000_xqmp4, FINISHED, 1 node
Splits: 56 total, 56 done (100.00%)
0:05 [6M rows, 0B] [1.1M rows/s, 0B/s]