kylin与superset集成实现数据可视化

原文地址:http://minirick.duapp.com/kylinyu-supersetji-cheng-shi-xian-shu-ju-ke-shi-hua/?utm_source=tuicool&utm_medium=referral

apache kylin是一个开源分布式引擎,提供Hadoop之上的SQL查询接口及多维分析(OLAP)能力以支持超大规模数据。而superset是airbnb开源的一款数据可视化工具。

kylin在超大数据规模下仍然可以提供秒级甚至毫秒级sql响应的OLAP多维分析查询服务。而且对服务器内存的要求也不像spark sql那么高,经过多方面的优化,数据膨胀率甚至可以控制在100%以内。它利用hive做预计算,然后建立多维的数据立方体,并存在hbase中,从而提供了实时查询的能力。

superset也就是早先的caravel,提供了丰富的图表供用户配置。只要连上数据源,勾几个简单的配置,或者写点sql。用户就可以轻易的构建基于d3、nvd3、mapbox-gl等的炫酷图表。
superset

我厂也是选择了kylin和superset,遗憾的是superset支持多种数据源,包括druid、hive、impala、sparkSQL、presto以及多种主流关系型数据库,但是并不支持kylin。于是我们对其进行了改进。

首先观察superset的源码,它后台使用Flask App Builder搭建的,数据访问层用sqlalchemy实现。也就是说,它本质上可以支持所有数据源,只要实现一套kylin的dialect即可。而同时github上有一个pykylin项目,就是实现的这个dialect。这极大增强了我解决这个问题的信心。

正好前几周,superset出了一个新的prod版本airbnb_prod.0.15.5.0。装好它和pykylin之后,导入kylin数据源,成功! 导入kylin数据源 但是点开sqllab想敲点sql验证一下时,却出了异常。 异常 Debug了pykylin代码,发现get_table_names方法的入参connection实际已经是sqlalchemy的Engine对象了,这可能是最新sqlalchemy的版本升级造成的。总之,将原来的代码:

def get_table_names(self, connection, schema=None, **kw):
return connection.connection.list_tables()
改成:

def get_table_names(self, engine, schema=None, **kw):
connection = engine.contextual_connect()
return connection.connection.list_tables()
即可。

顺便我们看到这里它扩展了sqlalchemy的list_tables方法,sqllab左上方的table选择区还有列出所有schema的下拉框,于是我们顺带把list_schama方法也实现。connection.py添加:

def list_schemas(self):
route = ‘tables_and_columns’
params = {‘project’: self.project}
tables = self.proxy.get(route, params=params)
return [t[‘table_SCHEM’] for t in tables]
dialect.py添加:

def get_schema_names(self, engine, schema=None, **kw):
connection = engine.contextual_connect()
return connection.connection.list_schemas()
之后执行sql还是有错: 异常 pykylin在每次调用kylin的api时会首先登录,以获得JSESSIONID,并存入cookie中,这里是登录失败,检查代码,发现这里问题还挺多的,首先proxy.py中的login方法作者写的是self.password = user应改成password。dialect.py中create_connect_args方法改为:

def create_connect_args(self, url):
opts = url.translate_connect_args()
api_prefix = ‘kylin/api/’
args = {
‘username’: opts[‘username’],
‘password’: opts[‘password’],
‘endpoint’: ‘http://%s:%s/%s’ % (opts[‘host’], opts[‘port’], api_prefix)
}
args.update(url.query)
return [], args
这样大部分sql查询没有问题,但是有的查询结果有部分值是null,这样也会出错。修改cursor.py的_type_mapped方法:

def _type_mapped(self, result):
meta = self.description
size = len(meta)
for i in range(0, size):
column = meta[i]
tpe = column[1]
val = result[i]
if val is None:
pass
elif tpe == ‘DATE’:
val = parser.parse(val)
elif tpe == ‘BIGINT’ or tpe == ‘INT’ or tpe == ‘TINYINT’:
val = int(val)
elif tpe == ‘DOUBLE’ or tpe == ‘FLOAT’:
val = float(val)
elif tpe == ‘BOOLEAN’:
val = (val == ‘true’)
result[i] = val
return result
这样在sqllab中执行sql基本没问题了。 sqllab

下一步开始自定义slice,定制自己的可视化dashboard。

在这里再次遇到问题,superset会自动把count函数计算的列设置别名叫count,而count是kylin的关键字,因此导致查找失败。修改superset的models.py的sqla_col方法:

@property
def sqla_col(self):name = self.metric_nameif name == 'count':name = 'total_count'return literal_column(self.expression).label(name)

另外在slice中还经常会遇到pandas抛出的KeyError异常。这是因为在superset里面所有的关键字都是小写,然而kylin返回的所有的数据metadata全是大写,导致superset在kylin的返回结果中查询关键字的时候出现找不到关键字的错误。

修改pykylin的cursor.py的execute方法。

def execute(self, operation, parameters={}, acceptPartial=True, limit=None, offset=0):
sql = operation % parameters
data = {
‘sql’: sql,
‘offset’: offset,
‘limit’: limit or self.connection.limit,
‘acceptPartial’: acceptPartial,
‘project’: self.connection.project
}
logger.debug(“QUERY KYLIN: %s” % sql)
resp = self.connection.proxy.post(‘query’, json=data)

    column_metas = resp['columnMetas']for c in column_metas:c['label'] = str(c['label']).lower()c['name'] = str(c['name']).lower()self.description = [[c['label'], c['columnTypeName'],c['displaySize'], 0,c['precision'], c['scale'], c['isNullable']]for c in column_metas]self.results = [self._type_mapped(r) for r in resp['results']]self.rowcount = len(self.results)self.fetched_rows = 0return self.rowcount

最后,我发现在查找的字段包含kylin中的date类型时也会出错。点击slice页面右上角的query按钮,可以查看superset最终发送的sql。 kylin不支持的长日期格式 将它直接拷贝到kylin的insight页面去执行,发现报错。原来kylin的date类型只支持年月日,而superset在添加日期搜索条件时为了实现定时刷新图表而在sql的日期条件中都精确到了时分秒。关于这个我原先是在superset中做了修改。

在superset的models.py的get_query_str方法中:

time_filter = dttm_col.get_time_filter(from_dttm, to_dttm)
改为

if engine.name == ‘kylin’:
time_filter = dttm_col.get_date_filter(from_dttm, to_dttm)
else:
time_filter = dttm_col.get_time_filter(from_dttm, to_dttm)
添加get_date_filter,dt_sql_literal函数:

def get_date_filter(self, start_dttm, end_dttm):
col = self.sqla_col.label(‘__time’)
return and_(
col >= text(self.dt_sql_literal(start_dttm)),
col <= text(self.dt_sql_literal(end_dttm)),
)

def dt_sql_literal(self, dttm):
return “’{}’”.format(dttm.strftime(‘%Y-%m-%d’))
这样对于所有kylin数据源的查找时间范围条件都将转为年月日的格式。

不过我一直感觉这个改动不是很完美,是一种典型的打补丁的做法。后来我发现superset支持在列的设置页面为一个日期列添加自定义的格式转换函数 superset日期转换函数设置 于是我在这里设置日期列格式

TO_DATE(‘{}’, ‘yyyy-MM-dd’)

然后可以看到slice这里sql中的该列都变成了to_date函数形式 to_date sql 最后的工作就是修改kylin源码,添加对日期函数的支持。hive sql是支持to_date等日期格式转换函数的,kylin凭什么不支持?

大致debug了一下kylin的源码,kylin处理sql的入口在server-base模块下的QueryController.java的query方法中。我发现在最终调用jdbc驱动执行sql之前,kylin会调QueryUtil类的massageSql方法来优化sql。主要是加上limit和offset参数。最后调内部类DefaultQueryTransformer的transform方法改掉sql中的一些通病,比如SUM(1)改成count(1)等。日期转换函数的处理放在这后面我觉得是最合适的。

添加正则表达式,以匹配日期函数:

private static final String TO_DATE = “(to_date|TO_DATE)\(‘|\”[‘|\”],\s?‘|\”[‘|\”]\)”;
private static final Pattern FN_TO_DATE = Pattern.compile(TO_DATE);
添加日期转行函数解析:

private String executeFN(String sql) {
Matcher m;
while (true) {
m = FN_TO_DATE.matcher(sql);
if (!m.find())
break;
String dateTime = m.group(2);
String format = m.group(3);
SimpleDateFormat sdf = new SimpleDateFormat(“yyyy-MM-dd HH:mm:ss”);
Date dt = null;
try {
dt = sdf.parse(dateTime);
} catch (ParseException e) {
logger.error(“Parse date error”, e);
}
sdf = new SimpleDateFormat(format);
String date = sdf.format(dt);
String begin = sql.substring(0, m.start());
String end = sql.substring(m.end(), sql.length());
sql = begin + “’” + date + “’” + end;
}
return sql;
}
然后kylin就可以支持上面sql的执行了 kylin支持to_date 最后,让我们多尝试一些可视化图表吧,把它们做成dashboard superset dashboard

结论:kylin很好地支持了我厂每天上百GB数据的立方体建模和实时查找,结合superset的方案,作为我厂内部的可视化工具,收到了很好地效果。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/570860.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Ambari离线部署Hadoop集群踩到的坑

1、远程拷贝HDP组件不全导致安装client时缺少rpm包&#xff0c;手动拷贝解决 2、安装HAWQ&#xff0c;启动时报错 passwordlell ssh hawq hosts &#xff0c;hawq master 和其他主机机拷贝文件输入密码受限&#xff0c;两方面原因&#xff1a; 一 root 用户 ssh 无密登录时 权…

2016012026 管凌波 散列函数的应用及其安全性

2016012026 管凌波 散列函数的应用及其安全性 一、散列函数是什么。 散列函数即为Hash函数&#xff0c;就是把任意长度的输入&#xff08;预映射&#xff09;&#xff0c;通过散列算法&#xff0c;变换成固定长度的输出&#xff0c;该输出就是散列值。这种转换是一种压缩映射&a…

Team Foundation Server (TFS) 2015 安装指导

原文地址&#xff1a;http://www.cnblogs.com/danzhang/p/4718035.html http://www.cnblogs.com/danzhang 张洪君 微软ALM MVP 1. 概述 微软于8月6日发布了大家期待已久的TFS 2015正式版&#xff0c; https://www.visualstudio.com/en-us/news/tfs2015-vs.aspx &#xff0c;…

VM虚拟机链接克隆及linux eth0网卡的快速设置方法

对于后台开发者来说,在学习过程中必然接触众多中间件,在自己的虚拟机进行操作甚至搭建cluster是很常见的事情.我在初学者时摸索出一套快速的克隆虚拟机方法.分享给大家.产品VMware Workstation版本10.0.2 build-1744117这是我的虚拟机命名,我觉得这样的命名比较合适,clone机/服…

一加手机虚拟键失灵解决方案

1、手机摔了一下后下方虚拟键无法使用&#xff0c;尝试多种小白点工具如悬浮菜单、超级小白点、easytouch&#xff0c;安装完后并取得root权限后仍不能弹出悬浮框&#xff0c;找不到原因&#xff0c;原则上来讲的话如果是硬件屏幕摔坏&#xff0c;某哥区域无法响应触摸不应影响…

scrapy newspaper bug

发现一个newspaper的bug,在github上已修复,但pip下载的包还是有这个错fix for "jpeg error with PIL, Cant convert NoneType object to str implicitly"修复办法: 打开python27/Lib/site-packages/newspaper/images.pyclass Scraper:def largest_image_url:把log.de…

Spring MVC+Mybatis 多数据源配置

文章来自&#xff1a;https://www.jianshu.com/p/fddcc1a6b2d8 1. 继承AbstractRoutingDataSource AbstractRoutingDataSource 是spring提供的一个多数据源抽象类。spring会在使用事务的地方来调用此类的determineCurrentLookupKey()方法来获取数据源的key值。我们继承此抽象类…

C#如何Json转字符串;字符串转Json;Newtonsoft.Json(Json.Net)

什么是JSON C#如何Json转字符串 字符串转Json Newtonsoft.Json(Json.Net)学习笔记&#xff08;转&#xff09; 转载于:https://www.cnblogs.com/macT/p/9040901.html

mysql更改root用户密码

