Spark读写HBase(主要讲解SHC的使用)

article/2025/10/29 23:28:00

前言

Spark读写HBase本身来说是没啥可以讲的,最早之前都是基于RDD的,网上的资料就太多了,可以参考:
参考链接1
参考链接2
其实都一样,后来有了Hortonworks公司的研发人员研发了一个Apache Spark - Apache HBase Connector,也就是我们熟悉的shc,通过这个类库,我们可以直接使用 Spark SQL 将 DataFrame 中的数据写入到 HBase 中,具体详细的介绍资料可以参考:
shc的github
国内大佬的总结
再后来,就有了Spark HBase Connector (hbase-spark)
一个国外的哥们总结过这几种方式,他写了一篇博客叫《Which Spark HBase Connector to use in 2019?》
写的比较详细,不过很遗憾的是,我测试了hbase-spark后,发现失败了,因为导入jar包后发现仍然缺少import org.apache.spark.sql.execution.datasources.hbase包,有时间重新测试。
其实国内的博客也有这三种方式的简单介绍,只不过没有那么详细。
我这篇博客主要是针对SHC进行的测试

SHC如何使用

研究一个框架和技术,请毫不犹豫的选择官方给的文档和案例,SHC在github中的README里写的十分详细了,我这里就简单的描述一下流程:
最简单的方式:

./bin/spark-submit  --class your.application.class --master yarn-client  --packages com.hortonworks:shc-core:1.1.1-2.1-s_2.11 --repositories http://repo.hortonworks.com/content/groups/public/ --files /etc/hbase/conf/hbase-site.xml /To/your/application/jar

不少人也试过这个方式,但是我不推荐,因为每提交一次都要下载无数的依赖包。

我建议是编译源码包然后通过Maven引入

这种方式也有不少人使用,大家可以参考这个,不过这个是本地测试的,我一般是直接在集群上使用,这里简单汇总一下流程

  1. 下载shc源码包
    在这里插入图片描述
    具体下载哪个我个人认为以你集群的HBase版本为准,如果HBase为1.X则下载下面的,2.X则下载上面的即可

  2. 编译源码包
    如果不修改pom文件,那么可以直接在源码包根目录下执行mvn的编译命令:

mvn install -DskipTests

如果要修改,可以参考这个,我个人认为只要大的版本相同,完全可以不用修改,比如我的Spark是2.4.0 HBase是1.2.0,直接编译完全没有问题

  1. 自己代码的pom文件中引入shc-core依赖
    <dependency><groupId>com.hortonworks</groupId><artifactId>shc-core</artifactId><version>1.1.2-2.2-s_2.11</version></dependency>

再导入Scala Spark相关依赖,我pom文件大概是这样的:

<properties><scala.version>2.11.8</scala.version><spark.version>2.4.0</spark.version><java.version>1.8</java.version>
</properties><pluginRepositories><pluginRepository><id>scala-tools.org</id><name>Scala-Tools Maven2 Repository</name><url>http://scala-tools.org/repo-releases</url></pluginRepository>
</pluginRepositories><dependencies><dependency><groupId>org.scala-lang</groupId><artifactId>scala-library</artifactId><version>${scala.version}</version></dependency><dependency><groupId>org.scala-lang</groupId><artifactId>scala-compiler</artifactId><version>${scala.version}</version></dependency><dependency><groupId>org.scala-lang</groupId><artifactId>scala-reflect</artifactId><version>${scala.version}</version></dependency><dependency><groupId>org.scala-lang</groupId><artifactId>scalap</artifactId><version>${scala.version}</version></dependency><dependency><groupId>org.apache.spark</groupId><artifactId>spark-core_2.11</artifactId><version>${spark.version}</version></dependency><dependency><groupId>org.apache.spark</groupId><artifactId>spark-sql_2.11</artifactId><version>${spark.version}</version></dependency><dependency><groupId>com.hortonworks</groupId><artifactId>shc-core</artifactId><version>1.1.2-2.2-s_2.11</version></dependency>
</dependencies><build><plugins><plugin><artifactId>maven-assembly-plugin</artifactId><configuration><classifier>dist</classifier><appendAssemblyId>true</appendAssemblyId><descriptorRefs><descriptor>jar-with-dependencies</descriptor></descriptorRefs></configuration><executions><execution><id>make-assembly</id><phase>package</phase><goals><goal>single</goal></goals></execution></executions></plugin><plugin><artifactId>maven-compiler-plugin</artifactId><configuration><source>1.7</source><target>1.7</target></configuration></plugin><plugin><groupId>net.alchim31.maven</groupId><artifactId>scala-maven-plugin</artifactId><version>3.2.2</version><executions><execution><id>scala-compile-first</id><phase>process-resources</phase><goals><goal>compile</goal></goals></execution></executions><configuration><scalaVersion>${scala.version}</scalaVersion><recompileMode>incremental</recompileMode><useZincServer>true</useZincServer><args><arg>-unchecked</arg><arg>-deprecation</arg><arg>-feature</arg></args><jvmArgs><jvmArg>-Xms1024m</jvmArg><jvmArg>-Xmx1024m</jvmArg></jvmArgs><javacArgs><javacArg>-source</javacArg><javacArg>${java.version}</javacArg><javacArg>-target</javacArg><javacArg>${java.version}</javacArg><javacArg>-Xlint:all,-serial,-path</javacArg></javacArgs></configuration></plugin><plugin><groupId>org.antlr</groupId><artifactId>antlr4-maven-plugin</artifactId><version>4.3</version><executions><execution><id>antlr</id><goals><goal>antlr4</goal></goals><phase>none</phase></execution></executions><configuration><outputDirectory>src/test/java</outputDirectory><listener>true</listener><treatWarningsAsErrors>true</treatWarningsAsErrors></configuration></plugin></plugins>
</build>

