💡 本系列文章是 DolphinScheduler 由淺入深的教程,涵蓋搭建、二開迭代、核心原理解讀、運維和管理等一系列內容。適用於想對 DolphinScheduler瞭解或想要加深理解的讀者。
推薦閱讀:
-
海豚排程監控:使用圖關係解決核心鏈路告警問題,減輕任務運維負擔,使用者五星好評!
-
海豚排程異常處理 | 使用 arthas 在記憶體中刪除啟動失敗的工作流,無需修改程式碼!
-
海豚排程監控:新增依賴缺失巡檢,上游改動再也不用擔心了!
祝開卷有益 😃
大家好,我是小陶,今天是清理排程資料的第二篇文章,之前分享過如何使用API清理工作流例項和任務例項,可以看這篇文章:海豚排程清理:使用 API 輕鬆清理歷史工作流例項以及日誌檔案
我們知道 DolphinScheduler 的工作流是有版本控制的,每一次更新任務、新增任務、修改任務等等操作,都會生成一個新的版本號,同時 process_definition_log 和 process_task_relation_log 的資料也會增加,久而久之,會積累大量的"無用資料",MySQL 的記錄越來越多,會影響排程的服務,進而影響使用者使用體驗和 MySQL 服務。
來看一個例子,往下看。👇👇👇
如下圖所示,該工作流隨著迭代,已經積累了 600 多個版本,我們用了這麼長時間的排程,沒有發生過需要切換歷史版本的情況,歷史的版本資料基本都算做“無用”資料了,同時為了保持穩定性,和數倉同學協商,只保留最近 20 個版本
。
所以,需要清理以上歷史版本記錄,保證頁面影響速度和 MySQL 服務。
清理排程任務歷史版本記錄,依然是使用API的方式,直接運算元據庫風險比較高。
本文的內容也比較簡單,先是說明 API 的邏輯,最後再介紹如何使用一個 Python 指令碼來呼叫 API 刪除歷史版本記錄。
1.API 邏輯介紹
DolphinScheduler 本身提供了刪除版本記錄的介面,請求型別:DELETE,介面地址:process-definition/{dag_code}/versions/{version} ,介面邏輯比較簡單,這裡就不贅述了。
2.使用 Python 指令碼呼叫API
Python指令碼的邏輯比較簡單,使用了4個API,按照順序是:
1.獲取專案列表
2.獲取工作流列表
3.獲取當前工作流版本資訊列表
4.刪除歷史版本
第三步,需要注意的是,獲取版本資訊列表的時候,指定了分頁大小是 20 ,從第二頁開始。因為我們要保留最近的 20 個版本記錄。
入參:無
Python 環境 2.7
具體的程式碼如下:
#!/usr/bin/python
# -*- coding: utf8 -*-
## 清理排程任務歷史版本記錄,依然是使用API的方式,直接運算元據庫風險比較高。
## 會減少 process_definition_log 和 process_task_relation_log 的資料。
import io
import subprocess
import requests
import json
import time
import datetime
# 配置資訊: ip 埠 token自行修改
base_url = 'http://xxxx:xxxx'
token = 'xxxxx'
# 獲取專案列表
def get_project_list():
url = "{base_url}/dolphinscheduler/projects?pageSize=100&pageNo=1&searchVal=&_t=0.3741042528841678".format(base_url=base_url)
payload={}
headers = {
'Connection': 'keep-alive',
'Accept': 'application/json, text/plain, */*',
'language': 'zh_CN',
'sessionId': '680b2a0e-624c-4804-9e9e-58c7d4a0b44c',
'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/99.0.4844.51 Safari/537.36',
'Referer': "{base_url}/dolphinscheduler/ui/".format(base_url=base_url),
'Accept-Language': 'zh-CN,zh;q=0.9,pt;q=0.8,en;q=0.7',
'token':token
}
response = requests.request("GET", url, headers=headers, data=payload)
response_data = json.loads(response.text)
totalList = response_data['data']['totalList']
return totalList
# 獲取工作定義列表
def get_definition_detail(project_code):
payload={}
headers = {
'Connection': 'keep-alive',
'Accept': 'application/json, text/plain, */*',
'language': 'zh_CN',
'sessionId': '680b2a0e-624c-4804-9e9e-58c7d4a0b44c',
'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/99.0.4844.51 Safari/537.36',
'Referer': "{base_url}/dolphinscheduler/ui/".format(base_url=base_url),
'Accept-Language': 'zh-CN,zh;q=0.9,pt;q=0.8,en;q=0.7',
'token':token
}
all_data = []
pageNo = 1
while True:
url = "{base_url}/dolphinscheduler/projects/{project_code}/process-definition?searchVal=&pageSize=50&pageNo={pageNo}".format(project_code=project_code,pageNo=pageNo,base_url=base_url)
response = requests.request("GET", url, headers=headers, data=payload)
response_data = json.loads(response.text)
page_data = response_data['data']['totalList']
totalPage = response_data['data']['totalPage']
if len(page_data) == 0:
print('工作定義列表為空,退出迴圈...')
break
all_data.extend(page_data)
if pageNo >= totalPage:
print('工作定義列表到頭了,退出迴圈...')
break
pageNo += 1
# 返回全部資料
return all_data
# 獲取工作定義的版本資訊列表,注意,這裡從第二頁開始!!!size是 20
def get_version_detail(project_code,dag_code,current_version):
payload={}
headers = {
'Connection': 'keep-alive',
'Accept': 'application/json, text/plain, */*',
'language': 'zh_CN',
'sessionId': '680b2a0e-624c-4804-9e9e-58c7d4a0b44c',
'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/99.0.4844.51 Safari/537.36',
'Referer': "{base_url}/dolphinscheduler/ui/".format(base_url=base_url),
'Accept-Language': 'zh-CN,zh;q=0.9,pt;q=0.8,en;q=0.7',
'token':token
}
all_version = []
pageNo = 2
while True:
if pageNo <= 1:
print('獲取工作定義的版本資訊列表,pageNo 必須大於1!!!')
break
url = "{base_url}/dolphinscheduler/projects/{project_code}/process-definition/{dag_code}/versions?searchVal=&pageSize=20&pageNo={pageNo}".format(project_code=project_code,dag_code=dag_code,pageNo=pageNo,base_url=base_url)
response = requests.request("GET", url, headers=headers, data=payload)
response_data = json.loads(response.text)
page_data = response_data['data']['totalList']
totalPage = response_data['data']['totalPage']
if len(page_data) == 0:
print('version列表為空,退出迴圈...')
break
for page in page_data:
version = int(page['version'])
# 保留近20個版本
if version + 20 <= current_version:
all_version.append(version)
if pageNo >= totalPage:
print('version列表到頭了,退出迴圈...')
break
pageNo += 1
# TODO 分析all_data裡面是否包含 current_version
# 返回正常的資料
return all_version
def delete(project_code,dag_code,version):
print('即將刪除的專案,工作流以及版本')
print(project_code)
print(dag_code)
print(version)
url = "{base_url}/dolphinscheduler/projects/{project_code}/process-definition/{dag_code}/versions/{version}".format(project_code=project_code,dag_code=dag_code,version=version,base_url=base_url)
# 'processInstanceIds=89767'
payload={}
headers = {
'Connection': 'keep-alive',
'Accept': 'application/json, text/plain, */*',
'language': 'zh_CN',
'sessionId': '680b2a0e-624c-4804-9e9e-58c7d4a0b44c',
'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/99.0.4844.51 Safari/537.36',
'Content-Type': 'application/x-www-form-urlencoded',
'Origin': 'http://10.1.19.150:7080',
'Referer': 'http://10.1.19.150:7080/dolphinscheduler/ui/',
'Accept-Language': 'zh-CN,zh;q=0.9,pt;q=0.8,en;q=0.7',
'token':token,
'Cookie': 'sessionId=680b2a0e-624c-4804-9e9e-58c7d4a0b44c; language=zh_CN; userName=admin; HERA_Token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzc29JZCI6Ii0xIiwic3NvX25hbWUiOiJhZG1pbiIsImF1ZCI6IjJkZmlyZSIsImlzcyI6ImhlcmEiLCJleHAiOjE2NDYwMjk3MDYsInVzZXJJZCI6IjEiLCJpYXQiOjE2NDU3NzA1MDYsInVzZXJuYW1lIjoiYWRtaW4ifQ.YEhr9Mi7FDsQIAn5GJorB0U3lL92KQA8YvP26QMhh9g; sessionId=680b2a0e-624c-4804-9e9e-58c7d4a0b44c'
}
response = requests.request("DELETE", url, headers=headers, data=payload)
print('執行結果如下:')
print(response.text)
if __name__ == '__main__':
# # 需要處理的專案
projects = get_project_list()
# 依次處理專案
for project in projects:
project_code = project['code']
print('正在處理專案:'+ str(project_code))
all_dags = get_definition_detail(project_code)
for dag in all_dags:
# 工作流code和當前版本
dag_code = dag['code']
current_version = dag['version']
print(dag_code)
print(current_version)
# 獲取該工作流歷史版本記錄...
all_data = get_version_detail(project_code,dag_code,current_version)
# TODO 刪除
print(all_data)
for v in all_data:
delete(project_code,dag_code,v)
使用示例:dolphin_clean_version.py 是上面的指令碼。
python dolphin_clean_version.py
指令碼在 GitHub 也維護了一份,歡迎 star
https://github.com/aikuyun/dolphin_practices/blob/main/dolphin_clean_version.py
3.注意事項
1.token 獲取的方式
以上就使用 API 一鍵減少關係日誌表和任務定義日誌表的資料量的過程,如果有任何疑問,都可以與我交流,希望可以幫到你,下次見。
本文由 白鯨開源 提供釋出支援!