Apache Kylin的自定义函数实现
来源:互联网 发布:java高级工程师好考吗 编辑:程序博客网 时间:2024/05/20 06:51
Apache Kylin是一个开源的分布式分析引擎,提供Hadoop之上的SQL查询接口及多维分析(OLAP)能力以支持超大规模数据,最初由eBay开发并贡献至开源社区。Apache Kylin提供了自己的WEB界面,用户可以在上面进行相应的SQL语句查询。但是由于Apache Kylin使用的是Calcite进行了SQL解析,因此有很多函数都不支持。本文主要介绍如何在Apache Kylin中实现自定义函数。关于Calcite的简单使用可以参考:http://blog.csdn.net/yu616568/article/details/49915577,这里简单介绍下Calcite关于函数的定义:
{ name: 'MY_PLUS', className: 'com.example.functions.MyPlusFunction', methodName: 'apply', path: []}
其中,name用来表示函数名,在调用自定义函数的时候使用;className表示实现函数的类;methodName表示在类中实现该函数的方法名。如果methodName是确定的,那么这个方法在对应的类中必须存在。方法可以是静态的或者非静态的,但是如果是非静态的,那么对应的类必须有一个不带参数的public构造函数。如果methodName是”*”,那么Calcite会为类中的每个方法都生成一个对应的函数,类中的每个方法名都必须大写,此时name将不再有意义,在调用的时候可以直接通过该方法名进行调用,后面将会结合例子进行介绍。如果以上关于函数的定义可以直接写在JSON中,关于Calcite JSON模型的更多介绍可以参考:https://calcite.apache.org/docs/model.html#custom-schema。
在Apache Kylin源码的org.apache.kylin.query目录下有一个ufd文件夹,我们可以在这个文件夹中定义自己的自定义函数类,当然也可以放在其他路径中,这里为了便于管理,最好将自定义的函数类都放在此路径下。这里我定义了一个名为KylinRound的类,用于实现自定义函数round,类的主要代码如下所示:
package org.apache.kylin.query.udf;import java.math.BigDecimal;public class KylinRound { /** * 返回第一个参数value小数点之后len位有效数字,并且四舍五入。 * @param value input value * @param len given length * @return */ public static double ROUND(double value, int len) { if (len < 0) throw new IllegalArgumentException("Parameter(s) error!"); String valueS = String.valueOf(value); valueS = valueS.substring(valueS.indexOf('.') + 1); if (valueS.length() > len) { BigDecimal input = new BigDecimal(value); BigDecimal result = new BigDecimal(Math.round(input.movePointRight(len).doubleValue())); return result.movePointLeft(len).doubleValue(); } else { return value; } } public static double ROUND(BigDecimal value, int len) { double valueD = value.doubleValue(); return ROUND(valueD, len); } public static double ROUND(String value, int len) { double valueD = Double.valueOf(value); return ROUND(valueD, len); }}
类中一共包含三个重载函数,可以接受三种不同类型的输入参数,分别是double、BigDecimal和String类型。为了在Kylin的SQL查询中支持round函数,还需要将该函数“注册”到Kylin中。前面提到Kylin在进行SQL解析的时候使用了Calcite,因此可以通过Calcite JSON模型的方法将自定义的round函数“注册”到Kylin上:
{ name: 'KylinROUND', className: 'org.apache.kylin.query.udf.KylinRound', methodName: '*',}
这里将methodName定义为‘*’,Kylin会为KylinRound类中的每一个方法都注册一个对应的函数(这些方法名都必须是大写)。此时name就没有什么意义了,用户可以在SQL语句中直接使用ROUND进行相应的处理。此方法不仅适用于重载函数,而且对于不同名的多个函数也是适用的。
在与udf同级的目录中有一个名为schema的文件夹,其中有一个OLAPSchemaFactory类,Kylin就是在这个类中,把自定义函数写到JSON中的。在这个类的末尾部分,我们将上面的“注册”代码加上:
for (String schemaName : schemaCounts.keySet()) { out.write(" {\n"); out.write(" \"type\": \"custom\",\n"); out.write(" \"name\": \"" + schemaName + "\",\n"); out.write(" \"factory\": \"org.apache.kylin.query.schema.OLAPSchemaFactory\",\n"); out.write(" \"operand\": {\n"); out.write(" \"" + SCHEMA_PROJECT + "\": \"" + project + "\"\n"); out.write(" },\n"); out.write(" \"functions\": [\n"); out.write(" {\n"); out.write(" name: 'MASSIN',\n"); out.write(" className: 'org.apache.kylin.query.udf.MassInUDF'\n"); out.write(" },\n"); out.write(" {\n"); out.write(" name: 'ROUND',\n"); out.write(" className: 'org.apache.kylin.query.udf.KylinRound',\n"); out.write(" methodName: '*'\n"); out.write(" }\n"); out.write(" ]\n"); out.write(" }\n"); if (++counter != schemaCounts.size()) { out.write(",\n"); }}
可以看到Kylin自己也定义了一个自定义函数类MassInUDF,但是并没有指定methodName,因此根据Calcite的解析规则,会去MassInUDF类中寻找名为“eval”的方法。查看MassInUDF类,可以发现确实有一个eval方法:
public class MassInUDF { public boolean eval(@Parameter(name = "col") Object col, @Parameter(name = "filterTable") String filterTable) { return true; }}
至此,我们就完成Kylin的自定义函数编写。然后重新编译源码即可。对于已经部署了Kylin的情况,可以编译后新生成的query/target/kylin-query-*.jar拷贝到Kylin部署目录的/tomcat/webapps/kylin/WEB-INF/lib目录下,替换原先的jar包,然后再重启Kylin服务器,就可以在WEB页面使用编写的自定义函数了。
- Apache Kylin的自定义函数实现
- Apache Kylin最新的Streaming OLAP实现
- Apache Kylin最新的Streaming OLAP实现
- apache kylin的二次开发
- Apache Kylin的前世今生
- Apache Kylin的入门安装
- Apache Kylin的Cube分析
- apache kylin
- Apache Kylin
- Apache Kylin在云海的实践
- Apache Kylin在百度地图的实践
- 安装Apache Kylin时遇到的问题
- Apache Kylin在百度地图的实践
- Apache Kylin 安装
- APACHE KYLIN简单介绍
- Apache Kylin使用总结
- 《浅谈Apache Kylin二次开发》
- Apache kylin学习笔记
- 面向对象的风格和基于对象的风格程序设计
- Android开发之context
- 集合大聚会
- java 对象赋值
- stm32 固件库之:uart
- Apache Kylin的自定义函数实现
- 手动注册database至crs中
- Android问题分析之ANR
- c语言练习题
- 起航,我的博客之
- git原理图及git协同模型
- (6)CSS的常用操作
- Android5.0+(CollapsingToolbarLayout)实现上划toolbar渐变效果
- Android N新特性-多窗口模式适配