代码编写

我这里实现了一个简单的场景,就是Spark从Hive表读取数据然后写入HBase,以及Spark从HBase中读取数据然后写入到Hive
先创建Hive表,并导入测试数据:

CREATE TABLE employee(id STRING,name STRING,age INT,city STRING)
ROW FORMAT DELIMITED FIELDS TERMINATED BY ',';准备数据
1,张三,23,北京
2,李四,24,上海
3,王五,25,重庆
4,赵六,26,天津
5,田七,27,成都
6,Lily,16,纽约
7,Jack,15,洛杉矶
8,Rose,18,迈阿密LOAD DATA LOCAL INPATH '/data/release/employee.txt' INTO TABLE employee;

SparkReadHive2HBase的代码:

import org.apache.spark.sql.SparkSession
import org.apache.spark.sql.execution.datasources.hbase.HBaseTableCatalogobject SparkReadHive2HBase {def main(args: Array[String]): Unit = {val catalog =s"""{|"table":{"namespace":"default", "name":"employee"},|"rowkey":"id",|"columns":{|"id":{"cf":"rowkey", "col":"id", "type":"string"},|"name":{"cf":"person", "col":"name", "type":"string"},|"age":{"cf":"person", "col":"age", "type":"int"},|"city":{"cf":"address", "col":"city", "type":"string"}|}|}""".stripMarginval spark = SparkSession.builder().appName(name = s"${this.getClass.getSimpleName}").config("spark.debug.maxToStringFields", "100").config("spark.yarn.executor.memoryOverhead", "2048").enableHiveSupport().getOrCreate()import spark.sqlsql(sqlText = "select * from employee").write.options(Map(HBaseTableCatalog.tableCatalog -> catalog, HBaseTableCatalog.newTable -> "4")).format("org.apache.spark.sql.execution.datasources.hbase").save()}
}

查看数据:
在这里插入图片描述

SparkReadHBase2Hive代码:

import org.apache.spark.sql.execution.datasources.hbase.HBaseTableCatalog
import org.apache.spark.sql.{DataFrame, SparkSession}object SparkReadHBase2Hive {def main(args: Array[String]): Unit = {val catalog =s"""{|"table":{"namespace":"default", "name":"employee"},|"rowkey":"id",|"columns":{|"id":{"cf":"rowkey", "col":"id", "type":"string"},|"name":{"cf":"person", "col":"name", "type":"string"},|"age":{"cf":"person", "col":"age", "type":"int"},|"city":{"cf":"address", "col":"city", "type":"string"}|}|}""".stripMarginval spark = SparkSession.builder().appName(name = s"${this.getClass.getSimpleName}").config("spark.debug.maxToStringFields", "100").config("spark.yarn.executor.memoryOverhead", "2048").enableHiveSupport().getOrCreate()import spark.sqlval df: DataFrame = spark.read.options(Map(HBaseTableCatalog.tableCatalog -> catalog)).format("org.apache.spark.sql.execution.datasources.hbase").load()df.createOrReplaceTempView("view1")sql("select * from view1 where age >= 18").write.mode("overwrite").saveAsTable("employee2")spark.stop()}
}

查看Hive中employee2表的数据:
在这里插入图片描述

如何提交

首先用Maven打完Jar包会有两个,我们要选择的一定是带依赖的jar包,虽然很大,但是因为我们集群没有相应的Jar包,因此选择大的Jar包

spark2-submit \
--class SparkReadHive2HBase \
--files /etc/hbase/conf/hbase-site.xml \
--master yarn \
--deploy-mode  cluster \
--num-executors 70 \
--executor-memory 20G \
--executor-cores 3 \
--driver-memory 4G \
--conf spark.default.parallelism=960 \
/data/release/hbasespark.jar

