1. 程式人生 > >基於MapReduce的HBase開發

基於MapReduce的HBase開發

       在偽分散式模式和全分散式模式下 HBase 是架構在 HDFS 上的,因此完全可以將MapReduce 程式設計框架和 HBase 結合起來使用。也就是說,將 HBase 作為底層“儲存結構”,MapReduce 呼叫 HBase 進行特殊的處理,這樣能夠充分結合 HBase 分散式大型資料庫和MapReduce 平行計算的優點。 

相對應MapReduce的hbase實現類:

  1)InputFormat 類:HBase 實現了 TableInputFormatBase 類,該類提供了對錶資料的大部分操作,其子類 TableInputFormat 則提供了完整的實現,用於處理表資料並生成鍵值對。TableInputFormat 類將資料表按照 Region 分割成 split,既有多少個 Regions 就有多個splits。然後將 Region 按行鍵分成<key,value>對,key 值對應與行健,value 值為該行所包含的資料。 
  2)Mapper 類和 Reducer 類:HBase 實現了 TableMapper 類和 TableReducer 類,其中TableMapper 類並沒有具體的功能,只是將輸入的<key,value>對的型別分別限定為 Result 和ImmutableBytesWritable。IdentityTableMapper 類和 IdentityTableReducer 類則是上述兩個類的具體實現,其和 Mapper 類和 Reducer 類一樣,只是簡單地將<key,value>對輸出到下一個階段。 

3)OutputFormat 類:HBase 實現的 TableOutputFormat 將輸出的<key,value>對寫到指定的 HBase 表中,該類不會對 WAL(Write-Ahead  Log)進行操作,即如果伺服器發生
故障將面臨丟失資料的風險。可以使用 MultipleTableOutputFormat 類解決這個問題,該類可以對是否寫入 WAL 進行設定。

程式碼:

import java.io.IOException; 
import java.util.Iterator; 
import java.util.StringTokenizer; 
 
import org.apache.hadoop.conf.Configuration; 
import org.apache.hadoop.fs.Path; 
import org.apache.hadoop.hbase.HBaseConfiguration; 
import org.apache.hadoop.hbase.HColumnDescriptor; 
import org.apache.hadoop.hbase.HTableDescriptor; 
import org.apache.hadoop.hbase.client.HBaseAdmin; 
import org.apache.hadoop.hbase.client.Put; 
import org.apache.hadoop.hbase.mapreduce.TableOutputFormat; 
import org.apache.hadoop.hbase.mapreduce.TableReducer; 
import org.apache.hadoop.hbase.util.Bytes; 
import org.apache.hadoop.io.IntWritable; 
import org.apache.hadoop.io.LongWritable; 
import org.apache.hadoop.io.Text; 
import org.apache.hadoop.io.NullWritable; 
import org.apache.hadoop.mapreduce.Job; 
import org.apache.hadoop.mapreduce.Mapper; 
import org.apache.hadoop.mapreduce.lib.input.FileInputFormat; 
import org.apache.hadoop.mapreduce.lib.input.TextInputFormat; 
 
public class WordCountHBase { 
 
  // 實現 Map 類 
  public static class Map extends 
      Mapper<LongWritable, Text, Text, IntWritable> { 
    private final static IntWritable one = new IntWritable(1); 
    private Text word = new Text(); 
 
    public void map(LongWritable key, Text value, Context context) 
        throws IOException, InterruptedException { 
      StringTokenizer itr = new StringTokenizer(value.toString()); 
      while (itr.hasMoreTokens()) { 
        word.set(itr.nextToken()); 
        context.write(word, one); 
      } 
    } 
  } 
 
  // 實現 Reduce 類 
  public static class Reduce extends 
      TableReducer<Text, IntWritable, NullWritable> { 
 
    public void reduce(Text key, Iterable<IntWritable> values, 
        Context context) throws IOException, InterruptedException { 
 
      int sum = 0; 
 
      Iterator<IntWritable> iterator = values.iterator(); 
      while (iterator.hasNext()) { 
        sum += iterator.next().get(); 
      } 
 
      // Put 例項化,每個詞存一行 
      Put put = new Put(Bytes.toBytes(key.toString())); 
      // 列族為 content,列修飾符為 count,列值為數目 
      put.add(Bytes.toBytes("content"), Bytes.toBytes("count"), 
          Bytes.toBytes(String.valueOf(sum))); 
 
      context.write(NullWritable.get(), put); 
    } 
  } 
 
