Hive-源码带你看hive命令背后都做了什么

news2024/11/17 3:26:32

一、源码下载

  下面是hive官方源码下载地址,我下载的是hive-3.1.3,那就一起来看下吧

https://dlcdn.apache.org/hive/hive-3.1.3/apache-hive-3.1.3-src.tar.gz

二、总结

由于篇幅太长担心占用你的时间,先把总结写到前面。

1、命令行输入 hive 命令 ,包括以下多种情况:

        a、hive -e "hql字符串" 

        b、hive -f hql文件

        c、hive -h

        d、hive --version

        e、hive --orcfiledump orc文件HDFS路径

        f、hive --rcfilecat  rc文件HDFS路径

        g、等等

2、初始化,包括

        a、配置相关路径

        b、hive启动脚本使用的jvm堆大小

        c、配置Hadoop、Spark、HBase等相关路径和环境变量

        d、添加distcp

        e、添加辅助jar

        f、等等

3、依次执行ext下的脚本(针对hive命令后面跟了什么样的服务)

4、执行ext/util下的脚本

5、执行默认的旧版CliDriver中main方法(cli.sh中有提到)

6、获取终端的输入并进行解析

        a、如果是 -e -f 会一次性解析并执行其中的hql

        b、如果不是会创建ConsoleReader和历史命令记录服务循环处理控制台输入的hql

三、脚本部分

注意:为了看起来清晰,会把不重要的部分省略掉

1、hive

#!/usr/bin/env bash

#......省略......

#初始化一些配置路径和hive启动脚本使用的jvm堆大小
. "$bin"/hive-config.sh

SERVICE=""
HELP=""
SKIP_HBASECP=false
SKIP_HADOOPVERSION=false