这里有个重点:

必须得使用cluster模式,否则报错:

ERROR client.ConnectionManager$HConnectionImplementation: Can't get connection to ZooKeeper: KeeperErrorCode = ConnectionLoss for /hbase

这样的顺利的实现的Spark使用DataFrame读写HBase咯

后记

我在定义HBase目录结构的时候,发生了一点小失误,我之前想的时候给employee表rowkey名字起为phone_number,后来不知咋地又想直接用id吧,于是把目录结构写混了:

val catalog =s"""{|"table":{"namespace":"default", "name":"employee"},|"rowkey":"id",|"columns":{|"id":{"cf":"rowkey", "col":"phone_number", "type":"string"},|"name":{"cf":"person", "col":"name", "type":"string"},|"age":{"cf":"person", "col":"age", "type":"int"},|"city":{"cf":"address", "col":"city", "type":"string"}|}|}""".stripMargin

于是报错:

ERROR yarn.ApplicationMaster: User class threw exception: java.lang.UnsupportedOperationException: empty.tail

改为正确的目录结构后就好了:

val catalog =s"""{|"table":{"namespace":"default", "name":"employee"},|"rowkey":"id",|"columns":{|"id":{"cf":"rowkey", "col":"id", "type":"string"},|"name":{"cf":"person", "col":"name", "type":"string"},|"age":{"cf":"person", "col":"age", "type":"int"},|"city":{"cf":"address", "col":"city", "type":"string"}|}|}""".stripMargin

http://chatgpt.dhexx.cn/article/PGX9MUYK.shtml

相关文章

shc将shell脚本转成二进制文件

最近在做一个项目&#xff0c;需要把shell脚本自定拷贝到目标客户端中执行&#xff0c;但是并不想让用户知道脚本的源码&#xff0c;于是采用shc对shell脚本进行处理 首先装个wget工具 yum -y install wget下载 wget http://www.datsi.fi.upm.es/~frosal/sources/shc-3.8.7.…

Shell脚本加密工具——Shc

Linux下的shell脚本用途广泛&#xff0c;经常包含IP、Pwd等关键信息&#xff0c;可读可写的特点很容易造成信息泄露&#xff0c;导致严重后果。基于这些原因&#xff0c;对脚本实施加密便变得很有必要。本文介绍的shc便是这样的一款加密工具。 1&#xff0c;下载安装 下载地址…

SHC加密sh脚本

SHC是一个将bash等脚本打包成二进制文件执行的工具,由于其执行脚本的方式不需要脚本文件落地,且在打包的二进制文件中加密脚本内容,在静态文件中没有脚本的痕迹,很多恶意文件利用该工具完成恶意行为,常规的恶意软件检测也难以判黑。 使用举例 生成二进制bin文件的命令:…

linux上shc下载和安装

安装好wget&#xff0c;有网直接下载即可 wget http://www.datsi.fi.upm.es/~frosal/sources/shc-3.8.7.tgz下载后解压 tar zxf shc-3.8.7.tgz安装gcc yum install gcc -y进入目录 gcc shc-3.8.7.c -o shc将命令移动到根bin下 mv shc /bin安装结束

shc加密shell脚本

shc的官网下载地址http://www.datsi.fi.upm.es/~frosal/sources/ shc是一个专业的加密shell脚本的工具.它的作用是把shell脚本转换为一个可执行的二进制文件&#xff0c;这个办法很好的解决了脚本中含有IP、 密码等不希望公开的问题。 如果你的shell脚本包含了敏感的口令或者…

shell脚本加密工具—shc

Shell脚本中包含大量信息&#xff0c;其中还有一些敏感信息&#xff0c;如用户名&#xff0c;密码&#xff0c;路径&#xff0c;ip等&#xff0c;这些信息在保存或运行时很容易就会泄露&#xff0c;所以需要对Shell脚本进行加密。 Shc是一个加密Shell脚本的工具&#xff0c;它的…

shc

2019独角兽企业重金招聘Python工程师标准>>> 1. shc是什么? shc是一个可以将shell script转化为可执行文件的工具, 默认一个shell script文件经过工具处理后有另外两个文件.x和.x.c文件, 其中.x文件可执行, 而.x.c文件是其源码. 需要注意的是这个工具不是编译, shc…

shell脚本shc加密解密

一、shc加密 #shc编译安装 #软件安装包地址&#xff1a;http://www.datsi.fi.upm.es/~frosal/sources/ tar xvfz shc-3.8.7.tgz cd shc-3.8.7 make #验证shc是否正确安装 ./shc -v #加密命令 shc -T -f a.sh #加密后生成的文件 #a.sh.x是加密后的可执行的二进制文件 #a.sh.x.c…