  // 建立 HBase 資料表 
  public static void createHBaseTable(String tableName)  
throws IOException { 
    // 建立表描述 
    HTableDescriptor htd = new HTableDescriptor(tableName); 
    // 建立列族描述 
    HColumnDescriptor col = new HColumnDescriptor("content"); 
    htd.addFamily(col); 
 
    // 配置 HBase 
    Configuration conf = HBaseConfiguration.create(); 
 
    conf.set("hbase.zookeeper.quorum","master"); 
    conf.set("hbase.zookeeper.property.clientPort", "2181"); 
    HBaseAdmin hAdmin = new HBaseAdmin(conf); 
 
    if (hAdmin.tableExists(tableName)) { 
      System.out.println("該資料表已經存在,正在重新建立。"); 
      hAdmin.disableTable(tableName); 
      hAdmin.deleteTable(tableName); 
    } 
 
    System.out.println("建立表:" + tableName); 
    hAdmin.createTable(htd); 
  } 
 
  public static void main(String[] args) throws Exception { 
    String tableName = "wordcount"; 
    // 第一步:建立資料庫表 
    WordCountHBase.createHBaseTable(tableName); 
 
    // 第二步:進行 MapReduce 處理 
    // 配置 MapReduce 
    Configuration conf = new Configuration(); 
    // 這幾句話很關鍵 
    conf.set("mapred.job.tracker", "master:9001"); 
    conf.set("hbase.zookeeper.quorum","master"); 
    conf.set("hbase.zookeeper.property.clientPort", "2181"); 
    conf.set(TableOutputFormat.OUTPUT_TABLE, tableName); 
 
    Job job = new Job(conf, "New Word Count"); 
    job.setJarByClass(WordCountHBase.class); 
 
    // 設定 Map 和 Reduce 處理類 
    job.setMapperClass(Map.class); 
    job.setReducerClass(Reduce.class); 
 
    // 設定輸出型別 
    job.setMapOutputKeyClass(Text.class); 
    job.setMapOutputValueClass(IntWritable.class); 
 
    // 設定輸入和輸出格式 
    job.setInputFormatClass(TextInputFormat.class); 
    job.setOutputFormatClass(TableOutputFormat.class); 
 
    // 設定輸入目錄 
    FileInputFormat.addInputPath(job, new Path("hdfs://master:9000/in/")); 
    System.exit(job.waitForCompletion(true) ? 0 : 1); 
 
  } 
} 

常見錯誤及解決方法:

1、java.lang.RuntimeException: java.lang.ClassNotFoundException: org.apache.hadoop.hbase.mapreduce.TableOutputFormat

錯誤輸出節選:

13/09/10 21:14:01 INFO mapred.JobClient: Running job: job_201308101437_0016
13/09/10 21:14:02 INFO mapred.JobClient:  map 0% reduce 0%
13/09/10 21:14:16 INFO mapred.JobClient: Task Id : attempt_201308101437_0016_m_000007_0, Status : FAILED
java.lang.RuntimeException: java.lang.ClassNotFoundException: org.apache.hadoop.hbase.mapreduce.TableOutputFormat
	at org.apache.hadoop.conf.Configuration.getClass(Configuration.java:849)
	at org.apache.hadoop.mapreduce.JobContext.getOutputFormatClass(JobContext.java:235)
	at org.apache.hadoop.mapred.Task.initialize(Task.java:513)
	at org.apache.hadoop.mapred.MapTask.run(MapTask.java:353)
	at org.apache.hadoop.mapred.Child$4.run(Child.java:255)
	at java.security.AccessController.doPrivileged(Native Method)
	at javax.security.auth.Subject.doAs(Subject.java:396)
	at org.apache.hadoop.security.UserGroupInformation.doAs(UserGroupInformation.java:1149)
	at org.apache.hadoop.mapred.Child.main(Child.java:249)
Caused by: java.lang.ClassNotFoundException: org.apache.hadoop.hbase.mapreduce.TableOutputFormat
	at java.net.URLClassLoader$1.run(URLClassLoader.java:202)
	at java.security.AccessController.doPrivileged(Native Method)
	at java.net.URLClassLoader.findClass(URLClassLoader.java:190)
	at java.lang.ClassLoader.loadClass(ClassLoader.java:306)
	at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:301)
	at java.lang.ClassLoader.loadClass(ClassLoader.java:247)
	at java.lang.Class.forName0(Native Method)
	at java.lang.Class.forName(Class.java:249)
	at org.apache.hadoop.conf.Configuration.getClassByName(Configuration.java:802)
	at org.apache.hadoop.conf.Configuration.getClass(Configuration.java:847)
	... 8 more

錯誤原因:

相關的類檔案沒有引入到 Hadoop 叢集上。

解決步驟:

步驟一、停止HBase資料庫:

[[email protected] bin]$ stop-hbase.sh 
stopping hbase............
master: stopping zookeeper.
[[email protected] bin]$ jps
16186 Jps
26186 DataNode
26443 TaskTracker
26331 JobTracker
26063 NameNode
   停止Hadoop叢集:
[[email protected] bin]$ stop-all.sh 
Warning: $HADOOP_HOME is deprecated.

stopping jobtracker
master: Warning: $HADOOP_HOME is deprecated.
master: 
master: stopping tasktracker
node1: Warning: $HADOOP_HOME is deprecated.
node1: 
node1: stopping tasktracker
stopping namenode
master: Warning: $HADOOP_HOME is deprecated.
master: 
master: stopping datanode
node1: Warning: $HADOOP_HOME is deprecated.
node1: stopping datanode
node1: 
node1: Warning: $HADOOP_HOME is deprecated.
node1: 
node1: stopping secondarynamenode
[[email protected] bin]$ jps
16531 Jps

步驟二、需要配置 Hadoop 叢集中每臺機器,在 hadoop 目錄的 conf 子目錄中,找 hadoop-env.sh檔案,並新增如下內容:

# set hbase environment
export HBASE_HOME=/opt/modules/hadoop/hbase/hbase-0.94.11-security
export HADOOP_CLASSPATH=$HBASE_HOME/hbase-0.94.11-security.jar:$HBASE_HOME/hbase-0.94.11-security-tests.jar:$HBASE_HOME/conf:$HBASE_HOME/lib/zookeeper-3.4.5.jar
步驟三、重新啟動叢集和hbase資料庫。

2、Error: java.lang.ClassNotFoundException: com.google.protobuf.Message

錯誤輸出節選:

2013-09-12 12:38:57,833 INFO  mapred.JobClient (JobClient.java:monitorAndPrintJob(1363)) -  map 0% reduce 0%
2013-09-12 12:39:12,490 INFO  mapred.JobClient (JobClient.java:monitorAndPrintJob(1392)) - Task Id : attempt_201309121232_0001_m_000007_0, Status : FAILED
Error: java.lang.ClassNotFoundException: com.google.protobuf.Message
	at java.net.URLClassLoader$1.run(URLClassLoader.java:202)
	at java.security.AccessController.doPrivileged(Native Method)
	at java.net.URLClassLoader.findClass(URLClassLoader.java:190)
	at java.lang.ClassLoader.loadClass(ClassLoader.java:306)
	at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:301)
錯誤原因:

明顯,沒找到protobuf-java-2.4.0a.jar包,將該包路徑加入hadoop-env.sh中。

相關推薦

基於node開發的http請求代理

oss .... http請求 代理 test 寫到 pan eve 常用 今天把項目中的反向代理腳本程序抽成了一個插件,通過配置文件配置代理的http請求,這樣使用起來比較方便,每位開發成員都可以用自己配置的代理調試代碼。 git proxy-ajax: http

基於jquery開發的UI框架整理分析

roi black html屬性 二次 quick src 相關 分析 prim 根據調查得知,現在市場中的UI框架差不多40個左右,不知大家都習慣性的用哪個框架,現在市場中有幾款UI框架稍微的成熟一些,也是大家比較喜歡的一種UI框架,那應該是jQuery,有部分U

如何基於WKWebView開發一個功能完善的資訊內容頁

可能 方便 styles 運行 文本框 是我 優雅 pan 主題樣式 前言 對於資訊類的APP來說 良好的閱讀體驗是必不可少的, 那麽如何去開發一個功能完善的資訊文章頁面就是本文要說的重點.相信本文會對很多在做同類功能開發的道友們有很大的幫助 , 如果某只大佬路過也歡迎指點

後臺接口平臺 基於Laravel 開發 快速開發數據接口

serve exe 執行 bat 集成 目前 compose pan 圖片處理 laravelPCMS V1.5.0 項目地址:https://github.com/q1082121/laravelcms 喜歡的朋友可以支持下 點點星標 百牛信息技術bainiu.ltd整理

基於Spring開發的一個BIO-RPC框架(對小白很友好)

instance 啟動項 jar包 pan 發現 就是 遠程 map 配置 PART1:先來整體看下項目的構成 其中bio-rpc-core就是所謂的rpc框架 bio-rpc-example-client即所謂的服務調用方(你的項目中想要調用服務的地方) bio-rp

基於pyQt5開發的股價顯示器(原創)

star ets 時間 class 修改 imp price 內網 pre 1 #/usr/bin/env python 2 # -*- coding: utf-8 -*- 3 ‘‘‘ 4 @author="livermorium116" 5 為了繞開

Spring基於註解開發異常

lib con 版本 mil line tex 宋體 開發 style 基於註解開發: 一開始:用的jar包: 百度查到: 導入aop包: 沒用 有的說: Spring版本和jdk版本不匹配 於是我換成了4.0版本 導入的jar包:

學習手記-基於iTOP4412開發板NFS服務器搭建及測試

