天天看點

Presto-gateway 講解與實戰操作

一、概述

Presto是一個Facebook開源的分布式SQL查詢引擎,适用于互動式分析查詢,資料量支援GB到PB位元組。客戶在使用Presto的時候發現單個叢集不能滿足業務需求,而建立多個Presto叢集之後,如何在叢集間排程任務就成為一個問題。在Presto中,一個Query執行周期内需要用戶端和服務端進行多次的HTTP請求,在多叢集模式下,如何保證同一個Query的請求都分發到同一個叢集呢?

Lyft為解決這個問題而開發了presto-gateway這個工具,并将它開源出來。(https://github.com/lyft/presto-gateway)

Presto-gateway 是在多個Presto叢集前的一個有狀态Load-balancer,Proxy和Router,它提供了透明的通路方法。如下圖:(内容來自于https://eng.lyft.com/presto-infrastructure-at-lyft-b10adb9db01)

Presto-gateway 講解與實戰操作

pinterest 架構:

Presto-gateway 講解與實戰操作

參考資料:

  • Lyft 資料:https://eng.lyft.com/presto-infrastructure-at-lyft-b10adb9db01
  • pinterest 資料:https://medium.com/pinterest-engineering/presto-at-pinterest-a8bda7515e52
【溫馨提示】如需擷取文章中使用到的鏡像和部署包,可關注我的公衆号【大資料與雲原生技術分享】回複【pgw】即可擷取。如上面兩個連結打不開,則需要借助”梯子“安全上網,”梯子“在公衆号上也有推薦哦,回複【ai】即可擷取推薦。

二、部署 mysql

Presto-gateway 使用 MySQL 來記錄後端Presto叢集和查詢曆史,是以我們需要先準備一台MySQL伺服器,自建或者托管的RDS均可。這裡使用mysql on k8s快速部署,不清楚的可以參考我這篇文章:【雲原生】MySQL on k8s 環境部署

# 1、下載下傳安裝包,注意修改鏡像位址
git clone https://gitee.com/hadoop-bigdata/mysql-on-k8s.git

# 2、先準備好鏡像
docker pull docker.io/bitnami/mysql:8.0.30-debian-11-r15
docker tag docker.io/bitnami/mysql:8.0.30-debian-11-r15 myharbor.com/bigdata/mysql:8.0.30-debian-11-r15
# mysqld-exporter
docker pull docker.io/bitnami/mysqld-exporter:0.14.0-debian-11-r33
docker tag docker.io/bitnami/mysqld-exporter:0.14.0-debian-11-r33 myharbor.com/bigdata/mysqld-exporter:0.14.0-debian-11-r33

# 3、安裝helm
wget https://get.helm.sh/helm-v3.9.4-linux-amd64.tar.gz
tar -xf helm-v3.9.4-linux-amd64.tar.gz
ln -s /opt/helm/linux-amd64/helm /usr/local/bin/helm

# 4、建立挂載目錄,可以修改chat包裡配置檔案修改路徑
mkdir -p /opt/bigdata/servers/mysql/data/data1

# 5、安裝mysql
helm install mysql ./mysql-on-k8s -n mysql --create-namespace


# 5、解除安裝(不執行)
helm uninstall mysql -n mysql 
kubectl delete pod -n mysql `kubectl get pod -n mysql |awk 'NR>1{print $1}'` --force
kubectl patch ns mysql -p '{"metadata":{"finalizers":null}}'
kubectl delete ns mysql --force           

建立 presto-gateway 庫

# 擷取mysql root密碼,一般企業裡使用非root使用者給應用使用。這裡為了友善,就直接用root了。
MYSQL_ROOT_PASSWORD=$(kubectl get secret --namespace mysql mysql -o jsonpath="{.data.mysql-root-password}" | base64 -d)

# 登入mysql
kubectl exec -it mysql-primary-0 -n mysql -- mysql -h mysql-primary.mysql.svc.cluster.local -uroot -p"$MYSQL_ROOT_PASSWORD"           

三、部署多套 presto 叢集

這裡部署也部署在k8s上,有不清楚的可以參考我之前的文章:【雲原生】Presto/Trino on k8s 環境部署

trino 官網:https://trino.io/docs/current/installation/kubernetes.html

# 安裝
#helm install trino ./presto-on-k8s -n presto --create-namespace
# 更新
#helm upgrade trino ./presto -n presto

# 也可以通過官方提供的chat部署,如下:
# docker pull trinodb/trino:latest,當然最新版本410,可能下載下傳會很慢,關注我公衆号【大資料與雲原生技術分享】可擷取離線鏡像包。
helm repo add trino https://trinodb.github.io/charts
# 下載下傳離線包
docker pull trino/trino && tar -xf trino-0.10.0.tgz
helm install trino001 ./trino -n trino001 --create-namespace --set service.type=NodePort
helm install trino002 ./trino -n trino002 --create-namespace --set service.type=NodePort

# 解除安裝
helm uninstall trino001  -n trino001
helm uninstall trino002  -n trino002
           

NOTES

[root@local-168-182-110 presto-gateway]# helm install trino001 ./trino -n trino001 --create-namespace --set service.type=NodePort
NAME: trino001
LAST DEPLOYED: Sun Mar 19 10:09:46 2023
NAMESPACE: trino001
STATUS: deployed
REVISION: 1
TEST SUITE: None
NOTES:
Get the application URL by running these commands:
  export NODE_PORT=$(kubectl get --namespace trino001 -o jsonpath="{.spec.ports[0].nodePort}" services trino001)
  export NODE_IP=$(kubectl get nodes --namespace trino001 -o jsonpath="{.items[0].status.addresses[0].address}")
  echo http://$NODE_IP:$NODE_PORT
[root@local-168-182-110 presto-gateway]# helm install trino002 ./trino -n trino002 --create-namespace --set service.type=NodePort
NAME: trino002
LAST DEPLOYED: Sun Mar 19 10:10:08 2023
NAMESPACE: trino002
STATUS: deployed
REVISION: 1
TEST SUITE: None
NOTES:
Get the application URL by running these commands:
  export NODE_PORT=$(kubectl get --namespace trino002 -o jsonpath="{.spec.ports[0].nodePort}" services trino002)
  export NODE_IP=$(kubectl get nodes --namespace trino002 -o jsonpath="{.items[0].status.addresses[0].address}")
  echo http://$NODE_IP:$NODE_PORT
[root@local-168-182-110 presto-gateway]#
           
Presto-gateway 講解與實戰操作

檢視

kubectl get pods -A
helm get notes trino001 -n trino001
helm get notes trino002 -n trino002

export NODE_PORT=$(kubectl get --namespace trino001 -o jsonpath="{.spec.ports[0].nodePort}" services trino001)
  export NODE_IP=$(kubectl get nodes --namespace trino001 -o jsonpath="{.items[0].status.addresses[0].address}")

https://$NODE_IP:$NODE_PORT           
Presto-gateway 講解與實戰操作
Presto-gateway 講解與實戰操作

四、部署 presto-gateway 與簡單使用

1)下載下傳

git clone https://github.com/lyft/presto-gateway.git           

2)Maven 編譯