SERVICE_ARGS=()
#省略,这里我们只输入的hive,没有加其他参数
while [ $# -gt 0 ]; do
  case "$1" in
	#......省略......
  esac
done

if [ "$SERVICE" = "" ] ; then
  if [ "$HELP" = "_help" ] ; then
    SERVICE="help"
  else
	#默认走的服务是cli 即客户端
    SERVICE="cli"
  fi
fi

#beeline是 Hive 0.11版本引入的新命令行客户端工具,本篇博客先分析hive命令客户端
if [[ "$SERVICE" == "cli" && "$USE_BEELINE_FOR_HIVE_CLI" == "true" ]] ; then
  SERVICE="beeline"
fi


#conf文件夹下默认有个hive-env.sh.template 可以重命名为hive-env.sh来使用
#在此处设置HiveHive和Hadoop环境变量。这些变量可用于控制HiveHive的执行。
#管理员应该使用它来配置HiveHive安装(这样用户就不必设置环境变量或设置命令行参数来获得正确的行为)。
#正在调用的hivehive服务(CLI等)可通过环境变量SERVICE获得
if [ -f "${HIVE_CONF_DIR}/hive-env.sh" ]; then
  . "${HIVE_CONF_DIR}/hive-env.sh"
fi

if [[ -z "$SPARK_HOME" ]]
then
  bin=`dirname "$0"`
  # 现在很多hadoop集群中也按照了spark,这里加载下spark的以西配置
  if test -e $bin/../../spark; then 
    sparkHome=$(readlink -f $bin/../../spark)
    if [[ -d $sparkHome ]]
    then
      export SPARK_HOME=$sparkHome
    fi
  fi
fi

CLASSPATH="${TEZ_CONF_DIR:-/etc/tez/conf}:${HIVE_CONF_DIR}"

HIVE_LIB=${HIVE_HOME}/lib

# hive执行所必须的jar包
if [ ! -f ${HIVE_LIB}/hive-exec-*.jar ]; then
  echo "Missing Hive Execution Jar: ${HIVE_LIB}/hive-exec-*.jar"
  exit 1;
fi

if [ ! -f ${HIVE_LIB}/hive-metastore-*.jar ]; then
  echo "Missing Hive MetaStore Jar"
  exit 2;
fi

#客户端特定代码
if [ ! -f ${HIVE_LIB}/hive-cli-*.jar ]; then
  echo "Missing Hive CLI Jar"
  exit 3;
fi

# Hbase和Hadoop使用各自的log4j jar。  包括 hives log4j jar 可能会导致log4j警告
# 因此,将hives log4j-JAR保存在LOG_JAR_CLASSPATH中,并在Hbase和Hadoop调用完成后将其添加到类路径中
LOG_JAR_CLASSPATH="";

for f in ${HIVE_LIB}/*.jar; do
  if [[ $f == *"log4j"* ]]; then
    LOG_JAR_CLASSPATH=${LOG_JAR_CLASSPATH}:$f;
  else
    CLASSPATH=${CLASSPATH}:$f;
  fi
done

# 添加辅助 jars ,如serdes (ser和des :序列化器(Serializer)和反序列化器(Deserializer))
if [ -d "${HIVE_AUX_JARS_PATH}" ]; then
  hive_aux_jars_abspath=`cd ${HIVE_AUX_JARS_PATH} && pwd`
  for f in $hive_aux_jars_abspath/*.jar; do
    if [[ ! -f $f ]]; then
        continue;
    fi
    if $cygwin; then
	f=`cygpath -w "$f"`
    fi
    AUX_CLASSPATH=${AUX_CLASSPATH}:$f
    if [ "${AUX_PARAM}" == "" ]; then
        AUX_PARAM=file://$f
    else
        AUX_PARAM=${AUX_PARAM},file://$f;
    fi
  done
elif [ "${HIVE_AUX_JARS_PATH}" != "" ]; then 
  HIVE_AUX_JARS_PATH=`echo $HIVE_AUX_JARS_PATH | sed 's/,/:/g'`
  if $cygwin; then
      HIVE_AUX_JARS_PATH=`cygpath -p -w "$HIVE_AUX_JARS_PATH"`
      HIVE_AUX_JARS_PATH=`echo $HIVE_AUX_JARS_PATH | sed 's/;/,/g'`
  fi
  AUX_CLASSPATH=${AUX_CLASSPATH}:${HIVE_AUX_JARS_PATH}
  AUX_PARAM="file://$(echo ${HIVE_AUX_JARS_PATH} | sed 's/:/,file:\/\//g')"
fi

# 从辅助lib文件夹下添加jar包
for f in ${HIVE_HOME}/auxlib/*.jar; do
  if [[ ! -f $f ]]; then
      continue;
  fi
  if $cygwin; then
      f=`cygpath -w "$f"`
  fi
  AUX_CLASSPATH=${AUX_CLASSPATH}:$f
  if [ "${AUX_PARAM}" == "" ]; then
    AUX_PARAM=file://$f
  else
    AUX_PARAM=${AUX_PARAM},file://$f;
  fi
done
if $cygwin; then
    CLASSPATH=`cygpath -p -w "$CLASSPATH"`
    CLASSPATH=${CLASSPATH};${AUX_CLASSPATH}
else
    CLASSPATH=${CLASSPATH}:${AUX_CLASSPATH}
fi

# supress the HADOOP_HOME warnings in 1.x.x
export HADOOP_HOME_WARN_SUPPRESS=true 

# to make sure log4j2.x and jline jars are loaded ahead of the jars pulled by hadoop
export HADOOP_USER_CLASSPATH_FIRST=true

# 将类路径传递给hadoop
if [ "$HADOOP_CLASSPATH" != "" ]; then
  export HADOOP_CLASSPATH="${CLASSPATH}:${HADOOP_CLASSPATH}"
else
  export HADOOP_CLASSPATH="$CLASSPATH"
fi

# 还将hive类路径传递给hadoop
if [ "$HIVE_CLASSPATH" != "" ]; then
  export HADOOP_CLASSPATH="${HADOOP_CLASSPATH}:${HIVE_CLASSPATH}";
fi

# 检查路径中的hadoop
HADOOP_IN_PATH=`which hadoop 2>/dev/null`
if [ -f ${HADOOP_IN_PATH} ]; then
  HADOOP_DIR=`dirname "$HADOOP_IN_PATH"`/..
fi
# HADOOP_HOME env变量覆盖路径中的hadoop
HADOOP_HOME=${HADOOP_HOME:-${HADOOP_PREFIX:-$HADOOP_DIR}}
if [ "$HADOOP_HOME" == "" ]; then
  echo "Cannot find hadoop installation: \$HADOOP_HOME or \$HADOOP_PREFIX must be set or hadoop must be in the path";
  exit 4;
fi

# 将distcp添加到类路径,hive依赖于它 
#(Distcp是Hadoop自带的分布式复制程序,它是作为一个MapReduce作业来实现的,该复制作业是通过集群中并行运行的 map 来完成,此过程中没有 reduce。)
for f in ${HADOOP_HOME}/share/hadoop/tools/lib/hadoop-distcp-*.jar; do
  export HADOOP_CLASSPATH=${HADOOP_CLASSPATH}:$f;
done

HADOOP=$HADOOP_HOME/bin/hadoop
if [ ! -f ${HADOOP} ]; then
  echo "Cannot find hadoop installation: \$HADOOP_HOME or \$HADOOP_PREFIX must be set or hadoop must be in the path";
  exit 4;
fi

if [ "$SKIP_HADOOPVERSION" = false ]; then
  # 确保我们使用的是Hadoop的兼容版本
  if [ "x$HADOOP_VERSION" == "x" ]; then
      HADOOP_VERSION=$($HADOOP version 2>&2 | awk -F"\t" '/Hadoop/ {print $0}' | cut -d' ' -f 2);
  fi
  
  # 将正则表达式保存到var中,以解决引用Bash 3.1和3.2之间不兼容的问题
  hadoop_version_re="^([[:digit:]]+)\.([[:digit:]]+)(\.([[:digit:]]+))?.*$"
  
  if [[ "$HADOOP_VERSION" =~ $hadoop_version_re ]]; then
      hadoop_major_ver=${BASH_REMATCH[1]}
      hadoop_minor_ver=${BASH_REMATCH[2]}
      hadoop_patch_ver=${BASH_REMATCH[4]}
  else
      echo "Unable to determine Hadoop version information."
      echo "'hadoop version' returned:"
      echo `$HADOOP version`
      exit 5
  fi
  
  if [ "$hadoop_major_ver" -lt "1" -a  "$hadoop_minor_ver$hadoop_patch_ver" -lt "201" ]; then
      echo "Hive requires Hadoop 0.20.x (x >= 1)."
      echo "'hadoop version' returned:"
      echo `$HADOOP version`
      exit 6
  fi
fi

if [ "$SKIP_HBASECP" = false ]; then
  # HBase检测。需要bin/hbase和一个conf-dir来构建类路径条目。
  # 从HBASE_HOME和HBASE_CONF_DIR的BigTop默认值开始。
  HBASE_HOME=${HBASE_HOME:-"/usr/lib/hbase"}
  HBASE_CONF_DIR=${HBASE_CONF_DIR:-"/etc/hbase/conf"}
  if [[ ! -d $HBASE_CONF_DIR ]] ; then
    # 未显式设置,也未在BigTop位置中设置。请尝试在HBASE_HOME中查找。
    HBASE_CONF_DIR="$HBASE_HOME/conf"
  fi
  
  # 也许我们已经找到了HBase配置。如果是,请将其包含在类路径中。
  if [[ -d $HBASE_CONF_DIR ]] ; then
    export HADOOP_CLASSPATH="${HADOOP_CLASSPATH}:${HBASE_CONF_DIR}"
  fi
  
  # 查找hbase脚本。首先检查HBASE_HOME,然后询问PATH。
  if [[ -e $HBASE_HOME/bin/hbase ]] ; then
    HBASE_BIN="$HBASE_HOME/bin/hbase"
  fi
  HBASE_BIN=${HBASE_BIN:-"$(which hbase)"}
  
  # 也许我们已经找到了HBase。如果是,请将其详细信息包含在类路径中
  if [[ -n $HBASE_BIN ]] ; then
    # 不包括ZK、PB和Guava (See HIVE-2055)
    # 取决于 HBASE-8438 (hbase-0.94.14+, hbase-0.96.1+) for `hbase mapredcp` command
    for x in $($HBASE_BIN mapredcp 2>&2 | tr ':' '\n') ; do
      if [[ $x == *zookeeper* || $x == *protobuf-java* || $x == *guava* ]] ; then
        continue
      fi
      export HADOOP_CLASSPATH="${HADOOP_CLASSPATH}:${x}"
    done
  fi
fi

if [ "${AUX_PARAM}" != "" ]; then
  if [[ "$SERVICE" != beeline ]]; then
    HIVE_OPTS="$HIVE_OPTS --hiveconf hive.aux.jars.path=${AUX_PARAM}"
  fi
  AUX_JARS_CMD_LINE="-libjars ${AUX_PARAM}"
fi

SERVICE_LIST=""

#循环执行"$bin"/ext 的脚本 ,第2步我们看看这些脚本都做了什么
for i in "$bin"/ext/*.sh ; do
  . $i
done

#循环执行$bin"/ext/util 下的脚本 其实下面就一个脚本即:execHiveCmd.sh (hive命令最终也是靠它执行的)
for i in "$bin"/ext/util/*.sh ; do
  . $i
done

if [ "$DEBUG" ]; then
  if [ "$HELP" ]; then
    debug_help
    exit 0
  else
    get_debug_params "$DEBUG"
    export HADOOP_CLIENT_OPTS="$HADOOP_CLIENT_OPTS $HIVE_MAIN_CLIENT_DEBUG_OPTS"
  fi
fi

TORUN=""
for j in $SERVICE_LIST ; do
  if [ "$j" = "$SERVICE" ] ; then
    TORUN=${j}$HELP
  fi
done

# 初始化所有服务的日志记录

export HADOOP_CLIENT_OPTS="$HADOOP_CLIENT_OPTS -Dlog4j.configurationFile=hive-log4j2.properties "

if [ -f "${HIVE_CONF_DIR}/parquet-logging.properties" ]; then
  export HADOOP_CLIENT_OPTS="$HADOOP_CLIENT_OPTS -Djava.util.logging.config.file=${HIVE_CONF_DIR}/parquet-logging.properties "
else
  export HADOOP_CLIENT_OPTS="$HADOOP_CLIENT_OPTS -Djava.util.logging.config.file=$bin/../conf/parquet-logging.properties "
fi

if [[ "$SERVICE" =~ ^(hiveserver2|beeline|cli)$ ]] ; then
  # 如果进程是后台的,则不要更改终端设置
  if [[ ( ! $(ps -o stat= -p $$) =~ "+" ) && ! ( -p /dev/stdin ) && ( ! $(ps -o tty= -p $$) =~ "?" ) ]]; then
    export HADOOP_CLIENT_OPTS="$HADOOP_CLIENT_OPTS -Djline.terminal=jline.UnsupportedTerminal"
  fi
fi

# 将用于hive的log4jjar包含到类路径中
CLASSPATH="${CLASSPATH}:${LOG_JAR_CLASSPATH}"
export HADOOP_CLASSPATH="${HADOOP_CLASSPATH}:${LOG_JAR_CLASSPATH}"

if [ "$TORUN" = "" ] ; then
  echo "Service $SERVICE not found"
  echo "Available Services: $SERVICE_LIST"
  exit 7
else
  set -- "${SERVICE_ARGS[@]}"
  $TORUN "$@"
fi

2、ext 下的脚本

我们先看看ext下有哪些脚本,是不是很多,不要慌,静下心踏实的看懂才会触摸到“底层”的快乐

1、beeline.sh

# 需要参数 [host [port [db]]]
THISSERVICE=beeline
export SERVICE_LIST="${SERVICE_LIST}${THISSERVICE} "

beeline () {
  beeline  的主入口,这篇博客先不深入讨论
  CLASS=org.apache.hive.beeline.BeeLine;

  # 仅包括 beeline 客户端jar及其依赖项
  beelineJarPath=`ls ${HIVE_LIB}/hive-beeline-*.jar`
  superCsvJarPath=`ls ${HIVE_LIB}/super-csv-*.jar`
  jlineJarPath=`ls ${HIVE_LIB}/jline-*.jar`
  hadoopClasspath=""
  if [[ -n "${HADOOP_CLASSPATH}" ]]
  then
    hadoopClasspath="${HADOOP_CLASSPATH}:"
  fi
  export HADOOP_CLASSPATH="${hadoopClasspath}${HIVE_CONF_DIR}:${beelineJarPath}:${superCsvJarPath}:${jlineJarPath}"
  export HADOOP_CLIENT_OPTS="$HADOOP_CLIENT_OPTS -Dlog4j.configurationFile=beeline-log4j2.properties "

  exec $HADOOP jar ${beelineJarPath} $CLASS $HIVE_OPTS "$@"
}

beeline_help () {
  beeline "--help"
} 

2、cleardanglingscratchdir.sh

一个清理悬挂的暂存目录的工具。在某些情况下,可能会留下一个临时目录,例如当vm重新启动时,Hive没有机会运行shutdown hook。该工具将测试一个正在使用的暂存目录,如果没有,请将其删除。

我们依靠HDFS写锁来检测是否正在使用暂存目录:

1、HDFS客户端打开HDFS文件($scratchdir/inuse.lck)进行写入,并且只在会话关闭时关闭它

2、cleardanglingscratchDir可以尝试打开$scratchdir/inuse.lck进行写入。如果相应的HiveCli/HiveServer2仍在运行,我们将得到异常。否则,我们知道会话已经结束

3、如果HiveCli/HiveServer2在没有关闭HDFS文件的情况下死亡,NameNode将在10分钟后收回租约,即死亡的HiveCli-HiveServer2所持有的HDFS文件在10分钟之后可以再次写入。一旦它变为可写入,clearhangingscratchDir将能够将其删除

THISSERVICE=cleardanglingscratchdir
export SERVICE_LIST="${SERVICE_LIST}${THISSERVICE} "

cleardanglingscratchdir () {
  CLASS=org.apache.hadoop.hive.ql.session.ClearDanglingScratchDir
  HIVE_OPTS=''
  execHiveCmd $CLASS "$@"
}

cleardanglingscratchdir_help () {
  echo ""
  echo "usage ./hive --service cleardanglingscratchdir"
}

3、cli.sh

THISSERVICE=cli
export SERVICE_LIST="${SERVICE_LIST}${THISSERVICE} "

# 将旧的CLI设置为默认客户端
# 如果USE_DEPRECATED_CLI未设置或不等于false,请使用旧的CLI
if [ -z "$USE_DEPRECATED_CLI" ] || [ "$USE_DEPRECATED_CLI" != "false" ]; then
  USE_DEPRECATED_CLI="true"
fi

updateCli() {
  if [ "$USE_DEPRECATED_CLI" == "true" ]; then
    export HADOOP_CLIENT_OPTS=" -Dproc_hivecli $HADOOP_CLIENT_OPTS "
    #默认hive客户端的启动类为CliDriver,java部分我们也会详细看下它
    CLASS=org.apache.hadoop.hive.cli.CliDriver
    JAR=hive-cli-*.jar
  else
    export HADOOP_CLIENT_OPTS=" -Dproc_beeline $HADOOP_CLIENT_OPTS -Dlog4j.configurationFile=beeline-log4j2.properties"
    CLASS=org.apache.hive.beeline.cli.HiveCli
    JAR=hive-beeline-*.jar
  fi
}

cli () {
  updateCli
  execHiveCmd $CLASS $JAR "$@"
}

cli_help () {
  updateCli
  execHiveCmd $CLASS $JAR "--help"
}

4、debug.sh

允许通过JDI API连接到Hive来调试它

用法:hive--debug[:逗号分隔的参数列表]

参数列表:

        recursive=<y|n> :是否也应在调试模式下启动子JVM。默认值:y

        port=<port_number> :主JVM侦听调试连接的端口。默认值:8000

        mainSuspend=<y|n>:主JVM是否应等待调试器连接的执行。默认值:y

        childSuspend=<y|n>:子JVM是否应等待调试器连接的执行。默认值:n

        swapSuspend:交换主JVM和子JVM之间的挂起选项

5、fixacidkeyindex.sh

用于检查和修复ORC文件的ACID密钥索引,(如果由于HIVE-18817而写入错误)的实用程序。将在ORC文件中检查的条件是,acid键索引中的条带数是否与ORC StripeInformation中的条带数匹配。

补充:

ORC采用混合存储结构。不是一个单纯的列式存储格式,它遵循了先水平分区,再垂直分区的理念。它支持复杂数据类型、ACID支持及内置索引支持,非常适合海量数据的存储。

ORC文件是以二进制的方式存储的,不可以直接读取。它是文件是自包含的,读取它不需考虑用户使用环境,因为它本身存储了文件数据、数据类型及编码信息,不依赖于 Hive Metastore 或任何其他外部元数据。

ORC的主体由多个Stripe(也成为条带)组成,Stripe又包含三个部分:Index Data、Row Data和Stripe Footer。索引和数据部分都按列划分,因此只需要读取所需列的数据。

THISSERVICE=fixacidkeyindex
export SERVICE_LIST="${SERVICE_LIST}${THISSERVICE} "

fixacidkeyindex () {
  CLASS=org.apache.hadoop.hive.ql.io.orc.FixAcidKeyIndex
  HIVE_OPTS=''
  execHiveCmd $CLASS "$@"
}

使用:

./hive --service fixacidkeyindex [-h] --check-only|--recover [--backup-path <new-path>] <path_to_orc_file_or_directory>

解释:

        --check-only:检查acid orc文件的有效acid键索引,并在不修复的情况下退出

        --recover:如果需要修复,请修复acid orc文件的acid键索引

        --backup-path <new_path>:指定存储损坏文件的备份路径(默认:/tmp)

        --help (-h):Print help message

6、help.sh

打印hive命令的使用信息,帮助你使用

7、hiveburninclient.sh

HiveBurnInClient是该脚本最后执行的java主类,内容也很简单,通过jdbc连接hive,创建两张表,并加载./examples/files/kv1.txt和./examples/files/kv2.txt到表中,进行单表查询和关联查询,并记录每次执行sql的时间

THISSERVICE=hiveburninclient
export SERVICE_LIST="${SERVICE_LIST}${THISSERVICE} "

hiveburninclient() {
  echo "Starting hiveburninclient"
  CLASS=org.apache.hive.testutils.jdbc.HiveBurnInClient
  if $cygwin; then
    HIVE_LIB=`cygpath -w "$HIVE_LIB"`
  fi
  JAR=${HIVE_LIB}/hive-service-*.jar
  exec $HADOOP jar $JAR $CLASS $HIVE_OPTS "$@"
}

hiveburninclient_help() {
  hiveburninclient -H
}

8、hiveserver2.sh

HiveServer2(HS2)是一种使客户端能够针对Hive执行查询的服务。HiveServer2是已弃用的HiveServer1的继任者。HS2支持多客户端并发和身份验证。它旨在为JDBC和ODBC等开放式API客户端提供更好的支持。

HS2是作为复合服务运行的单个进程,其中包括基于Thrift的Hive服务(TCP或HTTP)和用于web UI的Jetty web服务器。

THISSERVICE=hiveserver2
export SERVICE_LIST="${SERVICE_LIST}${THISSERVICE} "

hiveserver2() {
  >&2 echo "$(timestamp): Starting HiveServer2"
  CLASS=org.apache.hive.service.server.HiveServer2
  if $cygwin; then
    HIVE_LIB=`cygpath -w "$HIVE_LIB"`
  fi
  JAR=${HIVE_LIB}/hive-service-[0-9].*.jar

  export HADOOP_CLIENT_OPTS=" -Dproc_hiveserver2 $HADOOP_CLIENT_OPTS "
  export HADOOP_OPTS="$HIVESERVER2_HADOOP_OPTS $HADOOP_OPTS"
  exec $HADOOP jar $JAR $CLASS $HIVE_OPTS "$@"
}

hiveserver2_help() {
  hiveserver2 -H
}

timestamp()
{
 date +"%Y-%m-%d %T"
}

9、hplsql.sh

编译并运行HPL/SQL脚本,

THISSERVICE=hplsql
export SERVICE_LIST="${SERVICE_LIST}${THISSERVICE} "

hplsql () {
  CLASS=org.apache.hive.hplsql.Hplsql;

  # 仅包括HPL/SQL jar及其依赖项
  hplsqlJarPath=`ls ${HIVE_LIB}/hive-hplsql-*.jar`
  antlrJarPath="${HIVE_LIB}/antlr-runtime-4.5.jar"
  hadoopClasspath=""
  if [[ -n "${HADOOP_CLASSPATH}" ]]
  then
    hadoopClasspath="${HADOOP_CLASSPATH}:"
  fi
  export HADOOP_CLASSPATH="${hadoopClasspath}${HIVE_CONF_DIR}:${hplsqlJarPath}:${antlrJarPath}"

  exec $HADOOP jar ${hplsqlJarPath} $CLASS $HIVE_OPTS "$@"
}

hplsql_help () {
  hplsql "--help"
} 

10、jar.sh

用于需要Hadoop和Hive类路径和环境的应用程序,

./hive --service jar <yourjar> <yourclass> HIVE_OPTS <your_args>

11、lineage.sh

给定一个hql,LineageInfo主类负责解析给定的查询并获取沿袭信息(ParseDriver负责解析hql获取AST树)目前,这只打印给定hql的输入和输出表

THISSERVICE=lineage
export SERVICE_LIST="${SERVICE_LIST}${THISSERVICE} "

lineage () {
  CLASS=org.apache.hadoop.hive.ql.tools.LineageInfo

  # cli特定代码
  if [ ! -f ${HIVE_LIB}/hive-exec-*.jar ]; then
    echo "Missing Hive exec Jar"
    exit 3;
  fi

  if $cygwin; then
    HIVE_LIB=`cygpath -w "$HIVE_LIB"`
  fi

  exec $HADOOP jar ${HIVE_LIB}/hive-exec-*.jar $CLASS  "$@"
}

lineage_help () {
  echo "usage ./hive --service lineage 'hql' "
} 

hive -service lineage 'select * from personal_info_test where id =2'

可以看下只输出了输入表的表名

12、llap.sh

Hive2.0时添加的这个功能

llap是Live Long and Prosper(生生不息,繁荣昌盛)的缩写,是一个常用的祝福语,意为“长寿和繁荣”,它来自于美国电视剧《星际迷航》中的一个著名台词,由主角斯波克(Spock)所说。这句话传达了对他人健康长寿和事业兴旺的祝愿。

在hive中表示Live-Long And Process(常驻进程)可以进一步提升Hive的执行速度

从脚本中我们可以看到还用python启动了在yarn上的LLAP服务

关于Hive 的 LLAP功能我们会专门用一篇博客来讲,记得关注我哟


THISSERVICE=llap
export SERVICE_LIST="${SERVICE_LIST}${THISSERVICE} "

llap () {
  TMPDIR=$(mktemp -d /tmp/staging-yarn-XXXXXX)
  CLASS=org.apache.hadoop.hive.llap.cli.LlapServiceDriver;
  if [ ! -f ${HIVE_LIB}/hive-cli-*.jar ]; then
    echo "Missing Hive CLI Jar"
    exit 3;
  fi

  if $cygwin; then
    HIVE_LIB=`cygpath -w "$HIVE_LIB"`
  fi

  set -e;

  export HADOOP_CLIENT_OPTS=" -Dproc_llapcli $HADOOP_CLIENT_OPTS -Dlog4j.configurationFile=llap-cli-log4j2.properties "
  # hadoop 20 or newer - skip the aux_jars option. picked up from hiveconf
  $HADOOP $CLASS $HIVE_OPTS -directory $TMPDIR "$@"
  
  # check for config files
  test -f $TMPDIR/config.json

  python $HIVE_HOME/scripts/llap/yarn/package.py --input $TMPDIR "$@"

  # remove temp files
  rm -rf $TMPDIR
}

llap_help () {
  CLASS=org.apache.hadoop.hive.llap.cli.LlapServiceDriver;
  execHiveCmd $CLASS "--help"
} 

13、llapdump.sh

通过LLAP输入格式测试查询和数据检索的实用程序

THISSERVICE=llapdump
export SERVICE_LIST="${SERVICE_LIST}${THISSERVICE} "

llapdump () {
  CLASS=org.apache.hadoop.hive.llap.LlapDump
  HIVE_OPTS=''
  execHiveCmd $CLASS "$@"
}

llapdump_help () {
  echo "usage ./hive --service llapdump [-l <url>] [-u <user>] [-p <pwd>] <query>"
  echo ""
  echo "  --location (-l)  hs2 url"
  echo "  --user (-u)      user name"
  echo "  --pwd (-p)       password"
}

hive --service llapdump 'select * from personal_info_test where id =2'

14、llapstatus.sh

负责变更LLAP服务的状态

THISSERVICE=llapstatus
export SERVICE_LIST="${SERVICE_LIST}${THISSERVICE} "

llapstatus () {
  CLASS=org.apache.hadoop.hive.llap.cli.LlapStatusServiceDriver;
  if [ ! -f ${HIVE_LIB}/hive-cli-*.jar ]; then
    echo "Missing Hive CLI Jar"
    exit 3;
  fi

  if $cygwin; then
    HIVE_LIB=`cygpath -w "$HIVE_LIB"`
  fi

  set -e;

  export HADOOP_CLIENT_OPTS=" -Dproc_llapstatuscli $HADOOP_CLIENT_OPTS -Dlog4j.configurationFile=llap-cli-log4j2.properties "
  # hadoop 20 or newer - skip the aux_jars option. picked up from hiveconf
  $HADOOP $CLASS $HIVE_OPTS "$@"
  
}

llapstatus_help () {
  CLASS=org.apache.hadoop.hive.llap.cli.LlapStatusServiceDriver;
  execHiveCmd $CLASS "--help"
} 

15、metastore.sh

基于HadoopThriftAuthBridge 启动Metastore

HadoopThriftAuthBridge是将Thrift的SASL传输桥接到Hadoop的SASL回调处理程序和身份验证类的函数

THISSERVICE=metastore
export SERVICE_LIST="${SERVICE_LIST}${THISSERVICE} "

metastore() {
  echo "$(timestamp): Starting Hive Metastore Server"
  CLASS=org.apache.hadoop.hive.metastore.HiveMetaStore
  if $cygwin; then
    HIVE_LIB=`cygpath -w "$HIVE_LIB"`
  fi
  JAR=${HIVE_LIB}/hive-metastore-*.jar

  # hadoop 20 or newer - skip the aux_jars option and hiveconf

  export HADOOP_CLIENT_OPTS=" -Dproc_metastore $HADOOP_CLIENT_OPTS "
  export HADOOP_OPTS="$HIVE_METASTORE_HADOOP_OPTS $HADOOP_OPTS"
  exec $HADOOP jar $JAR $CLASS "$@"
}

metastore_help() {
  metastore -h
}

timestamp()
{
 date +"%Y-%m-%d %T"
}

16、metatool.sh

此类为配置单元管理员提供了一个工具

        1、使用DataNucleus对元存储执行JDOQL (JDO其实就是jdbc,因为hive-site.xml中关于metastore的配置都是javax.jdo.xxx)

        2、执行HA名称节点升级

THISSERVICE=metatool
export SERVICE_LIST="${SERVICE_LIST}${THISSERVICE} "

metatool () {
  HIVE_OPTS=''
  CLASS=org.apache.hadoop.hive.metastore.tools.HiveMetaTool
  execHiveCmd $CLASS "$@"
}

metatool_help () {
  HIVE_OPTS=''
  CLASS=org.apache.hadoop.hive.metastore.tools.HiveMetaTool
  execHiveCmd $CLASS "--help"
}

17、orcfiledump.sh

用于查看或修复orc文件的工具

hive --service orcfiledump --help

THISSERVICE=orcfiledump
export SERVICE_LIST="${SERVICE_LIST}${THISSERVICE} "

orcfiledump () {
  CLASS=org.apache.orc.tools.FileDump
  HIVE_OPTS=''
  execHiveCmd $CLASS "$@"
}

orcfiledump_help () {
  echo "usage ./hive orcfiledump [-h] [-j] [-p] [-t] [-d] [-r <col_ids>] [--recover] [--skip-dump] [--backup-path <new-path>] <path_to_orc_file_or_directory>"
  echo ""
  echo "  --json (-j)                 Print metadata in JSON format"
  echo "  --pretty (-p)               Pretty print json metadata output"
  echo "  --timezone (-t)             Print writer's time zone"
  echo "  --data (-d)                 Should the data be printed"
  echo "  --rowindex (-r) <col_ids> Comma separated list of column ids for which row index should be printed"
  echo "  --recover                   Recover corrupted orc files generated by streaming"
  echo "  --skip-dump                 Used along with --recover to directly recover files without dumping"
  echo "  --backup-path <new_path>  Specify a backup path to store the corrupted files (default: /tmp)"
  echo "  --help (-h)                 Print help message"
} 

我们创建一个orc表并插入些数据来实践下这个命令

create table if not exists test.personal_info_temp_orc
(id int comment 'id',
name string comment '姓名',
age string comment '年龄' ,
sex string comment '性别:1男0女2其他' ,
telno string comment '手机号' )
row format delimited
fields terminated by ','
stored as orc
;

#hive ORC表的数据不能通过hive客户端load数据文件加载,也不能使用hdfs dfs -put上传到对应目录
#只能通过insert 方式插入数据

insert into personal_info_temp_orc select * from ods.personal_info_temp order by id ;

#获取orc文件信息

 hive --orcfiledump /user/hive/warehouse/test.db/personal_info_temp_orc/000000_0

18、rcfilecat.sh

RCFile 和 ORCFile一样都是行列式存储文件,ORCFile为优化后的行列式存储文件

THISSERVICE=rcfilecat
export SERVICE_LIST="${SERVICE_LIST}${THISSERVICE} "

rcfilecat () {
  CLASS=org.apache.hadoop.hive.cli.RCFileCat
  HIVE_OPTS=''
  execHiveCmd $CLASS "$@"
}

rcfilecat_help () {
  echo "usage ./hive rcfilecat [--start='startoffset'] [--length='len'] "
} 

我们创建一个RCFile 格式的表并插入些数据来实践下这个命令

create table if not exists test.personal_info_temp_rc_file
(id int comment 'id',
name string comment '姓名',
age string comment '年龄' ,
sex string comment '性别:1男0女2其他' ,
telno string comment '手机号' )
row format delimited
fields terminated by ','
stored as rcfile
;

#hive ORC表的数据不能通过hive客户端load数据文件加载,也不能使用hdfs dfs -put上传到对应目录
#只能通过insert 方式插入数据

insert into personal_info_temp_rc_file select * from ods.personal_info_temp order by id ;

#获取orc文件信息

hive --rcfilecat /user/hive/warehouse/test.db/personal_info_temp_rc_file /000000_0

19、schemaTool.sh

这是一个初始化Hive元数据的工具,使用方法为(使用之前需要在hive-site.xml中正确填写元数据库的连接、用户名、密码)

schematool -dbType mysql -initSchema

THISSERVICE=schemaTool
export SERVICE_LIST="${SERVICE_LIST}${THISSERVICE} "

schemaTool() {
  HIVE_OPTS=''
  CLASS=org.apache.hive.beeline.HiveSchemaTool
  execHiveCmd $CLASS "$@"
}

schemaTool_help () {
  HIVE_OPTS=''
  CLASS=org.apache.hive.beeline.HiveSchemaTool
  execHiveCmd $CLASS "--help"
}

20、strictmanagedmigration.sh

HiveStrictManagedMigration是这个脚本对应的java类,会循环每个数据库并把他们移动到hive-site.xml中hive.metastore.warehouse.dir对应的路径下,默认为/user/hive/warehouse

如果我们有三个数据库 default、ods、dwd

在default下建的表放在了/user/hive/warehouse 下

在ods下建的表放在了/user/hive/warehouse/ods.db 下

在dwd下建的表放在了/user/hive/warehouse/dwd.db 下

THISSERVICE=strictmanagedmigration
export SERVICE_LIST="${SERVICE_LIST}${THISSERVICE} "

strictmanagedmigration () {
  CLASS=org.apache.hadoop.hive.ql.util.HiveStrictManagedMigration
  HIVE_OPTS=''
  execHiveCmd $CLASS "$@"
}

strictmanagedmigration_help () {
  strictmanagedmigration "--help"
}

21、tokentool.sh

用于操作MetaStore委派令牌的工具

22、version.sh

输出Hive的版本信息,基本每个工具都有这个功能,比如 java -version 等等

Hive 对应的命令是 hive --version 会输出版本信息、版本控制地址、提交的作者和时间、纠错码

3、ext/util下的脚本

这里只有一个脚本:execHiveCmd.sh

相比在很多脚本中都有它的身影,很多脚本对应的主类都是传递给它来运行的

CLI_JAR="hive-cli-*.jar"
BEELINE_JAR="hive-beeline-*.jar"

execHiveCmd () {
  CLASS=$1;
  shift;

  # 如果jar未作为参数传递,请使用相应的cli-jar
  if [ "$1" == "$CLI_JAR" ] || [ "$1" == "$BEELINE_JAR" ]; then
    JAR="$1"
    shift;
  else
    if [ "$USE_DEPRECATED_CLI" == "true" ]; then
      JAR="$CLI_JAR"
    else
      JAR="$BEELINE_JAR"
    fi
  fi

  # cli specific code
  if [ ! -f ${HIVE_LIB}/$JAR ]; then
    echo "Missing $JAR Jar"
    exit 3;
  fi

  if $cygwin; then
    HIVE_LIB=`cygpath -w "$HIVE_LIB"`
  fi

  # hadoop 20 or newer - skip the aux_jars option. picked up from hiveconf
  exec $HADOOP jar ${HIVE_LIB}/$JAR $CLASS $HIVE_OPTS "$@"
}

四、java部分

在cli.sh脚本中我们已经分析了默认hive客户端的启动类为CliDriver,下面我们就从CliDriver的main方法开始捋(不是主要的代码会省略掉,方便我们理清主线逻辑)

1、main

这部分代码很简单,我们接着往下看

  public static void main(String[] args) throws Exception {
    int ret = new CliDriver().run(args);
    //终止当前运行的Java虚拟机。参数用作状态代码;按照惯例,非零状态代码表示异常终止。
    System.exit(ret);
  }

2、run

  public  int run(String[] args) throws Exception {

    OptionsProcessor oproc = new OptionsProcessor();
    //从参数设置hive的环境变量,如果中间出现异常返回 1 终止虚拟机
    if (!oproc.process_stage1(args)) {
      return 1;
    }

    //......省略......
    
    //Hive客户端会话状态类
    CliSessionState ss = new CliSessionState(new HiveConf(SessionState.class));
    //把系统“标准”输入流、输出流、错误流 赋给 Hive客户端会话状态类 
    //如果期间有错误 返回 3 终止虚拟机
    ss.in = System.in;
    try {
      ss.out = new PrintStream(System.out, true, "UTF-8");
      ss.info = new PrintStream(System.err, true, "UTF-8");
      ss.err = new CachingPrintStream(System.err, true, "UTF-8");
    } catch (UnsupportedEncodingException e) {
      return 3;
    }

    //判断 hive命令后面的参数 比如 hive -e “hql” hive -f xxx.hql 等
    //这里就会根据命令行的参数初始化以下变量
    //    ss.database    执行的数据库
    //    ss.execString  -e 后面要执行的hql
    //    ss.fileName    -f 包含hql的文件
    //    ss.initFiles     
    if (!oproc.process_stage2(ss)) {
      return 2;
    }



    //设置通过命令行指定的所有属性
    HiveConf conf = ss.getConf();
    for (Map.Entry<Object, Object> item : ss.cmdProperties.entrySet()) {
      conf.set((String) item.getKey(), (String) item.getValue());
      ss.getOverriddenConfigurations().put((String) item.getKey(), (String) item.getValue());
    }

    //读取提示配置并替换变量。
    prompt = conf.getVar(HiveConf.ConfVars.CLIPROMPT);
    prompt = new VariableSubstitution(new HiveVariableSource() {
      @Override
      public Map<String, String> getHiveVariable() {
        return SessionState.get().getHiveVariables();
      }
    }).substitute(conf, prompt);
    prompt2 = spacesForString(prompt);

    if (HiveConf.getBoolVar(conf, ConfVars.HIVE_CLI_TEZ_SESSION_ASYNC)) {
      //以fire-and-forget 的方式启动会话。当需要会话的异步初始化部分时,
      //相应的getter和其他方法将根据需要等待。
      //fire-and-forget :把消息发送给服务器,但并不关心是否都到
      SessionState.beginStart(ss, console);
    } else {
      SessionState.start(ss);
    }

    ss.updateThreadName();

    //创建视图注册表
    HiveMaterializedViewsRegistry.get().init();

    //执行cli驱动程序工作
    try {
      return executeDriver(ss, conf, oproc);
    } finally {
      ss.resetThreadName();
      ss.close();
    }
  }

3、executeDriver

  /**
   * 执行Hive客户端的任务
   * @param ss CLI driver 的 session状态
   * @param conf Hive的配置信息
   * @param CLI 调用的操作处理器
   * @return 执行命令的状态
   * @throws Exception
   */  
  private int executeDriver(CliSessionState ss, HiveConf conf, OptionsProcessor oproc)
      throws Exception {

    CliDriver cli = new CliDriver();
    //设置cli的关于hive的环境变量
    cli.setHiveVariables(oproc.getHiveVariables());

    //如果指定,请使用指定的数据库
    cli.processSelectDatabase(ss);

    //执行-i init文件(始终处于静默模式)
    cli.processInitFiles(ss);

    //如果命令行带了 -e 参数 ,现在需要处理 -e 后面的 hql
    if (ss.execString != null) {
      //处理一行分号分隔的命令
      int cmdProcessStatus = cli.processLine(ss.execString);
      return cmdProcessStatus;
    }

    try {
      //如果命令行带了 -f 参数 ,现在需要处理 -f 里面的 hql
      if (ss.fileName != null) {
        return cli.processFile(ss.fileName);
      }
    } catch (FileNotFoundException e) {
      System.err.println("Could not open input file for reading. (" + e.getMessage() + ")");
      return 3;
    }
    //判断hive当前的执行引擎是否是 mr
    if ("mr".equals(HiveConf.getVar(conf, ConfVars.HIVE_EXECUTION_ENGINE))) {
      console.printInfo(HiveConf.generateMrDeprecationWarning());
    }

    //创建ConsoleReader并启动,读取用户输入,遇到“;”为一个完整的命令
    //并开启命令历史记录服务,将命令写入文件中
    setupConsoleReader();

    String line;
    int ret = 0;
    String prefix = "";
    String curDB = getFormattedDb(conf, ss);
    String curPrompt = prompt + curDB;
    String dbSpaces = spacesForString(curDB);

    //如果不是 -e -f 这样的一次性执行命令,那么就是需要一直持续解析用户输入的命令
    while ((line = reader.readLine(curPrompt + "> ")) != null) {
      if (!prefix.equals("")) {
        prefix += '\n';
      }
      //--会判断为你在hive控制台输入的注释,跳过
      if (line.trim().startsWith("--")) {
        continue;
      }
      //如果遇到 ; 就判断结尾,因此如果你一行输入两条hql,只会解析第一条hql
      if (line.trim().endsWith(";") && !line.trim().endsWith("\\;")) {
        line = prefix + line;
        //解析并执行这条hql 我们会在一篇博客中详细介绍一条hql执行的过程
        ret = cli.processLine(line, true);
        prefix = "";
        curDB = getFormattedDb(conf, ss);
        curPrompt = prompt + curDB;
        dbSpaces = dbSpaces.length() == curDB.length() ? dbSpaces : spacesForString(curDB);
      } else {
        prefix = prefix + line;
        curPrompt = prompt2 + dbSpaces;
        continue;
      }
    }

    return ret;
  }

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

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

相关文章

【Linux】软件管理器yum和编辑器vim

&#x1f525;博客主页&#xff1a; 小羊失眠啦. &#x1f3a5;系列专栏&#xff1a;《C语言》 《数据结构》 《C》 《Linux》 《Cpolar》 ❤️感谢大家点赞&#x1f44d;收藏⭐评论✍️ 文章目录 一、Linux下安装软件的方案1.1 源代码安装1.2 rpm安装1.3 yum安装 二、Linux软件…

备战2024年汉字小达人活动:历年区级样题练习和解析

今天我们来看一下汉字小达人活动的第一轮选拔的区级样题。区级样题是中文自修杂志社&#xff08;主办方&#xff09;发布的试题&#xff0c;主要是给学校老师选拔参考使用的&#xff0c;据了解&#xff0c;很多学校老师是直接用这个样卷在学校组织选拔&#xff0c;选拔成绩突出…

虚拟主播视频制作,低成本的数字人播报方案

传统的视频制作方式往往面临着成本高、周期长、人力投入大等挑战。为了满足企业对于高效、低成本视频制作的需求&#xff0c;美摄科技凭借其强大的技术研发实力&#xff0c;推出了面向企业的虚拟主播视频解决方案&#xff0c;为企业带来了全新的数字人播报视频制作体验。 美摄…

SVG 渐变边框在 CSS 中的应用

SVG 渐变边框在 CSS 中的应用 <template><div class"home"><div class"one"><svg width"100%" height"100%"><rect x"2" y"2" width"100%" height"100%" fill&q…

『 Linux 』Process Control进程控制(万字)

文章目录 &#x1f996; 前言&#x1f996; fork()函数调用失败原因&#x1f996; 进程终止&#x1f4a5; 进程退出码&#x1f4a5; 进程正常退出 &#x1f996; 进程等待&#x1f4a5; 僵尸进程&#x1f4a5; 如何解决僵尸进程的内存泄漏问题&#x1f4a5; wait( )/waitpid( )…

单链表的实现(数据结构)

本篇博客主要是单链表&#xff08;无头单项不循环&#xff09;的实现的代码分享 说明&#xff1a;因为此单链表无头&#xff08;哨兵位&#xff09;&#xff0c;可以说成没有初始化也可以说初始化时没有一个有效地址作为单链表的起始地址 例如下面代码中的plist NULL。 所以在…

MS5188N——16bit、8 通道、500kSPS、 SAR 型 ADC

产品简述 MS5188N 是 8 通道、 16bit 、电荷再分配逐次逼近型模数 转换器&#xff0c;采用单电源供电。 MS5188N 拥有多通道、低功耗数据采集系统所需的所有 组成部分&#xff0c;包括&#xff1a;无失码的真 16 位 SAR ADC &#xff1b;用于将输入配 置为单端输入…

开源爬虫技术在金融行业市场分析中的应用与实战解析

一、项目介绍 在当今信息技术飞速发展的时代&#xff0c;数据已成为企业最宝贵的资产之一。特别是在${industry}领域&#xff0c;海量数据的获取和分析对于企业洞察市场趋势、优化产品和服务至关重要。在这样的背景下&#xff0c;爬虫技术应运而生&#xff0c;它能够高效地从互…

字符串索引错误解决方案

字符串索引错误通常是由于尝试访问字符串中不存在的索引位置而引起的。我在Python编译中&#xff0c;字符串是一个不可变的序列&#xff0c;可以通过索引访问其中的字符。如果尝试访问超出字符串长度范围的索引位置&#xff0c;将引发IndexError异常。所以下面的问题如果遇到了…

运维知识点-Tomcat

Tomcat tomcat日志告警tomcat文件包含读取漏洞Tomcat ### 远程代码执行(7.0.0-7.0.81) 开启PUT,访问127.0.0.1:8080改PUT,创建x.jsp,写入shellwar后文件部署,登入特定后台,上传包含jsp写的war文件。文件解析tomcat日志告警 cat catalina.sh /usr/local/tomcat/confTo…

运维知识点-JBoss

JBoss 介绍介绍 JBoss是一个基于J2EE的开放源代码的应用服务器,也是一个运行EJB(Enterprise JavaBean)的容器和服务器。它支持EJB 1.1、EJB 2.0和EJB3的规范,体现了J2EE规范中最新的技术。JBoss遵循LGPL许可,可以在任何商业应用中免费使用,并且由开源社区开发,这使得JB…

345.反转字符串中的元音字母

题目&#xff1a;给你一个字符串 s &#xff0c;仅反转字符串中的所有元音字母&#xff0c;并返回结果字符串。 元音字母包括 a、e、i、o、u&#xff0c;且可能以大小写两种形式出现不止一次。 class Solution {//画图&#xff0c;好理解点public String reverseVowels(String…

MySQL常见的存储引擎介绍

我将为您详细讲解 MySQL 常见的存储引擎&#xff0c;以及它们的使用场景、特点、区别和优势。MySQL 支持多种存储引擎&#xff0c;每种存储引擎都有其特定的优势和局限性。了解这些存储引擎的特点和适用场景对于选择合适的存储引擎以及优化数据库性能至关重要。 1. InnoDB 存储…

搞不完的事情,大不了加班?

工作是生活的一部分&#xff0c;但当你发现搞不完的事情&#xff0c;大不了加班&#xff01;你就会陷入无限的循环。 如果你想早点下班 &#xff0c;并且好好做自己的账号&#xff0c;还是少看哪些月入5万-10万的博主&#xff01; 如果你照着大V账号模仿大概率会失败&#xff…

python统计日志中数据从开始到结束的响应时间的最大值、最小值、平均值、中位数

应用场景&#xff1a;需要根据日志文件&#xff0c;统计出数据从开始下发到收到回复所需的时间&#xff0c;包括最大值、最小值、平均值、中位数。 日志格式如图类似&#xff0c;每一行日志开始部分就是所需要截取的时间&#xff1b;1条日记是以某些关键词作为开始&#xff0c;…

R语言自定义颜色

一、创建颜色梯度&#xff08;渐变色&#xff09; 在绘热图时&#xff0c;需要将数值映射到不同的颜色上&#xff0c;这时就需要一系列的颜色梯度colorRampPalette 函数支持自定义的创建一系列的颜色梯度。 代码示例&#xff1a; library(RColorBrewer)x <- colorRampPal…

从新能源汽车行业自动驾驶技术去看AI的发展未来趋势

自动驾驶汽车关键技术主要包括环境感知、精准定位、决策与规划、控制与执行、高精地图与车联网V2X以及自动驾驶汽车测试与验证技术等。 &#x1f413; 自动驾驶技术 这是AI在汽车行业中应用最广泛的领域之一。自动驾驶技术利用AI算法和传感器来感知环境、识别障碍物&#xff0c…

购买阿里云服务器如何选择实例?根据业务场景与细分场景推荐实例规格

对于很多初次购买阿里云服务器的用户来说&#xff0c;面对众多可选择的云服务器实例规格&#xff0c;往往不知道如何选择&#xff0c;不同实例规格适用于不同的业务场景&#xff0c;本文为大家汇总了不同业务场景和细分场景下应该选择的主要实例规格&#xff0c;以及这些实例规…

传统应急照明解决方案和新标准下地铁应急照明的方案区别

传统地铁站应急照明系统方案 传统地铁站应急照明系统一般设置2套或4套,给相应端区域的应急照明提供电源。由于地铁站应急照明系统设计比较成熟&#xff0c;几乎所有的地铁站接线方案均采用了经典的双电源切换加蓄电池逆变交流220/380V的配电方式.以南方某地铁站为例,此地铁站是…

YoloV8改进策略:Block改进|自研Block,涨点超猛|代码详解|附结构图

涨点效果 涨点效果:在我自己的数据集上,mAP50 由0.986涨到了0.993,mAP50-95由0.737涨到0.757,涨点明显! 参考模型 参考的Block,如下图: 我对Block做了修改,修改后的结构图如下: 代码详解 from timm.models.layers import DropPathfrom torch import Tensor def …