如何使用spark从hbase读取数据
下面的代码将从hbase读取,然后将其转换为json结构并转换为schemaRDD,但问题是我正在使用List存储json字符串,然后传递到javaRDD,对于大约100 GB的数据,主机将在内存中加载数据。从hbase加载数据,然后执行操作,然后转换为JavaRDD的正确方法是什么如何使用spark从hbase读取数据,hbase,apache-spark,rdd,Hbase,Apache Spark,Rdd,下面的代码将从hbase读取,然后将其转换为json结构并转换为schemaRDD,但问题是我正在使用List存储json字符串,然后传递到javaRDD,对于大约100 GB的数据,主机将在内存中加载数据。从hbase加载数据,然后执行操作,然后转换为JavaRDD的正确方法是什么 包hbase\u读卡器; 导入java.io.IOException; 导入java.io.Serializable; 导入java.util.ArrayList; 导入java.util.List; 导入org.
包hbase\u读卡器;
导入java.io.IOException;
导入java.io.Serializable;
导入java.util.ArrayList;
导入java.util.List;
导入org.apache.spark.api.java.javapairdd;
导入org.apache.spark.api.java.JavaRDD;
导入org.apache.spark.api.java.JavaSparkContext;
导入org.apache.spark.rdd.rdd;
导入org.apache.spark.sql.api.java.JavaSQLContext;
导入org.apache.spark.sql.api.java.JavaSchemaRDD;
导入org.apache.commons.cli.ParseException;
导入org.apache.hadoop.hbase.HBaseConfiguration;
导入org.apache.hadoop.hbase.KeyValue;
导入org.apache.hadoop.hbase.client.HTable;
导入org.apache.hadoop.hbase.client.Result;
导入org.apache.hadoop.hbase.client.ResultScanner;
导入org.apache.hadoop.hbase.client.Scan;
导入org.apache.hadoop.hbase.io.ImmutableBytesWritable;
导入org.apache.hadoop.hbase.mapreduce.TableInputFormat;
导入org.apache.hadoop.hbase.util.Bytes;
导入org.apache.hadoop.io.Text;
导入org.apache.spark.SparkConf;
导入scala.Function1;
导入scala.Tuple2;
导入scala.runtime.AbstractFunction1;
导入com.google.common.collect.list;
公共类hbase_读取器{
公共静态void main(字符串[]args)引发IOException、ParseException{
List jars=Lists.newArrayList(“”);
SparkConf spconf=新的SparkConf();
spconf.setMaster(“本地[2]”);
spconf.setAppName(“HBase”);
//spconf.setSparkHome(“/opt/human/opt/spark-0.9.0-hdp1”);
setJars(jars.toArray(新字符串[jars.size()]);
JavaSparkContext sc=新的JavaSparkContext(spconf);
//spconf.set(“spark.executor.memory”,“1g”);
JavaSQLContext jsql=新的JavaSQLContext(sc);
HBaseConfiguration conf=新的HBaseConfiguration();
String tableName=“HBase.conudata1\u Raw\u Min1”;
HTable table=新的HTable(conf,tableName);
试一试{
ResultScanner scanner=table.getScanner(new Scan());
List jsonList=new ArrayList();
字符串json=null;
用于(结果行结果:扫描仪){
json=“”;
字符串rowKey=Bytes.toString(rowResult.getRow());
对于(字节[]s1:rowResult.getMap().keySet()){
字符串s1_str=Bytes.toString(s1);
字符串jsonname=“”;
对于(字节[]s2:rowResult.getMap().get(s1.keySet()){
字符串s2_str=Bytes.toString(s2);
for(长s3:rowResult.getMap().get(s1).get(s2).keySet()){
strings3_str=新字符串(rowResult.getMap().get(s1.get(s2.get(s3));
jsonSame+=“\”+s2\U str+“\”:“+s3\U str+”,”;
}
}
jsoname=jsoname.substring(0,jsoname.length()-1);
json+=“\”“+s1\”“+str+”\”“+:{”+jsonSame+“}”+“,”;
}
json=json.substring(0,json.length()-1);
json=“{\“RowKey\”:\”+RowKey+“\”,“+json+”}”;
添加(json);
}
JavaRDD-jsonRDD=sc.parallelize(jsonList);
JavaSchemaRDD schemaRDD=jsql.jsonRDD(jsonRDD);
系统输出println(schemaRDD.take(2));
}最后{
table.close();
}
}
}
我更喜欢阅读hbase,并在spark中进行json操作。Spark提供了从hadoop存储(包括HBase)读取数据的功能。您必须以配置参数和表输入格式及其键值提供HBase配置、表名和扫描 您可以使用类及其作业参数来提供表名和扫描配置 例如:
conf.set(TableInputFormat.INPUT_TABLE, "tablename");
JavaPairRDD<ImmutableBytesWritable, Result> data =
jsc.newAPIHadoopRDD(conf, TableInputFormat.class,ImmutableBytesWritable.class, Result.class);
conf.set(TableInputFormat.INPUT_TABLE,“tablename”);
JavaPairRDD数据=
newAPIHadoopRDD(conf,TableInputFormat.class,ImmutableBytesWritable.class,Result.class);
然后可以在spark中执行json操作。由于spark可以在内存已满时进行重新计算,因此它只加载重新计算部分(cmiiw)所需的数据,因此您不必担心数据大小这是使用spark(Scala)读取HBase数据的基本示例,您也可以在Java中编写:
import org.apache.hadoop.hbase.client.{HBaseAdmin, Result}
import org.apache.hadoop.hbase.{ HBaseConfiguration, HTableDescriptor }
import org.apache.hadoop.hbase.mapreduce.TableInputFormat
import org.apache.hadoop.hbase.io.ImmutableBytesWritable
import org.apache.spark._
object HBaseRead {
def main(args: Array[String]) {
val sparkConf = new SparkConf().setAppName("HBaseRead").setMaster("local[2]")
val sc = new SparkContext(sparkConf)
val conf = HBaseConfiguration.create()
val tableName = "table1"
System.setProperty("user.name", "hdfs")
System.setProperty("HADOOP_USER_NAME", "hdfs")
conf.set("hbase.master", "localhost:60000")
conf.setInt("timeout", 120000)
conf.set("hbase.zookeeper.quorum", "localhost")
conf.set("zookeeper.znode.parent", "/hbase-unsecure")
conf.set(TableInputFormat.INPUT_TABLE, tableName)
val admin = new HBaseAdmin(conf)
if (!admin.isTableAvailable(tableName)) {
val tableDesc = new HTableDescriptor(tableName)
admin.createTable(tableDesc)
}
val hBaseRDD = sc.newAPIHadoopRDD(conf, classOf[TableInputFormat], classOf[ImmutableBytesWritable], classOf[Result])
println("Number of Records found : " + hBaseRDD.count())
sc.stop()
}
}
更新日期:2016年
从Spark 1.0.x+开始,现在您还可以使用Spark HBase连接器:
Maven依赖项包括:
<dependency>
<groupId>it.nerdammer.bigdata</groupId>
<artifactId>spark-hbase-connector_2.10</artifactId>
<version>1.0.3</version> // Version can be changed as per your Spark version, I am using Spark 1.6.x
</dependency>
<dependency>
<groupId>com.hortonworks</groupId>
<artifactId>shc</artifactId>
<version>1.0.0-2.0-s_2.11</version> // Version depends on the Spark version and is supported upto Spark 2.x
</dependency>
it.nerdammer.bigdata
您还可以将此RDD转换为数据帧并在其上运行SQL,或者可以将这些数据集或数据帧映射到用户定义的JavaPOJO或Case类。它工作得很好
如果您还需要其他信息,请在下面发表评论。仅添加有关如何添加扫描的评论:
TableInputFormat具有以下属性:
扫描行开始
扫描行停止
由于这个问题并不新鲜,目前还有一些其他选择:
- ,一个可直接在HBase Reso中使用的模块
- 霍顿工厂
我对第一个项目不太了解,但它似乎不支持Spark 2.x。但是,它在RDD级别上对Spark 1.6.x提供了丰富的支持
另一方面,HBase上的Spark有Spark 2.0和即将推出的Spark 2.1的分支。这个项目非常有希望,因为它专注于数据集/数据帧API。在幕后,它实现了标准的Spark数据源API,并利用Spark Catalyst引擎进行查询优化。开发人员声称它能够进行分区修剪、列修剪、谓词下推和实现数据局部性
一个简单的例子,使用t
<dependency>
<groupId>com.hortonworks</groupId>
<artifactId>shc</artifactId>
<version>1.0.0-2.0-s_2.11</version> // Version depends on the Spark version and is supported upto Spark 2.x
</dependency>
conf.set(TableInputFormat.SCAN_ROW_START, "startrowkey");
conf.set(TableInputFormat.SCAN_ROW_STOP, "stoprowkey");
case class Record(col0: Int, col1: Int, col2: Boolean)
val spark = SparkSession
.builder()
.appName("Spark HBase Example")
.master("local[4]")
.getOrCreate()
def catalog =
s"""{
|"table":{"namespace":"default", "name":"table1"},
|"rowkey":"key",
|"columns":{
|"col0":{"cf":"rowkey", "col":"key", "type":"int"},
|"col1":{"cf":"cf1", "col":"col1", "type":"int"},
|"col2":{"cf":"cf2", "col":"col2", "type":"boolean"}
|}
|}""".stripMargin
val artificialData = (0 to 100).map(number => Record(number, number, number % 2 == 0))
// write
spark
.createDataFrame(artificialData)
.write
.option(HBaseTableCatalog.tableCatalog, catalog)
.option(HBaseTableCatalog.newTable, "5")
.format("org.apache.spark.sql.execution.datasources.hbase")
.save()
// read
val df = spark
.read
.option(HBaseTableCatalog.tableCatalog, catalog)
.format("org.apache.spark.sql.execution.datasources.hbase")
.load()
df.count()