# 安裝maven
wget https://dlcdn.apache.org/maven/maven-3/3.9.1/binaries/apache-maven-3.9.1-bin.tar.gz --no-check-certificate
tar -zvxf apache-maven-3.9.1-bin.tar.gz
ln -s `pwd`/apache-maven-3.9.1/bin/mvn /sbin/mvn

# 安裝jdk
tar -xf jdk-8u212-linux-x64.tar.gz

# /etc/profile檔案中追加如下内容:
echo "export JAVA_HOME=`pwd`/jdk1.8.0_212" >> /etc/profile
echo "export PATH=\$JAVA_HOME/bin:$PATH" >> /etc/profile
echo "export CLASSPATH=.:\$JAVA_HOME/lib/dt.jar:\$JAVA_HOME/lib/tools.jar" >> /etc/profile
# 加載生效
source /etc/profile

# 開始編譯
cd presto-gateway
mvn clean install           

3)修改配置

先更改 gateway-ha 目錄下配置檔案 gateway-ha-config.yml,先查詢mysql資訊,登入mysql建立資料庫

# 擷取對外端口
kubectl get svc -n mysql

# 擷取mysql root密碼
MYSQL_ROOT_PASSWORD=$(kubectl get secret --namespace mysql mysql -o jsonpath="{.data.mysql-root-password}" | base64 -d)
echo $MYSQL_ROOT_PASSWORD

