`
guiyu0856
  • 浏览: 39208 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

Hive可视化日志web方案的实现

    博客分类:
  • hive
阅读更多

2. 接口数据协议

IDE基于Hive部分约定的数据调用约定。

2.1 HQL语法约定

该部分的HQLWeb Server提交至Hive Server端执行。

根据Hive的特点,除了执行部分SELECT语句会启动MapReduce外,其他如alterloadinsert语句等都不会涉及M/R。由此可知,大部分情况下不会有MapReduce的执行过程日志输出,而目前IDE的日志监控部分仅对有MapReduce执行的查询有处理。根据《基于Hive JDBC实现的Web可视化界面方案V0.2.docx》分析得知,Hive JDBC仅对executeQueryclose方法做了真正实现,所有的HQL语句皆通过executeQuery方法传入并执行。因此,是否启动日志监控功能,只要在此方法的HQL参数前添加日志开关标识即可。

日志开关的标识约定为:{TYPE}_{DEST}_{SN}[_{IP}_{PORT}]  #@#@ 

TYPE:代表语句类型,取值为KILLQUERY(即select的语句)。

DEST:代表目的地,取值为HBASEREDIS(FILEHDFS暂不支持)

SN:为每个Job日志和查询结果数据key的前缀。如,执行A Job的日志单元标识前缀为dataA,那么对于存储在目的地中的key序列为dataA_LOG000001dataA_LOG000002dataA_LOG000003dataA_LOGNN为大于等于0的正整数,在位数不足6位的情况下,前缀补0以达到6位长度),客户端取对应执行日志时,即通过该key值序列逐一取出。而查询结果数据的key前缀为dataA_DATA

另外特别注意两点:1.编号由000001开始;2.由于语法前缀标识符以下划线_分割,那么SN中决不能出现_符号,否则数据出错。

IP:目标主机的有效IP地址或域名,该参数在DESTREDIS时必填,否则可以为空;

PORT:目标主机的有效端口,该参数在DESTREDIS时必填,否则可以为空。即当DESTREDIS时,日志开关的标识约定变为:{TYPE}_{DEST}_{SN}

#@#@:为分割标识,在欲新增日志存储方式的语句最前面。#@#@前后各留一个或多个空格。其中TYPE为 KILL时,无需#@#@分隔符及后缀。

下面针对各种情况分别举例:

一、 应用redis转存日志。select * from table 这个查询HQL,假如,流水号设定为20121112151900redisip地址为192.168.8.8,端口为8888,那么查询语句应该更改为:QUERY_REDIS_20121112151900_192.168.8.8_8888 #@#@         select * from table 

二、 应用hbase转存日志。select * from table 这个查询HQL,假如,流水号设定为20121112151900,那么查询语句应该更改为:QUERY_HBASE_20121112151900  #@#@  select * from table 

三、 应用rediskill停止执行任务。 select * from table 这个查询HQL,假如,流水号设定为20121112151900redisip地址为192.168.8.8,端口为8888,那么kill语句应该更改为:KILL_REDIS_20121112151900_192.168.8.8_8888

四、 应用hbasekill停止执行任务。 select * from table 这个查询HQL,假如,流水号设定为20121112151900,那么kill语句应该更改为:KILL_HBASE_20121112151900

调用Statement.executeQuery(sql)执行即可。

2.2 读取日志约定

Web Server发起读取转存日志的请求。

读取执行日志的方式会随着存放的目的地不同而稍有差异,建议Web Server封装读取日志的接口,便于灵活切换。下面分别约定从RedisHBase中读取日志的规则。

Redis读取日志

 日志在redis中以key-value键值对的形式进行存储,其key值是日志开关标识中的SN为前缀,后跟6位从000001开始的序列;value值为具体日志内容的字符串型。

举例说明,假设日志开关的为QUERY_REDIS_20121112151900_192.168.8.8_8888,那么Web Server读取日志时连接的Redis服务端的IPPort分别为192.168.8.88888,再调用redis客户端递增读取以20121112151900_LOG00000120121112151900_LOG00000220121112151900_LOG00000NN为大于等于0的正整数,在位数不足6位的情况下,前缀补0,达到6位长度)。

每次读取日志时,同时读取20121112151900_LOG000000的日志标志位,当标志位的以“00”开头时,表示程序正常执行完毕;当以“10”开头时,表示程序仍在执行中;当以“20”开头时,表示程序执行完毕,但是执行过程异常;当以“30”开头时,表示程序异常终止[详见2.5]。简单代码如下:

Jedis jedis = new Jedis("192.168.8.8", 8888);

int num=1;

String numStr= String.valueOf(i);

numStr=000000.subString(0,6- numStr.length())+numStr;

String  loginfo=jedis.get("20121112151900_LOG " + numStr);

System.out.println(loginfo);

String logFlag= jedis.get("20121112151900_LOG000000 " );

if(logFlag !=null && logFlag.startWith(00)){

   //判断状态标志位,并输出提示

}

 

HBase读取日志

 日志在HBase中以rowid-value行键与列族值的条记录形式进行存储,其rowid值是日志开关标识中的SN为前缀,后跟6位从000001开始的序列;value值为具体日志内容的字符串型。

举例说明,假设日志开关的为QUERY_HBASE_20121112151900,那么Web Server读取日志时连接的HBase服务端通过hbase-site.xml中进行配置,再调用HBase客户端递增读取以20121112151900_LOG 00000120121112151900_LOG 00000220121112151900_LOG 00000NN为大于等于0的正整数,在位数不足6位的情况下,前缀补0,达到6位长度)或者设定rowid值区间批量读取。

每次读取日志时,同时读取20121112151900_LOG000000的日志标志位,当标志位的以“00”开头时,表示程序正常执行完毕;当以“10”开头时,表示程序仍在执行中;当以“20”开头时,表示程序执行完毕,但是执行过程异常;当以“30”开头时,表示程序异常终止[详见2.5]。简单代码如下:

1. 读取单条记录

HTable table = new HTable(conf"IDE_MR_LOG");

int num=1;

String rowKey = String.valueOf(i);

rowKey ="20121112151900_LOG " +”000000.subString(0,6- numStr.length())+numStr;

Get get = new Get(rowKey.getBytes());

Result rs = table.get(get);

for (KeyValue kv : rs.raw()) {

//System.out.print(new String(kv.getRow()) + " ");

//System.out.print(new String(kv.getFamily()) + ":");

//System.out.print(new String(kv.getQualifier()) + " ");

//System.out.print(kv.getTimestamp() + " ");

System.out.println(new String(kv.getValue()));

String logFlag= jedis.get("20121112151900_LOG000000 " );

if(logFlag !=null && logFlag.startWith(00)){

        //判断状态标志位,并输出提示

}

}

2. 读取多条记录

HTable table = new HTable(conf"IDE_MR_LOG");

int num=1;

String startRowKey = String.valueOf(i);

startRowKey =” 20121112151900_LOG+000000.subString(0,6- numStr.length())+numStr;

String startRowKey = String.valueOf(i);

String endRowKey =” 20121112151900_LOG+000000.subString(0,6- numStr.length())+numStr;

Scan s = new Scan(startRowKey.getBytes[],endRowKey.getBytes[],);

ResultScanner ss = table.getScanner(s);

for (Result r : ss) {

for (KeyValue kv : rs.raw()) {

//System.out.print(new String(kv.getRow()) + " ");

//System.out.print(new String(kv.getFamily()) + ":");

//System.out.print(new String(kv.getQualifier()) + " ");

//System.out.print(kv.getTimestamp() + " ");

System.out.println(new String(kv.getValue()));

String logFlag= jedis.get("20121112151900_LOG000000 " );

if(logFlag !=null && logFlag.startWith(00)){

        //判断状态标志位,并输出提示

}

}

  }

 

 

 

2.3 读取查询结果数据约定

Web Server发起读取转存(方便后续可追踪)查询结果数据的请求。

读取执行查询结果数据的方式会随着存放的目的地不同而稍有差异,建议Web Server封装读取和写入数据的接口,便于灵活切换。下面分别约定从RedisHBase中读取查询结果数据的规则。

Redis读取数据

日志在redis中以key-value键值对的形式进行存储,其key值是日志开关标识中的SN为前缀,后跟+_DATA组成数据的keyvalue值为查询列的元数据和结果数据组装而成的JSON格式的字符串。

拼装的JSON格式为:

{

"metadata":["selcolumn1","selcolumn2",...,"selcolumnN"],

"resultdata":

 [

 ["value1","value2",...,"valueN"],

["value1","value2",...,"valueN"],

...,

["value1","value2",...,"valueN"]

]

}

其中,metadataselect语句中查询的列顺序,当列为*时,由元数据ResultSetMetaData取出;

resultdataselect语句中查询的列顺序,对应为每一条记录组合而成的数组结构。

举例说明,假设日志开关的为QUERY_REDIS_20121112151900_192.168.8.8_8888,那么Web Server读取数据时连接的Redis服务端的IPPort分别为192.168.8.88888,再调用redis客户端读取key值为20121112151900_D的值。简单代码如下:

Jedis jedis = new Jedis("192.168.8.8", 8888);

String  jsonData=jedis.get("20121112151900_DATA " );

System.out.println(jsonData);

 

HBase读取数据

日志在HBase中以rowid-value行键与列族的条记录形式进行存储,其rowid值是日志开关标识中的SN为前缀,后跟“_D”后再接6位从000001开始的序列;value值为一个列族,列族下对应的列由select后接的查询列(全部转换为小写)生成。如,select a,b,c from table,那么在HBase的列族对应为:value:a, value:b, value:c 

举例说明,假设日志开关的为QUERY_HBASE_20121112151900,那么Web Server读取查询结果数据时连接的HBase服务端通过hbase-site.xml中进行配置,再调用HBase客户端递增读取以20121112151900_DATA00000120121112151900_DATA00000220121112151900_DATA00000NN为大于等于0的正整数,在位数不足6位的情况下,前缀补0,达到6位长度)或者设定rowid值区间批量读取。简单代码如下:

1. 读取单条记录

HTable table = new HTable(conf"IDE_MR_DATA");

int num=1;

String rowKey = String.valueOf(i);

rowKey =” 20121112151900_DATA+000000.subString(0,6- numStr.length())+numStr;

Get get = new Get(rowKey.getBytes());

Result rs = table.get(get);

for (KeyValue kv : rs.raw()) {

System.out.print(new String(kv.getRow()) + " ");

System.out.print(new String(kv.getFamily()) + ":");

System.out.print(new String(kv.getQualifier()) + " ");

//System.out.print(kv.getTimestamp() + " ");

System.out.println(new String(kv.getValue()));

}

2. 读取多条记录

HTable table = new HTable(conf"IDE_MR_DATA");

int num=1;

String startRowKey = String.valueOf(i);

startRowKey =” 20121112151900_DATA+000000.subString(0,6- numStr.length())+numStr;

String startRowKey = String.valueOf(i);

String endRowKey =” 20121112151900_DATA+000000.subString(0,6- numStr.length())+numStr;

Scan s = new Scan(startRowKey.getBytes[],endRowKey.getBytes[],);

ResultScanner ss = table.getScanner(s);

for (Result r : ss) {

for (KeyValue kv : rs.raw()) {

System.out.print(new String(kv.getRow()) + " ");

System.out.print(new String(kv.getFamily()) + ":");

System.out.print(new String(kv.getQualifier()) + " ");

//System.out.print(kv.getTimestamp() + " ");

System.out.println(new String(kv.getValue()));

}

  }

 

 

2.4 操作日志存储约定

操作日志必须持久化,存储在RMDB中,操作日志的写入由Web Server完成。

操作日志表字段包括:operator,operteStartTime, operteEndTime,operateContent,operateResult,operateRaletiveRowId,分别表示操作人,操作开始时间,操作结束时间,操作内容,操作结果,操作关联的结果集rowId

举例说明,假设IDE上线运行一段时间后,想追踪运行情况,那么可以从操作日志中读取具体情况。假设查询日志开关SN20121112151900的操作历史,那么Web Server读取数据时连接的HBase服务端通过hbase-site.xml中进行配置,再调用HBase客户端递增读取以20121112151900_LOGrowId。代码为JDBC普通代码,此处略去。

2.5 状态标志位约定

序号

编码

说明

1

00#@#@num#@#@概要描述

程序执行完毕,日志输出完毕。num为写入日志最终条数

2

10#@#@num#@#@概要描述

程序正在执行中。其中,num为过渡值。

3

20#@#@num#@#@概要描述

程序执行完毕,但其间报有异常。num为写入日志最终条数

4

30#@#@num#@#@概要描述

程序异常终止,日志输出完毕。num为写入日志最终条数

     

注意

#@#@”是编码与中文描述的分隔符,#号后面接中文描述,例如“00#@#@执行完毕”、“20#@#@执行完毕,日志开关中指定的ipport连接异常”。

读取状态标志位的keyrowid为日志开关标识中SN值加上_LOG000000,即{SN}_LOG000000

 

 

<!--EndFragment-->
0
0
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics