今天為大家介紹一款來自 OpenMLDB 社區的優秀獨立工具 - OpenMLDB SQL Simulator(https://github.com/vagetablechicken/OpenMLDBSQLEmulator) ,可以讓你更加高效方便的開發、調試 OpenMLDB SQL。
為了高效的實現時序特征計算,OpenMLDB SQL 對標準 SQL 做了改進和擴展,因此初學者在使用 OpenMLDB SQL 的時候,經常會碰到語法不熟悉、執行模式混淆等問題。如果直接在 OpenMLDB 上進行開發、調試,由于部署、構建索引、大數據量等問題,經常會浪費大量時間在無關任務上,并且可能無法找到 SQL 本身的錯誤原因。OpenMLDB SQL Emulator 是一個輕量級 OpenMLDB SQL 模擬開發調試工具,可以在脫離 OpenMLDB 集群部署的情況下,進行 SQL 的驗證和調試操作,堪稱 OpenMLDB SQL 的開發調試神器。我們強烈推薦此工具給我們的應用開發人員,可以首先基于此工具快速驗證 SQL 的正確性、可上線性以后,再切換到 OpenMLDB 真實環境上進行部署上線。
安裝和啟動
從項目頁面下載運行包 emulator-1.0.jar
https://github.com/vagetablechicken/OpenMLDBSQLEmulator/releases,使用如下方式啟動(注意當前發布的 1.0 版本對應于 OpenMLDB 0.8.3 的 SQL 語法):
java -jar emulator-1.0.jar
注意,如果想使用 run
命令執行 SQL 來驗證結果,還需要同時下載該頁面下的 toydb_run_engine
,并且存放在系統 /tmp
目錄下。
創建虛擬數據庫和表
啟動后,將直接進入到默認的數據庫 emudb,不需要額外創建數據庫。
- 數據庫不需要被顯式創建,只需要
use <db name>
或建表時指定數據庫名,即可自動創建數據庫。 - 使用命令
addtable
或者t
來創建虛擬表,重復創建同名表就是更新操作,將使用最新的表schema。我們使用簡化的類 SQL 語法管理表,比如下面的例子創建了一個含有兩列的表。
addtable t1 a int, b int64
- 使用命令
showtables
或者st
來查看當前所有的數據庫和表。
驗證 OpenMLDB SQL
OpenMLDB SQL 是否可以上線,在集群中可以使用 DEPLOY
進行上線測試,但是需要管理 DEPLOYMENT 與索引。例如,如果不需要某些測試用的 DEPLOYMENT,需要手動刪除;如果創建了不需要的索引,還需要清理索引。所以,我們建議在 Emulator 中測試驗證,你可以使用val
和valreq
分別進行在線批模式和在線請求模式(即服務部署上線)的 OpenMLDB SQL 驗證。例如,我們測試一個 SQL 是否能被 DEPLOY
上線,使用 valreq
命令:
addtable t1 a int, b int64
valreq select count(*) over w1 from t1 window w1 as (partition by a order by b rows between unbounded preceding and current row);
如果測試不通過,將打印 SQL 編譯錯誤;通過則打印“validate * success”。整個過程在虛擬環境中,無需擔心建表后的資源占用,也沒有任何副作用。只要 valreq 驗證通過的 SQL,則一定能在真實集群中上線。
測試運行 OpenMLDB SQL
OpenMLDB Emulator 也可以返回計算結果,用于測試 SQL 計算是否符合預期。你可以在其中不斷進行計算和上線驗證,直到調試得到最終的上線SQL。該功能可以通過 Emulator 的 run
命令實現。注意,使用run
命令需要額外的 toydb_run_engine 支持,可以使用自帶 toydb 的 emulator 包,或在此頁面下載 https://github.com/vagetablechicken/OpenMLDBSQLEmulator/releases) toydb 程序,并將其直接放入/tmp
中。
假設 Emulator 已有 toydb,測試運行步驟如下:
# step 1, generate a yaml template
gencase
# step 2, modify the yaml file to add table and data
# ...
# step 3, load yaml to get table catalog,
# then using val/valreq sql to validate the sql in emulator
loadcase
valreq <sql>
# step 4, dump the sql, this will rewrite the yaml file
dumpcase <sql># step 5, run sql using toydb
run
運行命令gencase
將會生成一個yaml模版文件,默認創建目錄為是/tmp/emu-case.yaml
。然后,你需要編輯這個 yaml 文件,如下所示。編輯需要注意以下幾點:
- 你必須修改表名,表 schema 及其數據,這些不可在 Emulator 中修改。
- 你可以修改運行 mode,接受 batch 或 request 模式。
- 你可以不填寫 SQL,可以在 Emulator 中通過
dumpcase
寫入文件。常見使用方法是,先validate SQL,SQL通過校驗后dump到case中,再使用run
命令確認 SQL 的計算符合預期。 - 表的 indexs 也無需手動填寫,
dumpcase
時可以根據表 schema 自動生成(indexs 并非特殊的索引,與 SQL 也無關,僅僅是創建表時需要創建至少一個索引)。如果你不使用dumpcase
,那么請手動填寫至少一個索引,索引沒有特別要求。
# call toydb_run_engine to run this yaml file
# you can generate yaml cases for reproduction by emulator dump or by yourself# you can set the global default db
db: emudb
cases:- id: 0desc: describe this case# you can set batch modemode: requestdb: emudb # you can set default db for case, if not set, use the global default dbinputs:- name: t1db: emudb # you can set db for each table, if not set, use the default db(table db > case db > global db)# must set table schema, emulator can't do thiscolumns: ["id int", "pk1 string","col1 int32", "std_ts timestamp"]# gen by emulator, just to init table, not the deployment indexindexs: []# must set the data, emulator can't do thisdata: |1, A, 1, 15901154200002, B, 1, 1590115420000# query: only support single query, to check the result by `expect`sql: |# optional, you can just check the output, or add your expect# expect:# schema: id:int, pk1:string, col1:int, std_ts:timestamp, w1_col1_sum:int, w2_col1_sum:int, w3_col1_sum:int# order: id# data: |# 1, A, 1, 1590115420000, 1, 1, 1# 2, B, 1, 1590115420000, 1, 1, 1
簡單起見,我們不進行修改,直接使用這個模版來演示如何修改運行 case。在 Emulator 中,我們執行loadcase
,這個 case 的表信息將被加載到 Emulator 中,可以通過st/showtables
確認 case 的表加載成功。
emudb> st
emudb={t1=id:int32,pk1:string,col1:int32,std_ts:timestamp}
可以看到表信息已成功加載,我們就可以使用valreq
來確認我們編寫的 SQL 是語法正確且可以上線的。然后,可以對這個 SQL 進行計算測試,使用命令dumpcase
和run
,例如:
valreq select count(*) over w1 from t1 window w1 as (partition by id order by std_ts rows between unbounded preceding and current row);
dumpcase select count(*) over w1 from t1 window w1 as (partition by id order by std_ts rows between unbounded preceding and current row);
run
dumpcase
實際是將 SQL 與默認索引寫入 case 文件中,run
命令運行該 case 文件。所以,如果你足夠熟練,也可以直接修改這個case文件,再在 Emulator 中使用 run
運行它,或直接使用toydb_run_engine --yaml_path=...
來運行。運行后將會得到計算結果用于調試檢查。
更多
OpenMLDB SQL Emulator 還有 genddl 功能,可以幫助用戶根據 SQL 直接生成最佳索引的建表語句,避免冗余索引(目前僅支持單數據庫)。未來將在索引處理上,提供更簡單方便的操作,指導用戶進行索引管理。此外,Emulator 交互使用上,建議多使用?help
和 ?list-all
提示,命令均為小寫,但參數填寫的 SQL 不限制大小寫,與 CLI 一致,SQL作為一個參數也不需要額外的雙引號引用。未來將會增加命令歷史、導出當前環境等功能,方便用戶操作與對接真實 OpenMLDB 集群。
相關閱讀
- OpenMLDB 官網: https://openmldb.ai/
- OpenMLDB GitHub 主頁: https://github.com/4paradigm/OpenMLDB
- OpenMLDB 文檔: https://openmldb.ai/docs/zh/
- OpenMLDB 微信交流群