# 登入mysql
mysql -h 192.168.182.110 -P30306 -uroot -p"$MYSQL_ROOT_PASSWORD"
# 建立庫
create database prestogateway;
# 檢視
show databases;           
Presto-gateway 講解與實戰操作

修改配置 gateway-ha/gateway-ha-config.yml

dataStore:
  jdbcUrl: jdbc:mysql://192.168.182.110:30306/prestogateway
  user: root
  password: wQKFKLi6By
  driver: com.mysql.cj.jdbc.Driver
           

4)sql 初始化

# 擷取mysql root密碼
MYSQL_ROOT_PASSWORD=$(kubectl get secret --namespace mysql mysql -o jsonpath="{.data.mysql-root-password}" | base64 -d)

# 登入mysql
mysql -h 192.168.182.110 -P30306 -uroot -p"$MYSQL_ROOT_PASSWORD"

use prestogateway;

source ./gateway-ha/target/classes/gateway-ha-persistence.sql;           

5)啟動服務

# check檢查配置
java -jar ./gateway-ha/target/gateway-ha-1.9.5-jar-with-dependencies.jar check ./gateway-ha/gateway-ha-config.yml
# 啟動服務
nohup java -jar ./gateway-ha/target/gateway-ha-1.9.5-jar-with-dependencies.jar server ./gateway-ha/gateway-ha-config.yml &
           

web 通路:http://<server-ip>:8090/entity

Presto-gateway 講解與實戰操作

6)增加和修改presto叢集

可以通過兩種方式來将Presto叢集添加進來,如果名字相同,則可以更新現有資訊。

1、通過CURL指令

擷取presto對我端口

kubectl get svc -n trino001
kubectl get svc -n trino002

# 預設排程(routingGroup=adhoc)
curl -X POST http://localhost:8080/entity?entityType=GATEWAY_BACKEND \
 -d '{  "name": "adhoc001", 
        "proxyTo": "http://192.168.182.110:30792",
        "active": true, 
        "routingGroup": "adhoc" 
    }'
curl -X POST http://localhost:8080/entity?entityType=GATEWAY_BACKEND \
 -d '{  "name": "adhoc002", 
        "proxyTo": "http://192.168.182.110:31258",
        "active": true, 
        "routingGroup": "adhoc" 
    }'

# 配置presto1,presto2
curl -X POST http://localhost:8080/entity?entityType=GATEWAY_BACKEND \
 -d '{  "name": "presto1", 
        "proxyTo": "http://192.168.182.110:30792",
        "active": true, 
        "routingGroup": "presto1" 
    }'

curl -X POST http://localhost:8080/entity?entityType=GATEWAY_BACKEND \
 -d '{  "name": "presto2", 
        "proxyTo": "http://192.168.182.110:31258",
        "active": true, 
        "routingGroup": "presto2" 
    }'
           
Presto-gateway 講解與實戰操作

2、通過Web UI

位址:http://<server-ip>:8090/entity

Presto-gateway 講解與實戰操作

7)presto叢集清單

curl -X GET http://localhost:8080/gateway/backend/active | python -m json.tool           
Presto-gateway 講解與實戰操作

8)上線和下線presto叢集

