前言
在Redash二次開發上做了不少工作,修改bug,定製樣式,定製功能,增加數據源等等。聊聊自己的二次開發經驗。
懂分享的人,一定會快樂!
環境準備
Redash依賴的外部環境比較多,特別是Python相關的包,大多數時候一次裝不成功,需要單獨裝或者更新安裝其他系統依賴庫,祝大家一次成功!
環境準備可以參考另一篇blog,沒用全說,其餘的自己動動腦筋比較好。
附傳送門:Redash開發指南
系統架構介紹
總的來說,Redash分爲2部分:前端展示,後端數據庫連接查詢。在這中間,Redash採用celery進行任務調度,滿足大量用戶查詢。
接下來會從三個方面進行總結:
- 總體結構
- 前端邏輯
- 後端邏輯
總體結構
Redash在應用層、前後端均帶有自己的核心模塊。總而言之,當用戶在使用Query、Dashboard、Alert功能時,會由前端提供基礎的展示,
再把用戶的請求通過JS和後端的Server層交互。用戶所有的請求會放在任務隊列中,對於需要查詢的任務,則會去找對應的數據查詢引擎。
前端邏輯
前端主要是控制頁面元素和CSS樣式,提供可視化組件和基本的功能。所有與後端交互的部分由JS業務邏輯控制,實現數據傳輸與功能跳轉。
後端邏輯
後端的大部分功能依賴Celery進行完成,使用Redis做消息中間件。在任務隊列中,大多數任務互相獨立,進行數據查詢時,worker起到主要作用。
Redash的一個特色是連接了28種以上的數據源,所以自帶的數據查詢引擎模塊融合了這些數據庫(引擎)的Python調用接口,十分豐富。
代碼結構介紹
Redash的模塊化做的非常好,基本上可以通過目錄和文件名分析出代碼的功能定位。嗯,看過的都說好,改過的都說爽。
一圖其實可以省略很多字。實在不明白,歡迎留言評論,加小密圈哈。
案例上手
Redash有一個潛在的性能問題:Hive獲取幾萬張表的schema信息時,促使celery worker任務隊列堵塞,資源響應過慢。
所以,就以這個問題來看看源碼修改。
問題分析:Reash採用desc命令獲取hive table schema信息(db名,table列名),每張表執行一次desc,速度過慢。
解決方案:直接通過hive metadata獲取,即,從mysql database中獲取schema信息。(不懂hive的metadata爲啥用mysql的,可以去查查)
準備查詢mysql的SQL代碼:
# 獲取DB名
db_sql = "select name as db from DBS"
# 獲取table名
db_list = ['xx1', 'xx2']
for db in db_list:
tabel_sql = "select tbl_name as table_name from DBS as db inner join TBLS as tbl on db.db_id = tbl.db_id where db.name = '{}'".format(db[0])
# 獲取column名
table_list = ['t1', 't2']
for table in table_list:
sql = "select * from ( "
sql += "select col.column_name, col.type_name as column_type from DBS as db inner join TBLS as tbl on db.db_id = tbl.db_id inner join SDS as sds on tbl.sd_id = sds.sd_id inner join COLUMNS_V2 as col on sds.cd_id = col.cd_id"
sql += " where db.name = '{}' and tbl_name = '{}'".format(db[0], table[0])
sql += " union all "
sql += "select pt.PKEY_NAME as column_name, pt.PKEY_TYPE as column_type from DBS as db inner join TBLS as tbl on db.db_id = tbl.db_id left join PARTITION_KEYS as pt on tbl.tbl_id = pt.tbl_id"
sql += " where db.name = '{}' and tbl_name = '{}'".format(db[0], table[0])
sql += " ) as t where t.column_name is not null"
前端添加hive數據源連接串的地方,增加mysql配置信息:
# 修改前端配置
def configuration_schema(cls):
return {
"type": "object",
"properties": {
"host": {
"type": "string"
},
"port": {
"type": "number"
},
"database": {
"type": "string"
},
"username": {
"type": "string"
},
"mysql_host": {
"type": "string",
},
"mysql_port": {
"type": "number",
"default": 3306
},
"mysql_database": {
"type": "string",
"default": "hive_test"
},
"mysql_username": {
"type": "string",
"default": "root"
},
"passwd": {
"type": "string",
"title": "Mysql Password"
}
},
"order": ["host", "port", "database", "username", "mysql_host", "mysql_port", "mysql_database", "mysql_username", "passwd"],
"required": ["host", "mysql_host", "mysql_port", "mysql_database", "mysql_username", "passwd"],
'secret': ['passwd']
}
修改獲取schema信息的處理函數_get_table(self, schema), 將其改爲通過配置拿mysql連接串,聯繫上述SQL邏輯,獲取schema信息即可。此處不做演示了。
結語
以上,算是筆者總結的二次開發入門資料吧。如有問題,歡迎加入小圈子,一起交流!