udp 都是 使用 共享目錄 none padding rgb 安裝 通訊 NFS特點:1)基於UDP/IP2)功能和網盤基本上差不多,但性能沒那麽強。NFS服務器搭建步驟:在ubantu上安裝nfs軟件:nfs-kernel-server配置文件1)打開配置文件:/etc

Django基於Pycharm開發之四[關於靜態文件的使用,配置以及源碼分析](原創)

OS director 一個 pin mes map text 開發人員 容易 對於django靜態文件的使用,如果開發過netcore程序的開發人員,可能會比較容易理解django關於靜態文件訪問的設計原理,個人覺得,這是一個middlerware的設計,但是在djang

基於socketserver開發多線程ftp

邏輯 += 登錄 provide pen edi tell %s tar 完成功能: 用戶加密認證 允許同時多用戶登錄 每個用戶有自己的家目錄 ,且只能訪問自己的家目錄 對用戶進行磁盤配額,每個用戶的可用空間不同 允許用戶在ftp server上隨意切換目錄 允許用戶查看

如何基於 k8s 開發高可靠服務?容器雲牛人有話說

容器雲?? k8s 是當前主流的容器編排服務,它主要解決「集群環境」下「容器化應用」的「管理問題」,主要包括如下幾方面:?? 容器集群管理 編排? 調度? 訪問? ? 基礎設施管理 計算資源? 網絡資源? 存儲資源?? k8s 的強大依賴於它良好的設計理念和抽象,吸引了越來越多的開發者投入到 k8

基於flask開發web微信

window 自己 網頁 time dal -s 最近聯系人 bin in use 流程 階段一 目標:基於falsk編寫登錄頁面,獲取二維碼 解析:1:、二維碼圖片地址有個後綴字符串 2、圖片生成之前,先獲取到隨機字符串再生成二維碼 3、二維碼的圖片的來源

一、ESP8266入門(基於LUA開發

opera 包括 blog 情況 探索 到你 哈哈哈 打開 雜項 序 一入坑便停不下來。。。 還挺有意思的哈,233,,,, 資料雜,自己一個一個去找確實浪費了不少時間,而且大多還都是英文的,需要硬著頭皮看。 這次實踐入門,更是對英語的重要確信無疑。Github必

[ Python ] Flask 基於 Web開發 大型程序的結構實例解析

精確 object commit static AS AI .sql version bar      作為一個編程入門新手,Flask是我接觸到的第一個Web框架。想要深入學習,就從《FlaskWeb開發:基於Python的Web應用開發實戰》這本書入手,本書由於是翻譯

基於CXF開發crm服務

config 註解 註冊服務 mil 一個 action http emp jdbc 1 基於CXF開發crm服務 1.1 數據庫環境搭建 1.2 web項目環境搭建 第一步:創建動態web項目 第二步:導入CXF相關jar包 第三步:配置web.xml

基於servlet開發的財務收支管理系統

用戶登錄 varchar 軟件設計 安全性 prim 財務 文檔 設計 安全 本系統開發是基於B/S模式的,開發工具:Eclipse或myeclipse 項目後端開發語言:Java,使用servlet

基於java開發的開原始碼GPS北斗位置服務監控平臺

最近在研究位置服務平臺,基於全球衛星定位技術(GNSS)、網際網路技術、空間地理資訊科技(GIS)、3G/4G無線通訊技術,面向全國公眾使用者建立大容量、實時、穩定的位置資訊服務運營平臺。實現管理目標的實時位置跟蹤,歷史軌跡查詢,超速、越區、防盜搶等報警, 遠端控制、油量監控,資料統計分析與報表等功能。平臺採

JSON Web Token實戰篇——基於koa開發WEB後臺認證機制

今天來說說JSON Web Token,JSON Web Token(縮寫 JWT)是目前最流行的跨域認證解決方案。關於它的介紹,可以看阮一峰的這篇文章JSON Web Token 入門教程 工作流程 這裡直接使用官網的圖 知道了JWT的原理後,我們來看一下如何基於koa開發web

嵌入式Linux基於QML開發QtMultimedia應用

ByToradex秦海 1). 簡介 使用QML語言進行QT應用程式開發可以將介面開發和邏輯控制分開,提高應用的開發週期和靈活性;另外對於多媒體應用非常重要的一點是,基於QML/QT Quick 的應用程式可以直接呼叫GPU進行加速,這大大提高了多媒體應用在嵌入式系

基於Omapl138開發板linux3.3系統分析do_initcall()函式

參考了網上的很多內容,網上的分析基本上是基於linux2.6或者3.1的核心,對於這個函式而言,其實大同小異,但是幾乎沒有哪篇文章能一次性把我想要了解的東西全部呈現,所以自己嘗試整理如下: do_initcalls()-> static void __init do_init