Spark读写Phoenix

Phoenix是使用Java编写的一个开源项目,基于在HBase之上的一个SQL层,能让我们通过标准的JDBC API读写HBase,而不用Scan或者get的方式,其实底层是将SQL编译成原生的HBase scans进行查询。

注意:二级索引,要通过phoenix写入,才能更新索引表,直接写hbase是不能更新索引表的,除非是全局索引,这样可以在插入hbase的时候,写两份数据到索引表和使用表中,但是索引不支持更新,同一rowkey下的索引,每次插入一次,都是一条,存储空间极度浪费

  本文将通过Spark的方式来读写Phoenix,基于以下版本开发测试。

  scala-version:2.11.8

  spark-version:2.2.0

  hbase-version:1.3.1

  phoenix-version:4.14.0

接下来正式开始了。

  1. 添加Maven依赖
org.apache.spark spark-core_2.11 2.2.0
  <dependency>
    <groupId>org.apache.phoenix</groupId>
    <artifactId>phoenix-spark</artifactId>
    <version>4.14.0-HBase-1.3</version>
    <scope>provided</scope>
  </dependency>

2、Spark读写Phoenix

import org.apache.spark.sql.SQLContext
import org.apache.spark.{SparkConf, SparkContext}

object Phoenix2Spark {
def main(args: Array[String]): Unit = {

//这种事老的API来访问Phoenix
val jdbcPhoenixUrl = “jdbc:phoenix:172.18.18.100:2181”
val tableName = “test”

val conf = new SparkConf().setAppName("phoenix-spark").setMaster("local")
val sc = new SparkContext(conf)
val sqlContext = new SQLContext(sc)

val df = sqlContext.load("org.apache.phoenix.spark", Map("table"->tableName, "zkUrl"->jdbcPhoenixUrl))
df.show()

sc.stop()

}

}

原文链接:http://www.cnblogs.com/koushr/p/9844449.html
spark sql可以与hbase交互,比如说通过jdbc,但是实际使用时,一般是利用phoenix操作hbase。此时,需要在项目中引入phoenix-core-4.10.0-HBase-1.2.jar和phoenix-spark-4.10.0-HBase-1.2.jar。

而如今常用的方法为用Phoenix读取hbase数据,Phoenix详情可见官方(Phoenix官网链接),Phoenix也为Apache项目,通过spark去连Phoenix读取hbase中的数据会方便的多,Phoenix提供的sqlApI可以很方便的通过sql去查询hbase中的数据,且官方也提供spark链接Phoenix的方法,代码如下(参见此链接)pyspark处,也提供了其他语言方法:

java代码示例:

public static void main(String[] args) {
    SparkSession spark = SparkSession.builder()
            .appName("heihei")
            .master("local[*]")
            .getOrCreate();
    Dataset<Row> df = spark.read().format("org.apache.phoenix.spark")
            .option("zkUrl", "192.168.56.11:2181")
            .option("table", "test1")
            .load();

    df = df.filter("name not like 'hig%'").filter("password like '%0%'");

    df.write().format("org.apache.phoenix.spark")
            .mode(SaveMode.Overwrite)
            .option("zkUrl", "192.168.56.11:2181")
            .option("table", "test2")
            .save();
}

上例从hbase test1表中读取数据,把符合 where name not like ‘hig%’ and password like ‘%0%’ 筛选条件的数据输出到hbase test2表中。以上写法不用担心内存溢出,程序会自动partition

当然,其中也包括了写入方法,这里不一一赘述。此方法load出一个sparkDF,对DF在进行相应的表映射(构建一个视图),用官方提供的方法即可,类似于createOrReplaceTempView(“table”),然后再对相应的table进行sql操作即可获取想要的数据,在转成Rdd进行相应的map操作,但是在使用Phoenix的时候需要注意几个问题,Phoenix查询时以key查询会很快,但是当要查询其他字段时,同样走的全表扫描,而当hbase表的数据量很大时,此种方法任然效率很慢,但庆幸的是,通过Phoenix可以很方便的构建二级索引,有了二级索引之后,对hbase的查询就会快很多,满足大多数的业务要求,但在建二级索引的时候同样需要注意一个问题,当表的数据量足够大时,构建索引会非常耗时,且通常都构建不起来,会timeout或者抛出异常,所以在构建二级索引时最好的方式为:异步创建索引,可参考此链接中提供的方法(点击打开链接)。
在这里插入图片描述

scala代码示例:

def main(args: Array[String]): Unit = {
val spark = SparkSession.builder().master(“local[*]”).appName(“phoenix-test”).getOrCreate()
// 第一种读取方法
var df = spark.read.format(“org.apache.phoenix.spark”).option(“table”, “test1”).option(“zkUrl”, “192.168.56.11:2181”).load()
df = df.filter(“name not like ‘hig%’”)
.filter(“password like ‘%0%’”)
df.show()

val configuration = new Configuration()
configuration.set("hbase.zookeeper.quorum", "192.168.56.11:2181")
// 第二种读取方法
df = spark.sqlContext.phoenixTableAsDataFrame("test1", Array("ID", "INFO.NAME", "INFO.PASSWORD"), conf = configuration)
df.show()

//第一种输出方法
df.write
  .format("org.apache.phoenix.spark")
  .mode("overwrite")
  .option("table", "test2")
  .option("zkUrl", "192.168.56.11:2181")
  .save()

//第二种输出方法
df.saveToPhoenix(Map("table" -> "test2", "zkUrl" -> "192.168.56.11:2181"))

}
phoenixTableAsDataFrame()是org.apache.phoenix.spark.SparkSqlContextFunctions中的方法,saveToPhoenix()是org.apache.phoenix.spark.DataFrameFunctions中的方法,在phoenix-spark-4.10.0-HBase-1.2.jar中。使用这两个方法时必须 import org.apache.phoenix.spark._,否则编辑器识别不出语法,也不会自动import。

