1. 程式人生 > >Apache Calcite項目簡介

Apache Calcite項目簡介

nec creat UNC addrule lin cdata cas aso ast

文章導讀:

  1. 什麽是Calcite?
  2. Calcite的主要功能?
  3. 如何快速使用Calcite?

什麽是Calcite

Apache Calcite是一個動態數據管理框架,它具備很多典型數據庫管理系統的功能,比如SQL解析、SQL校驗、SQL查詢優化、SQL生成以及數據連接查詢等,但是又省略了一些關鍵的功能,比如Calcite並不存儲相關的元數據和基本數據,不完全包含相關處理數據的算法等。

也正是因為Calcite本身與數據存儲和處理的邏輯無關,所以這讓它成為與多個數據存儲位置(數據源)和多種數據處理引擎之間進行調解的絕佳選擇。

Calcite所做的工作就是將各種SQL語句解析成抽象語法樹(AST Abstract Syntax Tree),並根據一定的規則或成本對AST的算法與關系進行優化,最後推給各個數據處理引擎進行執行。

目前,使用Calcite作為SQL解析與優化引擎的又Hive、Drill、Flink、Phoenix和Storm,Calcite憑借其優秀的解析優化能力,會有越來越多的數據處理引擎采用Calcite作為SQL解析工具。

Calcite 主要功能

Calcite的主要功能我們上面其實已經提到了,主要有以下功能:

SQL解析:通過JavaCC將SQL解析成未經校驗的AST語法樹

SQL校驗:校驗分兩部分,一種為無狀態的校驗,即驗證SQL語句是否符合規範;一種為有狀態的即通過與元數據結合驗證SQL中的Schema、Field、Function是否存在。

SQL查詢優化:對上個步驟的輸出(RelNode)進行優化,得到優化後的物理執行計劃

SQL生成:將物理執行計劃生成為在特定平臺/引擎的可執行程序,如生成符合Mysql or Oracle等不同平臺規則的SQL查詢語句等

數據連接與執行:通過各個執行平臺執行查詢,得到輸出結果。

所以在Calcite中,一條SQL的處理步驟就很清晰了,那麽我們通過Calcite的代碼來實際了解一下:

// 初始化配置
SqlParser.ConfigBuilder configBuilder = SqlParser.configBuilder();
configBuilder.setUnquotedCasing(Casing.UNCHANGED);
//Sql解析:解析Sql語句,通過JavaCC解析成AST語法樹,表現為SqlNode
SqlParser sqlParser = SqlParser.create(sql, configBuilder.build());
SqlNode sqlNode = sqlParser.parseQuery();
//Sql校驗:結合元數據信息驗證Sql是否符合規範
Planner planner = Frameworks.getPlanner(config);
SqlNode node = planner.validate(sqlNode);
//Sql查詢優化:將SqlNode轉換為LogicalPlan,表現為RelNode
RelRoot relRoot = planner.rel(node);
RelNode project = relRoot.project();
//指定優化規則
final HepProgram program = new HepProgramBuilder() 
    .addRuleInstance(SubQueryRemoveRule.PROJECT)
    .addRuleInstance(SubQueryRemoveRule.FILTER)
    .addRuleInstance(SubQueryRemoveRule.JOIN)
    .build();
//生成優化後的RelNode
HepPlanner prePlanner = new HepPlanner(program);
prePlanner.setRoot(project);
RelNode relNode = prePlanner.findBestExp();
//ToDo 執行查詢 

使用Calcite

那麽前面對Calcite進行了簡單的介紹,我們如何使用Calcite呢?Calcite的使用非常簡單,你要做的只是添加數據源即可。我們以Mysql數據源為例,我們通過添加Mysql數據庫作為Calcite的數據源,實現通過Calcite對Mysql數據進行查詢的Demo。

//初始化calcite connection
Class.forName("org.apache.calcite.jdbc.Driver");
Properties info = new Properties();
info.setProperty("lex", "JAVA");
Connection connection =
    DriverManager.getConnection("jdbc:calcite:", info);
CalciteConnection calciteConnection =
    connection.unwrap(CalciteConnection.class);
//添加mysql數據庫作為數據源
SchemaPlus rootSchema = calciteConnection.getRootSchema();
Class.forName("com.mysql.jdbc.Driver");
BasicDataSource dataSource = new BasicDataSource();
dataSource.setUrl("jdbc:mysql://localhost");
dataSource.setUsername("username");
dataSource.setPassword("password");
Schema schema = JdbcSchema.create(rootSchema, "hr", dataSource,
    null, "name");
rootSchema.add("hr", schema);
//執行查詢
Statement statement = calciteConnection.createStatement();
ResultSet resultSet = statement.executeQuery(
    "select d.deptno, min(e.empid)\n"
    + "from hr.emps as e\n"
    + "join hr.depts as d\n"
    + "  on e.deptno = d.deptno\n"
    + "group by d.deptno\n"
    + "having count(*) > 1");
print(resultSet);
resultSet.close();
statement.close();
connection.close();

Calcite提供了多種方式添加數據源,如通過“inline:”的字符串方式以及通過json或yaml文件的方式。同時,Calcite抽象出了功能齊全的接口,可以方便的將CSV文件抽象成數據表進行查詢。這部分內容可以通過官方的示例了解一下!

當然SQL解析、校驗與執行計劃優化是Calcite的基本功能,Calcite的NB之處在於,Calcite的目標是“one size fits all”,希望能為不同的計算平臺和數據源提供統一的查詢引擎,並且以類似傳統數據庫的訪問方式(SQL)來訪問Hadoop上的數據。所以Calcite提供了非常豐富的可擴展接口,幫助我們實現擴展數據源、擴展針對不同數據源的優化規則、擴展SQL查詢語法、擴展數據處理引擎等等。這部分後面會詳細介紹(挖坑ing)

參考資料:
https://calcite.apache.org/docs/tutorial.html
https://www.infoq.cn/article/new-big-data-hadoop-query-engine-apache-calcite

好久不更新了

Apache Calcite項目簡介