HBase rest API - GET、PUT/POST、的使用

来源:互联网 发布:淘宝 作弊 编辑:程序博客网 时间:2024/05/17 13:09

要使用Hadoop,数据合并至关重要,HBase应用甚广。一般而言,需要针对不同情景模式将现有的各种类型的数据库或数据文件中的数据转入至HBase中。
常见方式为:使用HBase的API中的Put方法; 使用HBase 的bulk load 工具;使用定制的MapReduce Job方式。


启动HBase rest功能
//-------------------------------------------
$ hbase-daemon.sh start rest 


查看server是否正常
//-------------------------------------------
$ curl http://localhost:8080/version


REST Server默认监听8080端口,如果被占,可以修改HBase的hbase-site.xml文件
//-------------------------------------------
<property>
        <name>hbase.rest.port</name>
        <value>8090</value>
 </property>




GET、PUT/POST、  -- -----rest api -------


官方文档 http://hbase.apache.org/book.html#_rest


返回xml格式:
curl -H "Accept: text/xml" http://itr-hbasetest01:20550/version -v
curl -H "Accept: text/xml" http://itr-hbasetest01:20550/version/cluster -v


返回json格式:
curl -H "Accept: application/json" http://itr-hbasetest01:20550/status/cluster | python -mjson.tool  // python的一个工具,可对json进行解析





curl -X PUT -H "Content-Type: application/json" http://itr-hbasetest01:20550/tbl_rest/schema -d '{"ColumnSchema":[{"name":"cf"}]}' -v //创建(tbl_rest)table
$ screen -r hbase
$ hbase shell
$ list 'tb1.*'
$ disable 'tb1_rest'
$ drop 'tb1_rest'
$ list 'tb1.*'



查看有多少个region、在哪个机器上、region名字、startKey... 都可以通过restAPI调用出来
//----------------------------------
curl -H "Accept: application/json" http://itr-hbasetest01:20550/tbl_rest/regions | python -mjson.tool 



通过restAPI往里面加数据(json或xml脚本)


1. hbase_put_rest_json.sh 脚本:
//-----------------------------------
table=$1
cf=$2
column=$3
key=$4
value=$5


cq_enc=`echo -ne $cf:$column | base64`


key_enc=`echo -ne $key | base64`
value_enc=`echo -ne $value | base64`


data='{ "Row": [ { "key": "'$key_enc'", "Cell": [ { "column": "'$cq_enc'", "$": "'$value_enc'" } ] } ] }'
echo $data
curl -H "Content-Type: application/json" --data "$data" http://itr-hbasetest01.zalando:20550/$table/$key -v  //告诉restAPI要操作的表是哪一个 Key是哪一个


执行:
$ ./hbase_put_rest_json.sh tbl_rest cf test sku_1 123 
$ list 'tb1.*'



2. hbase_put_rest_xml.sh 脚本:
//-----------------------------------------------------
table=$1
cf=$2
column=$3
key=$4
value=$5


cq_enc=`echo -ne $cf:$column | base64` //做编码转换


key_enc=`echo -ne $key | base64`
value_enc=`echo -ne $value | base64`


xml='<?xml version="1.0" encoding="UTF-8" standalone="yes"?><CellSet><Row key="'$key_enc'"><Cell column="'$cq_enc'">'$value_enc'</Cell></Row></CellSet>'
echo $xml
curl -H "Content-Type: text/xml" --data "$xml" http://itr-hbasetest01.zalando:20550/$table/$key -v


执行:
./hbase_put_rest_xml.sh tbl_rest cf test1 sku_2 789  //xml方式添加列值
> scan 'tb1_rest'



还可以用restAPI去取这个json的值:
//--------------------------------------------------
curl -H "Accept: application/json" http://itr-hbasetest01:20550/tbl_rest/sku_2 | python -mjson.tool  //查看sku_2列


echo -n "c2t1XzI=" | base64 -d   //对"c2t1XzI="做编码转换,不然格式看不懂。 echo -n输出格式不加换行
echo -n "Nzg5" | base64 -d       // "Nzg5"是经过base64编码的值,所以用base64 -d 解码成我们能看懂的数据



原始命令行取值方式,格式不整洁:
$ curl -H "Accept: text/xml" http://itr-hbasetest01:20550/tbl_rest/sku_2
也可以用xml的方式-在Postman网页命令行里看比较直观(值与json一样,表达形式不一样)
//----------------------------------
Postman网页配置项:
//--------------------------------
http://itr-hbasetest01:20550/tbl_rest/sku_2    GET
Accept       text/xml(application/json)  Manage presets
Header       value 