# 下線
curl -X POST http://localhost:8080/gateway/backend/deactivate/presto2

# 上線
curl -X POST http://localhost:8080/gateway/backend/activate/presto2           

9)删除presto叢集

curl -X POST http://localhost:8080/gateway/backend/deactivate/presto1           

10)路由規則

Presto-gateway提供了使用者可以自定義路由規則的功能來重定向請求到不同叢集,這個規則可以通過修改配置檔案(gateway-ha/gateway-ha-config.yml)來設定。

routingRules:
  rulesEngineEnabled: true
  rulesConfigPath:"src/test/resources/rules/routing_rules.yml" # replace with path toyour rules config file           
  • 預設情況下(預設rulesEngineEnabled是false),presto-gateway讀取X-Trino-Routing-Group請求頭來路由請求。如果沒有指定這個報頭,請求被發送到預設路由組(adhoc)。
  • 路由規則引擎根據請求資訊(如任何請求頭)編寫自定義邏輯來路由請求。路由規則與presto-gateway應用程式代碼分離到配置檔案中,允許動态更改規則。

1、定義路由規則

為了更好的觸發路由規則,我們使用了easy-rules(https://github.com/j-easy/easy-rules/wiki/defining-rules#composite-rules) 引擎。這些規則應該存儲在YAML檔案中。規則由name、description、condition和actions(操作清單)組成。如果特定規則的條件計算結果為true,則觸發其動作。配置檔案:src/test/resources/rules/routing_rules.yml

---
name: "presto1"
description: "if query from airflow, route to etl group"
priority: 0
condition: "request.getHeader(\"X-Trino-Source\") == \"presto1\""
actions:
  - "result.put(\"routingGroup\", \"presto1\")"
---
name: "presto2"
description: "if query from airflow with special label, route to etl-special group"

priority: 1
condition: "request.getHeader(\"X-Trino-Source\") == \"presto2\""
actions:
  - "result.put(\"routingGroup\", \"presto2\")"           
【注意】請求頭可以通過 HttpServletRequest 或者 nginx轉發設定。每個規則必須至少有一個action,表示前面的condition滿足後,要執行的步驟。例如上面的cetus_adhoc_search,定義表明如果請求來源于cetus,就轉發路由給adhoc presto叢集組處理。

優先級(priority):整數越低,優先級越高。如果不指定優先級,則預設為INT_MAX。

五、測試驗證

1)下載下傳 presto 用戶端

# cli 用戶端
wget https://repo1.maven.org/maven2/io/trino/trino-cli/410/trino-cli-410-executable.jar
chmod +x trino-cli-410-executable.jar

# jdbc用戶端
wget https://repo1.maven.org/maven2/io/trino/trino-jdbc/410/trino-jdbc-410.jar
chmod +x trino-jdbc-410.jar           

2)示例示範

1、通過CLI用戶端通路presto-gateway

通過presto-gateway去查詢presto叢集資訊

Presto-gateway 講解與實戰操作
# https://gatewayhost:8080
./trino-cli-410-executable.jar --server http://192.168.182.110:8080  --user=admin --execute "select * from system.runtime.nodes;"           
Presto-gateway 講解與實戰操作
Presto-gateway 講解與實戰操作

2、通過上下線來切換調用的叢集

# 下線
curl -X POST http://localhost:8080/gateway/backend/deactivate/presto1

# 上線
curl -X POST http://localhost:8080/gateway/backend/activate/presto1           

當然也可以通過添加header的方式進行定點調用。

【注意】如果未指定路由規則,則預設排程到adhoc,如果adhoc對應多個presto叢集,則會負載均衡,多個叢集會輪詢調用。

Presto-gateway 講解與實戰操作就先到這裡了,有任何疑問歡迎給我留言哦,後續會持續更新相關技術文章,有任何疑問歡迎留言或私信,也可以關注我的公衆号【大資料與雲原生技術分享】深入技術交流或私信咨詢問題~

繼續閱讀