如何使用SHC加密Shell脚本

导读如何在Linux环境中加密shell脚本&#xff1f;shell脚本包含密码&#xff0c;不希望其他具有执行权限的人查看shell脚本并获取密码。可以安装使用shc工具&#xff0c;普通用户无法读取shc创建的加密Shell脚本。SHC是指&#xff1a;Shell脚本编译器(Shell Script Compiler)。…

计算机类SCI期刊IF排名

数据基于最新的(2021)科睿唯安数据库&#xff0c;计算机科学及人工智能方向。 1-10名&#xff1a; 11-20名&#xff1a;

爱思唯尔计算机期刊排名,2017影响因子高增长爱思唯尔物理期刊推荐

原标题&#xff1a;2017影响因子高增长爱思唯尔物理期刊推荐 爱思唯尔Elsevier凭借出版高质量物理学期刊百余年的经验&#xff0c;能敏锐发现物理学领域的需求变化&#xff0c;帮助物理学家们脱颖而出&#xff0c;逐步建立完善他们的职业生涯。爱思唯尔物理期刊团队的目标很简单…

计算机中运行Xbrowser,丢失msvcr110.dll

删除那些向文件夹添加dll文件的说法。直接下载两个版本的文件安装即可&#xff1a; 官方下载地址

linux xbrowser 安装包,xmanager安装包

xmanager安装包是一款专门应用于远程遥控的专业软件。使用xmanager安装包用户们就可以对争的同意的设备来远程遥控&#xff0c;对xmanager安装包感兴趣那就快来下载吧。 xmanager安装包介绍 1、一款功能强大、使用方便的会话管理工具&#xff0c;主要供网管使用。 2、可以轻松连…

使用 Xbrowser4远程连接到 CentOS 7

2019独角兽企业重金招聘Python工程师标准>>> 将 gdm 切换到 lightdm 打开终端&#xff0c;切换root帐号 # su - 2.安装 lightdm # yum install lightdm 3.配置 lightdm&#xff0c;如果不存在&#xff0c;则创建之 # vi /etc/lightdm/lightdm.conf [XDMCPServer] e…

linux桌面网络连接是个X,Xbrowser如何运行多个X桌面

Xbrowser的用户界面非常直观。在Xbrowser中&#xff0c;可以使用X显示器控制协议(XDMCP)浏览或连接远程的UniX/LinuX机器。本集就同大家讲讲如何使用Xbrowser运行多个X桌面。 打开多个XDMCP会话的具体操作&#xff1a; 1、运行Xbrowser&#xff0c;Xbrowser中列出了所有连接的主…

【Xmanager】Xbrowser-Xstart远程访问RHEL5.3配置

转自http://www.throwexcept.com/article/1417030564765.html 用Xstart连接Linux远程桌面有一个好处&#xff0c;服务器端不用做什么设置&#xff0c;开启SSH即可。 服务器要有桌面环境和X Window。 用XDMCP连接&#xff0c;服务器端得做一些配置&#xff0c;麻烦。 开始菜单 -…

使用Xmanager - Xbrowser打开远程最小化方式安装的CentOS 7.6的图形化界面

默认开机后进入命令提示符界面&#xff1a; 如果需要使用图形界面&#xff0c;可执行如下操作&#xff1a; 1、关闭CentOS 7.6的firewalld防火墙&#xff0c;或打开177端口 2、安装桌面环境&#xff1a; # yum -y groupinstall "X Window System" # yum -y install g…

【原创】利用xbrowser进行远程连接

1.首先保证本机与目的机能够ping通&#xff0c;这是前提。 确定能够连通后&#xff0c;打开xbrower。 2.邮件点击空白&#xff0c;选择new->XDMCP Session。 3.弹出的属性卡中&#xff0c;在session中填入会话名称&#xff0c;在Host中填入目的机的ip。 4.然后就多出了登录图…

Linux远程终端工具之Xmanager----Xbrowser篇

最近在学习RH401课程&#xff0c;由于在平时都是用SecureCRT来远程连接到服务器进行操作的&#xff0c;可是RH401里面的一些实验是需要在linux图形化界面上鼠标点点的。因为不想在直接在实验机器面前操作&#xff0c;所以就找了找远程终端控制的软件。当时百度找到了Xmanager&a…

Linux远程连接工具Xmanager Xbrowser--Win10远程连接CentOS6.9桌面

为方便日常服务器的管理维护&#xff0c;使用Xmanager远程连接公司服务器&#xff0c;连接方法如下&#xff1a; 环境 服务器&#xff1a;CentOS 6.9 GNOME桌面环境 个人主机&#xff1a;Windows 10专业版 连接步骤 1、在服务器上安装xdm yum install xdm -y 2、修改xdm配置参数…