Hive-jdbc获取sessionId

在HiveStatement中有一个sessHandle:

public class HiveStatement implements java.sql.Statement {
  ...
  private final TSessionHandle sessHandle; // 这个代表了hive的session,通过sessionId可以去hive服务器或者hadoop目录中获取hive的查询日志,在hiveserver2中,这个sessionId是UUID类生成的
  ...

TSessionHandle有个getSessionId方法可以获取到sessionId

public class TSessionHandle implements org.apache.thrift.TBase<TSessionHandle, TSessionHandle._Fields>, java.io.Serializable, Cloneable {
  ...
  private THandleIdentifier sessionId; // required
  ...
  public THandleIdentifier getSessionId() {
    return this.sessionId;
  }
  ...

THandleIdentifier类有guid和secret

public class THandleIdentifier implements org.apache.thrift.TBase<THandleIdentifier, THandleIdentifier._Fields>, java.io.Serializable, Cloneable {
  ...
  private ByteBuffer guid; // 这个代表了sessionId的字符串(UUID)
  private ByteBuffer secret; // required
  ...

但是guid是个ByteBuffer,不知道怎么反序列化成字符串
后来我看了hiveserver2的代码,在hive-service.jar中,有个HandleIdentifier类可以对THandleIdentifier的byte数据进行反序列化:

/**
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.apache.hive.service.cli;

import java.nio.ByteBuffer;
import java.util.UUID;

import org.apache.hive.service.cli.thrift.THandleIdentifier;

/**
 * HandleIdentifier.
 *
 */
public class HandleIdentifier {
  private final UUID publicId;
  private final UUID secretId;

  public HandleIdentifier() {
    publicId = UUID.randomUUID();
    secretId = UUID.randomUUID();
  }

  public HandleIdentifier(UUID publicId, UUID secretId) {
    this.publicId = publicId;
    this.secretId = secretId;
  }

  public HandleIdentifier(THandleIdentifier tHandleId) {
    ByteBuffer bb = ByteBuffer.wrap(tHandleId.getGuid());
    this.publicId = new UUID(bb.getLong(), bb.getLong());
    bb = ByteBuffer.wrap(tHandleId.getSecret());
    this.secretId = new UUID(bb.getLong(), bb.getLong());
  }

  public UUID getPublicId() {
    return publicId;
  }

  public UUID getSecretId() {
    return secretId;
  }

  public THandleIdentifier toTHandleIdentifier() {
    byte[] guid = new byte[16];
    byte[] secret = new byte[16];
    ByteBuffer guidBB = ByteBuffer.wrap(guid);
    ByteBuffer secretBB = ByteBuffer.wrap(secret);
    guidBB.putLong(publicId.getMostSignificantBits());
    guidBB.putLong(publicId.getLeastSignificantBits());
    secretBB.putLong(secretId.getMostSignificantBits());
    secretBB.putLong(secretId.getLeastSignificantBits());
    return new THandleIdentifier(ByteBuffer.wrap(guid), ByteBuffer.wrap(secret));
  }

  @Override
  public int hashCode() {
    final int prime = 31;
    int result = 1;
    result = prime * result + ((publicId == null) ? 0 : publicId.hashCode());
    result = prime * result + ((secretId == null) ? 0 : secretId.hashCode());
    return result;
  }

  @Override
  public boolean equals(Object obj) {
    if (this == obj) {
      return true;
    }
    if (obj == null) {
      return false;
    }
    if (!(obj instanceof HandleIdentifier)) {
      return false;
    }
    HandleIdentifier other = (HandleIdentifier) obj;
    if (publicId == null) {
      if (other.publicId != null) {
        return false;
      }
    } else if (!publicId.equals(other.publicId)) {
      return false;
    }
    if (secretId == null) {
      if (other.secretId != null) {
        return false;
      }
    } else if (!secretId.equals(other.secretId)) {
      return false;
    }
    return true;
  }

  @Override
  public String toString() {
    return publicId.toString();
  }
}

这个类没有依赖太多东西,可以直接复制到自己项目中使用

String sessionId = new HandleIdentifier(sessHandle).getPublicId();

这样行了

然后hive会把一个session的日志记录在本地的一个文件(${hive.exec.local.scratchdir}/${user}/${sessionId})和hdfs的一个文件(${hive.exec.scratchdir}/${user}/${sessionId})中,可以去跟踪这些文件去看sql的执行情况。

更简单的方法是调用HiveStatement.getQueryLog()去获取查询日志

原文地址:https://www.cnblogs.com/lanhj/p/7528347.html