不同版本命令不一样 MySQL 5.7.6 and later: ALTER USER ‘root’’localhost’ IDENTIFIED BY ‘MyNewPass’; MySQL 5.7.5 and earlier: SET PASSWORD FOR ‘root’’localhost’ PASSWORD(‘MyNewPass’);

python2.7 安装numpy no module name zlib

CentOS6.7默认安装Python-2.6 而numpy支持python2.7以上&#xff0c;所以需要安装Python2.7&#xff0c;安装的步骤就不细说了&#xff0c;编译安装,然后再建立软连接。 之后安装numpy时报错no module named setuptools &#xff0c;pip 安装或者源码安装&#xff0c;我采用源…

java : nio 学习

https://github.com/astutesparrow/nio https://www.ibm.com/developerworks/cn/education/java/j-nio/j-nio.html 转载于:https://www.cnblogs.com/chen-msg/p/9041510.html

AWS DevOps – 配合Jenkins和CodeDeploy实现代码自动化部署

AWS DevOps – 配合Jenkins和CodeDeploy实现代码自动化部署 Amazon ElastiCache 连接至 Redis 节点 通过 AWS Command Line Interface使用高级别 s3 命令 在 Linux 上安装 AWS Command Line Interface 在Amazon EC2主机上安装Zmodem协议传输工具lrzsz 安装lrzsz出现configure: …

pip install mysqlclient报错fails with EnvironmentError: mysql_config not found

解决&#xff1a; CentOS yum install mysql-devel 再重新执行pip install mysqlclient解决

管理外部程序的流程

本部分包含&#xff1a; 关于外部程序DBA任务来启用外部过程调用关于外部程序 外部程序是用C&#xff0c;C &#xff0c;Java或其他语言编写的程序&#xff0c;编译并存储在数据库之外&#xff0c;然后由用户会话调用。例如&#xff0c;PL / SQL程序单元可以调用执行特殊用途处…

ssh登陆慢/xhell访问主机慢

用ssh连其他linux机器&#xff0c;会等待10-30秒才有提示输入密码。严重影响工作效率。登录很慢&#xff0c;登录上去后速度正常&#xff0c;这种情况主要有两种可能的原因&#xff1a; DNS反向解析的问题 OpenSSH在用户登录的时候会验证IP&#xff0c;它根据用户的IP使用反向…

围观神龙架构首次开箱,现场直播暴力拆机

围观神龙架构首次开箱&#xff0c;现场直播暴力拆机 发布时间&#xff1a;2018-05-16 13:43:01686人关注34人参与阿里云X-Dragon大事记2017年4月&#xff1a;阿里云X-Dragon项目立项&#xff1b;2017年10月&#xff1a;阿里云正式推出基于X-Dragon架构的弹性裸金属服务器&#…

windows-server-2012R2离线中文语言包安装

1、离线包下载地址http://download.csdn.net/detail/github_38358734/9858412 2、安装方法&#xff1a; 解压离线包 Dism /online /Add-Package /PackagePath:C:\test\LangPacks\lp.cab 大概10分钟&#xff0c;完成。 然后重启电脑&#xff0c;到控制面板语言区域选项&…

文字闪烁效果

效果图&#xff1a; HTML Code: <a class"blink" href"#" target"_blank"> 扁平化设计看上去非常简单、直观扁平化设计看上去非常简单、直去非化设计看上去非常简单、直观扁平化设计看上去非常简单、直观扁平常简单</a> JQuery Code…

SVN数据代码迁移Windows2012ServerR2

场景描述&#xff1a;服务器迁移&#xff0c;需要把SVN服务从主机A迁移到主机B 环境&#xff1a;两台服务器都是windows-server-2012R2 目录&#xff1a;A、B目录及结构相同 SVN-Server_Home: C:\Program Files\VisualSVN Server\bin Repositories_HOME:D:\Repositories 第一…

程序员怎样锻炼编程思维(学习方法)

1.明确学习目的 学习编程对大多数IT业人员来说都是非常有用的。学编程&#xff0c;做一名编程人员&#xff0c;从个人角度讲&#xff0c;可以解决在软件使用中所遇到的问题&#xff0c;改进现有软件&#xff0c;可以为自己找到一份理想的工作添加重要得砝码&#xff0c;有利于在…