遇到的问题:
spark 批量写数据到 phoenix
这个问题搞了一周,spark读取hive数据插入phoenix

总共4.5g的数据

最开始是版本问题,和cdh上的版本不一致

代码本地执行没问题,上传集群各种错误,

最后更改 /etc/spark2/conf/classpath.txt 文件 和 /etc/spark2/conf/spark-evn.sh 文件。让其加载classpath.txt文件。

之后

spark write到phoenix 时 ,出现 写数据速度大于索引更新速度

然后任务就挂了

最后

hbase加以下参数 执行成功

phoenix.index.failure.block.write=true

官网的例子:

一、Load a DataFrame
Given a table TABLE1 and a Zookeeper url of localhost:2181 you can load the table as a DataFrame using the following Python code in pyspark

df = sqlContext.read
.format(“org.apache.phoenix.spark”)
.option(“table”, “TABLE1”)
.option(“zkUrl”, “localhost:2181”)
.load()

二、Save a DataFrame
Given the same table and Zookeeper URLs above, you can save a DataFrame to a Phoenix table using the following code

df.write
.format(“org.apache.phoenix.spark”)
.mode(“overwrite”)
.option(“table”, “TABLE1”)
.option(“zkUrl”, “localhost:2181”)
.save()

三、Saving DataFrames
The save is method on DataFrame allows passing in a data source type. You can use org.apache.phoenix.spark, and must also pass in a table and zkUrl parameter to specify which table and server to persist the DataFrame to. The column names are derived from the DataFrame’s schema field names, and must match the Phoenix column names.

The save method also takes a SaveMode option, for which only SaveMode.Overwrite is supported.

Given two Phoenix tables with the following DDL:

CREATE TABLE INPUT_TABLE (id BIGINT NOT NULL PRIMARY KEY, col1 VARCHAR, col2 INTEGER);
CREATE TABLE OUTPUT_TABLE (id BIGINT NOT NULL PRIMARY KEY, col1 VARCHAR, col2 INTEGER);

import org.apache.spark.SparkContext
import org.apache.spark.sql._
import org.apache.phoenix.spark._
// Load INPUT_TABLE
val sc = new SparkContext(“local”, “phoenix-test”)
val sqlContext = new SQLContext(sc)
val df = sqlContext.load(“org.apache.phoenix.spark”, Map(“table” -> “INPUT_TABLE”,
“zkUrl” -> hbaseConnectionString))
// Save to OUTPUT_TABLE
df.saveToPhoenix(Map(“table” -> “OUTPUT_TABLE”, “zkUrl” -> hbaseConnectionString))
or
df.write
.format(“org.apache.phoenix.spark”)
.mode(“overwrite”)
.option(“table”, “OUTPUT_TABLE”)
.option(“zkUrl”, “localhost:2181”)
.save()

四、Saving Phoenix
Given a Phoenix table with the following DDL

CREATE TABLE OUTPUT_TEST_TABLE (id BIGINT NOT NULL PRIMARY KEY, col1 VARCHAR, col2 INTEGER);

Saving RDDs
The saveToPhoenix method is an implicit method on RDD[Product], or an RDD of Tuples. The data types must correspond to one of the Java types supported by Phoenix.

import org.apache.spark.SparkContext
import org.apache.phoenix.spark._
val sc = new SparkContext(“local”, “phoenix-test”)
val dataSet = List((1L, “1”, 1), (2L, “2”, 2), (3L, “3”, 3))
sc
.parallelize(dataSet)
.saveToPhoenix(
“OUTPUT_TEST_TABLE”,
Seq(“ID”,“COL1”,“COL2”),
zkUrl = Some(“phoenix-server:2181”)
)

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
回答: 要在Spark读写HBase,你需要进行以下几个步骤。首先,你需要在simple.sbt配置文件中指定HBase的版本号,包括hbase-client、hbase-common和hbase-server的版本号。你可以通过在Linux系统中打开终端并导航到HBase安装目录,然后使用命令"cd /usr/local/hbase"和"ls"来查找这些版本号。\[1\] 接下来,你需要创建一个Python文件,比如SparkOperateHBase.py,然后在文件中添加读取HBase数据的代码。你需要导入必要的库,设置Spark的配置,指定HBase的主机和表名,以及配置HBase的相关参数。然后,你可以使用Spark的newAPIHadoopRDD方法来读取HBase数据,并对数据进行操作。最后,你可以将结果打印出来。\[2\] 最后,你需要将支持HBase的jar包导入Spark的jars目录下。你可以使用命令"cp /usr/local/software/hbase/hbase-2.4.9/lib/hbase*.jar /usr/local/software/spark/spark-3.0.3-bin-hadoop2.7/jars"来完成这个步骤。\[3\] 这样,你就可以在Spark读写HBase数据了。 #### 引用[.reference_title] - *1* [大数据-05-Spark读写HBase数据](https://blog.csdn.net/weixin_33670713/article/details/85983819)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* *3* [Spark 读写Hbase](https://blog.csdn.net/jinxing_000/article/details/123706938)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值