2. 技术选型
调研发现常用的Python连接Hive的工具有Presto、pyHive、impala及pyhs2等。经过执行效率及公司现有环境综合比较最终选择了Presto作为查询主要工具。
Presto是由Facebook开发的,是一个运行在多台服务器上的分布式查询引擎,本身虽然并不存储数据,但是可以接入多种数据源(Hive、HBase、Oracle、MySQL、Kafka、Redis等),并且支持跨数据源的级联查询。Presto所使用的执行模式与Hive有根本的不同,大部分场景下Presto比Hive快一个数量级。Presto是常驻任务,接受请求立即执行,全内存并行计算;Hive需要用Yarn做资源调度,接受查询需要先申请资源,启动进程,并且采用MapReduce计算模型,中间结果会经过磁盘,所以速度就相对较慢。
使用过程中发现Presto存在部分HiveQL不兼容问题,比如:show tables like a*命令无法执行、表结构查询与预期不符、执行切换库操作报错时不抛异常等。考虑到Presto部分功能缺失带来的问题,于是选择pyHive作为功能弥补工具,在执行特定SQL语句时会切换到pyHive去连接Hive执行,切换操作对用户无感知。区别于Hive,需要格外注意的是:Presto不支持隐式转换。比如Hive会成功执行以下语句:
select count(1) from sample_label where label <> ''; |
但是使用Presto执行就会报错:
PrestoUserError(type=USER_ERROR, name=SYNTAX_ERROR, message="line 1:83: '<>' cannot be applied to integer, varchar(0)", query_id=20191106_024551_01370_8ukjc)。
报错原因是,label列定义类型为integer,在使用Presto时直接将该列与空字符做比较,Presto不支持隐式转换所以就会报错。对于该类问题,使用时只需将label显式转换为string或者varchar类型即可解决:
select count(1) from sample_label where cast(label?as?string) <> ''; |
presto及pyHive的安装很简单,使用如下命令分别安装即可:
pip install presto-python-client
pip install pyHive
3. 模块代码demo
1) 入口函数
def main(options, hostname, port): setup_cqlruleset(options.cqlmodule) setup_cqldocs(options.cqlmodule) #初始化历史执行命令及结果文件 init_history() if options.file is None: stdin = None else: try: encoding, bom_size = get_file_encoding_bomsize(options.file) stdin = codecs.open(options.file, 'r', encoding) stdin.seek(bom_size) except IOError, e: sys.exit("Can't open %r: %s" % (options.file, e)) try: #初始化Shell,该类继承cmd.Cmd shell = Shell(hostname, port, database=options.database, username=options.username, password=options.password, stdin=stdin, tty=options.tty, completekey=options.completekey, single_statement=options.execute, connect_timeout=DEFAULT_CONNECT_TIMEOUT_SECONDS) except KeyboardInterrupt: sys.exit('Connection aborted.') except Exception, e: sys.exit('Connection error: %s' % (e,)) if options.debug: shell.debug = True #交互式命令循环处理 shell.cmdloop() batch_mode = options.file or options.execute if batch_mode and shell.statement_error: sys.exit(2) if __name__ == '__main__': main(*read_options(sys.argv[1:], os.environ)) |
2) Presto连接Hive代码demo
import prestodb conn=prestodb.dbapi.connect( host= ip, port=8443, user='username', catalog='hive', schema='default', http_scheme='https', auth=prestodb.auth.BasicAuthentication("username", "username的密码"), ) conn._http_session.verify = './presto.pem' #身份认证相关文件 cur = conn.cursor() cur.execute('SELECT * FROM system.runtime.nodes') rows = cur.fetchall() print rows |
3) 单表命令模块
使用Hive查询全表数据量,需要执行SQL语句select count(*) from tablename查询。经过该工具代码封装后,查询表数据只需要使用count tablename即可实现,且查询效率比使用原生Hive快一个数量级。查询结果保存在历史文件中,可以使用相关命令查看。单表模块命令有多个,count命令代码demo如下:
class?SigleTableAnalysis(cmd.Cmd): #count table,查询表数据量,支持传入where条件 @classmethod def?do_count(self, parsed, print_command=True, print_res=True): try: table_name = parsed.split(' ')[1].strip(';') statement = 'select count(1) from %s' % table_name if len(parsed.split(' ')) >=3 and parsed.split(' ')[2].strip() == 'where': wherecondition = ' '.join(parsed.split(' ')[3:]) statement = statement + ' where ' + wherecondition status, res = perform_simple_statement(statement, detail=False, print_command=print_command,?print_res=print_res) if not print_res: return status, res except IndexError as e: print('please check whether your command is right') except Exception as e: import traceback print('%s detail: %s' % (str(e), traceback.format_exc())) |
更多模块代码demo与count命令代码demo相似,双表查询模块、拉链表测试模块、数据质量分析模块会在单表模块的基础上进行封装使用,设计会更复杂一些,不再给出demo。
7.1.3 大数据测试工具使用
目前 easy_data_test工具支持的操作主要有如下几点:
1)支持单表数据量、列空值数据量、列非空值数据量、列最大值、列最小值、列不同值、不同值数据量查询,支持对表结构、任意select的查询,支持表基本信息查询、值域分析、异常值分析、手机号合规性分析、ID号合规性分析;
2)支持双表数据量对比、列空值数据量对比、列非空值数据量对比、表结构对比、Hive双表一致性对比、Hive&HBase一致性对比;
3)支持主备集群及库切换、库表集群信息查看;
4)支持历史执行命令及结果实时查看、全表分析Html展示、值域Html展示、Hive双表一致性分析结果Html展示;
5)支持拉链表通用测试(拉链表是否断链、拉链表日期正确性、拉链表与临时表数据量、数值对比)。
版权声明:51Testing软件测试网获得人民邮电出版社和作者授权连载本书部分章节。
任何个人或单位未获得明确的书面许可,不得对本文内容复制、转载或进行镜像,否则将追究法律责任。