技术选型——机器学习测试(7)

发表于:2020-10-19 09:54

字体: | 上一篇 | 下一篇 | 我要投稿

 作者:融360 AI 测试团队    来源:51Testing软件测试网原创

  2. 技术选型
  调研发现常用的Python连接Hive的工具有Presto、pyHive、impala及pyhs2等。经过执行效率及公司现有环境综合比较最终选择了Presto作为查询主要工具。
  Presto是由Facebook开发的,是一个运行在多台服务器上的分布式查询引擎,本身虽然并不存储数据,但是可以接入多种数据源(Hive、HBase、OracleMySQL、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软件测试网获得人民邮电出版社和作者授权连载本书部分章节。
任何个人或单位未获得明确的书面许可,不得对本文内容复制、转载或进行镜像,否则将追究法律责任。
《2023软件测试行业现状调查报告》独家发布~

关注51Testing

联系我们

快捷面板 站点地图 联系我们 广告服务 关于我们 站长统计 发展历程

法律顾问:上海兰迪律师事务所 项棋律师
版权所有 上海博为峰软件技术股份有限公司 Copyright©51testing.com 2003-2024
投诉及意见反馈:webmaster@51testing.com; 业务联系:service@51testing.com 021-64471599-8017

沪ICP备05003035号

沪公网安备 31010102002173号