(Send)


//----------------------------------


直接取值,而不是用上面的base64变化方式,实际应用中方便
//---------------------------------------------------------
 curl -H "Accept: application/octet-strean" http://itr-hbasetest01:20550/tbl_rest/sku_2/cf:test1  


删除表
//---------------------------------------------------------
curl -X DELETE -H "Accept: application/json" http://itr-hbasetest01:20550/tbl_rest/schema -v 
> scan 'tb1.*'
> list 'tb1.*'




------------------ 加载 JRuby script 操作二进制数据 ------------------


alter 'test1', NAME => 'cf', METHOD => 'delete'
alter 'test1', 'delete' => 'cf'


alter 'test1', NAME => 'cf'


//----put数据
put 'test1', 'user1', 'cf:1399999999', "\x00\x00\x00\x09"
put 'test1', 'user1', 'cf:1400000000', "\x00\x00\x00\x08"
put 'test1', 'user1', 'cf:1400000001', "\x00\x00\x00\x07"
put 'test1', 'user1', 'cf:1400000002', "\x00\x00\x20\xFB"
put 'test1', 'user2', 'cf:1500000000', "\x00\x00\x00\x11"
put 'test1', 'user2', 'cf:1500000001', "\x00\x00\x20\xFC"


//-----JRuby脚本( scan_binary_values.rb )
//-----HBase shell 使用Ruby写的,所以集成起来很容易


import org.apache.hadoop.hbase.HBaseConfiguration
import org.apache.hadoop.hbase.client.HTable
import org.apache.hadoop.hbase.client.Scan;
import org.apache.hadoop.hbase.util.Bytes;
import org.apache.hadoop.hbase.client.ResultScanner;
import org.apache.hadoop.hbase.client.Result;
import org.apache.hadoop.io.Text;
import java.util.ArrayList;


def scan_binary_values(table, cf)
  htable = HTable.new(HBaseConfiguration.new, table)
  rs = htable.getScanner(Bytes.toBytes(cf))#(Bytes.toBytes("cf"), Bytes.toBytes("long"))
  output = ArrayList.new
  output.add "ROW\t\t\t\t\t\tCOLUMN\+CELL"
  rs.each { |r|
    r.raw.each { |kv|
      row = Bytes.toString(kv.getRow)
      fam = Bytes.toString(kv.getFamily)
      ql = Bytes.toString(kv.getQualifier)
      ts = kv.getTimestamp
      #val = Bytes.toInt(kv.getValue) (toLong(下面一行包含了两个类型))
      val = (kv.getValueLength == 8 ? Bytes.toLong(kv.getValue) : Bytes.toInt(kv.getValue))
      output.add " #{row} \t\t\t\t\t\t column=#{fam}:#{ql}, timestamp=#{ts}, value=#{val}"
    }
  }
  output.each {|line| puts "#{line}\n"}
end




//-----------提交调用JRuby脚本
 > require '/home/hduser/hbase/scan_binary_values'



//---------直接使用
 > scan 'test1', COLUMNS => 'cf'  查询值类型会是二进制的形式



//---------而用
 > scan_binary_values 'test1', 'cf'  查询的值将以整形变量显示


//---------而用
 > scan_binary_values 'test1', 'lf'  查询的值将不能以整形变量显示,因为lf里是长整型的value(8位Byter)
 可修改脚本#val = Bytes.toInt(kv.getValue) 成toLong()






Conpaction做的是数据文件合并,过大时Split,当一个region split 文件过多时还可以用 Merge去合并文件
避免Conpact、split (特别和hive整合时) 跟下面四个参数都有关
//--------------------------------------------------------------------
hbase.hregion.memstore.flush.size --- 跟split相关,达到这个大小就写入HBase,调大避免产生过多的storeFile
hbase.hregion.max.fileze          (table_att => MAX_FILESIZE) 设置得非常大就可以避免自动split
hbase.hstore.compactionThreshold  阈值(hstore的文件个数积累到什么数(8乘以flush.size)时触发Conpaction),如置8:超过8个文件就开始split,跟flush.size相关

hbase.hregion.majorcompaction     majorcompaction间隔时间设置,删除过期的数据


0 0