日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

入门HBase

發布時間:2025/3/21 编程问答 25 豆豆
生活随笔 收集整理的這篇文章主要介紹了 入门HBase 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

團隊內部要分享HBase的知識,之前研究了一段時間,知識比較零散,這一次就系統化的整理一番,之后在想到Hbase的時候,看著一篇就夠了。

概覽

特性

Hbase是一種NoSQL數據庫,這意味著它不像傳統的RDBMS數據庫那樣支持SQL作為查詢語言。Hbase是一種分布式存儲的數據庫,技術上來講,它更像是分布式存儲而不是分布式數據庫,它缺少很多RDBMS系統的特性,比如列類型,輔助索引,觸發器,和高級查詢語言等待。那Hbase有什么特性呢?如下:

  • 強讀寫一致,但是不是“最終一致性”的數據存儲,這使得它非常適合高速的計算聚合
  • 自動分片,通過Region分散在集群中,當行數增長的時候,Region也會自動的切分和再分配
  • 自動的故障轉移
  • Hadoop/HDFS集成,和HDFS開箱即用,不用太麻煩的銜接
  • 豐富的“簡潔,高效”API,Thrift/REST API,Java API
  • 塊緩存,布隆過濾器,可以高效的列查詢優化
  • 操作管理,Hbase提供了內置的web界面來操作,還可以監控JMX指標

什么時候用Hbase?

Hbase不適合解決所有的問題:

  • 首先數據庫量要足夠多,如果有十億及百億行數據,那么Hbase是一個很好的選項,如果只有幾百萬行甚至不到的數據量,RDBMS是一個很好的選擇。因為數據量小的話,真正能工作的機器量少,剩余的機器都處于空閑的狀態
  • 其次,如果你不需要輔助索引,靜態類型的列,事務等特性,一個已經用RDBMS的系統想要切換到Hbase,則需要重新設計系統。
  • 最后,保證硬件資源足夠,每個HDFS集群在少于5個節點的時候,都不能表現的很好。因為HDFS默認的復制數量是3,再加上一個NameNode。

Hbase在單機環境也能運行,但是請在開發環境的時候使用。

內部應用

  • 存儲業務數據:車輛GPS信息,司機點位信息,用戶操作信息,設備訪問信息。。。
  • 存儲日志數據:架構監控數據(登錄日志,中間件訪問日志,推送日志,短信郵件發送記錄。。。),業務操作日志信息
  • 存儲業務附件:UDFS系統存儲圖像,視頻,文檔等附件信息

不過在公司使用的時候,一般不使用原生的Hbase API,使用原生的API會導致訪問不可監控,影響系統穩定性,以致于版本升級的不可控。

Hbase架構

img

  • Zookeeper,作為分布式的協調。RegionServer也會把自己的信息寫到ZooKeeper中。
  • HDFS是Hbase運行的底層文件系統
  • RegionServer,理解為數據節點,存儲數據的。
  • Master RegionServer要實時的向Master報告信息。Master知道全局的RegionServer運行情況,可以控制RegionServer的故障轉移和Region的切分。

架構細化

image.png

  • HMaster是Master Server的實現,負責監控集群中的RegionServer實例,同時是所有metadata改變的接口,在集群中,通常運行在NameNode上面,這里有一篇更細的HMaster介紹

    • HMasterInterface暴露的接口,Table(createTable, modifyTable, removeTable, enable, disable),ColumnFamily (addColumn, modifyColumn, removeColumn),Region (move, assign, unassign)
    • Master運行的后臺線程:LoadBalancer線程,控制region來平衡集群的負載。CatalogJanitor線程,周期性的檢查hbase:meta表。
  • HRegionServer是RegionServer的實現,服務和管理Regions,集群中RegionServer運行在DataNode

    • HRegionRegionInterface暴露接口:Data (get, put, delete, next, etc.),Region (splitRegion, compactRegion, etc.)
    • RegionServer后臺線程:CompactSplitThread,MajorCompactionChecker,MemStoreFlusher,LogRoller
  • Regions,代表table,Region有多個Store(列簇),Store有一個Memstore和多個StoreFiles(HFiles),StoreFiles的底層是Block。

存儲設計

在Hbase中,表被分割成多個更小的塊然后分散的存儲在不同的服務器上,這些小塊叫做Regions,存放Regions的地方叫做RegionServer。Master進程負責處理不同的RegionServer之間的Region的分發。在Hbase實現中HRegionServer和HRegion類代表RegionServer和Region。HRegionServer除了包含一些HRegions之外,還處理兩種類型的文件用于數據存儲

  • HLog, 預寫日志文件,也叫做WAL(write-ahead log)
  • HFile 真實的數據存儲文件

HLog

  • MasterProcWAL:HMaster記錄管理操作,比如解決沖突的服務器,表創建和其它DDLs等操作到它的WAL文件中,這個WALs存儲在MasterProcWALs目錄下,它不像RegionServer的WALs,HMaster的WAL也支持彈性操作,就是如果Master服務器掛了,其它的Master接管的時候繼續操作這個文件。

  • WAL記錄所有的Hbase數據改變,如果一個RegionServer在MemStore進行FLush的時候掛掉了,WAL可以保證數據的改變被應用到。如果寫WAL失敗了,那么修改數據的完整操作就是失敗的。

    • 通常情況,每個RegionServer只有一個WAL實例。在2.0之前,WAL的實現叫做HLog
    • WAL位于/hbase/WALs/目錄下
    • MultiWAL: 如果每個RegionServer只有一個WAL,由于HDFS必須是連續的,導致必須寫WAL連續的,然后出現性能問題。MultiWAL可以讓RegionServer同時寫多個WAL并行的,通過HDFS底層的多管道,最終提升總的吞吐量,但是不會提升單個Region的吞吐量。
  • WAL的配置:

    // 啟用multiwal <property><name>hbase.wal.provider</name><value>multiwal</value> </property>

Wiki百科關于WAL

HFile

HFile是Hbase在HDFS中存儲數據的格式,它包含多層的索引,這樣在Hbase檢索數據的時候就不用完全的加載整個文件。索引的大小(keys的大小,數據量的大小)影響block的大小,在大數據集的情況下,block的大小設置為每個RegionServer 1GB也是常見的。

探討數據庫的數據存儲方式,其實就是探討數據如何在磁盤上進行有效的組織。因為我們通常以如何高效讀取和消費數據為目的,而不是數據存儲本身。

Hfile生成方式

起初,HFile中并沒有任何Block,數據還存在于MemStore中。

Flush發生時,創建HFile Writer,第一個空的Data Block出現,初始化后的Data Block中為Header部分預留了空間,Header部分用來存放一個Data Block的元數據信息。

而后,位于MemStore中的KeyValues被一個個append到位于內存中的第一個Data Block中:

:如果配置了Data Block Encoding,則會在Append KeyValue的時候進行同步編碼,編碼后的數據不再是單純的KeyValue模式。Data Block Encoding是HBase為了降低KeyValue結構性膨脹而提供的內部編碼機制。

image.png

讀寫簡流程

image.png

Hbase單機模式安裝

這一次來部署一個單機版的Hbase,單獨的Hbase daemon(Master,RegionServers和ZooKeeper)運行在同一個JVM進程中,然后持久化存儲到文件系統中。這是最簡單的部署,但是卻能幫助我們更好的理解Hbase。安裝完成之后,我們在演示一下hbase命令行的用法。

image

環境

  • CentOS 7
  • Hbase 1.2.8

安裝單機

  • 確保安裝了jdk,在Linux上使用自帶的包管理器直接安裝就好,使用二進制也是一個不錯的選擇,我用的是CentOS
  • yum install java-1.8.0-openjdk* -y
  • 下載Hbase的二進制包,下載地址位于http://mirror.bit.edu.cn/apache/hbase/hbase-1.2.8/,然后解壓到系統的目錄。
  • tar -xf hbase-1.2.8-bin.tar.gz cd hbase-1.2.8
  • 配置hbase的環境變量,修改JAVA_HOME。注意看下自己的JAVA_HOME在什么位置
  • image

    vim conf/hbase-env.sh // 注意這個是在CentOS上的java位置 export JAVA_HOME=/etc/alternatives/java_sdk_1.8.0/
  • 配置onf/hbase-site.xml,這個是Hbase的主配置文件,你可以指定hbase和ZooKeeper數據寫入的目錄,當然也可以指定hbase的根目錄在哪個位置。
  • 我將hbase的目錄放在hadoop用戶家目錄的hbase目錄下。我們不用事先創建好hbase的data目錄,hbase會自動幫我們創建好的,如果已經存在了data目錄,hbase會將存在的目錄進行遷移。

    useradd -s /sbin/nologin -m hadoopvim conf/hbase-site.xml <configuration><property><name>hbase.rootdir</name><value>file:///home/hadoop/hbase</value></property><property><name>hbase.zookeeper.property.dataDir</name><value>/home/hadoop/zookeeper</value></property><property><name>hbase.unsafe.stream.capability.enforce</name><value>false</value><description>Controls whether HBase will check for stream capabilities (hflush/hsync).Disable this if you intend to run on LocalFileSystem, denoted by a rootdirwith the 'file://' scheme, but be mindful of the NOTE below.WARNING: Setting this to false blinds you to potential data loss andinconsistent system state in the event of process and/or node failures. IfHBase is complaining of an inability to use hsync or hflush it's mostlikely not a false positive.</description></property> </configuration>
  • Hbase二進制包下有start-hbase腳本,可以方便的啟動hbase,如果我們的配置是正確的,那么會正常啟動。
  • ./bin/start-hbase.sh

    image

    如果啟動之后,可以打開http://localhost:16010查看Hbase的Web UI

    image

    使用Hbase

    我們可以先用Hbase提供的命令行工具,位于hbase的/bin/目錄下

  • 連接Hbase
  • ./hbase shell
  • 查看幫助信息, 敲
  • >help

    image

  • 創建一個表,必須要指定表名稱和列簇名
  • hbase(main):003:0> create 'test', 'cf' 0 row(s) in 1.6320 seconds=> Hbase::Table - test

    image

  • 列出關于你的表的信息,list 'sometable'
  • image

  • 查看表更為詳細的信息,使用describe命令
  • image

  • 把數據放到表中
  • image

  • 查看表中的所有數據
  • image

  • 獲取單行的數據
  • image

  • 其余的命令可以自行嘗試
  • 退出shell,使用quit
  • 這里演示了下單機版的hbase如何安裝,了解hbase shell的基本用法,關于Hbase更深入的東西,可以了解下官方文檔。

    Hbase數據模型

    在Hbase中,有一些術語需要提前了解。如下:

    • Table:Hbase的table由多個行組成
    • Row:一個行在Hbase中由一個或多個有值的列組成。Row按照字母進行排序,因此行健的設計非常重要。這種設計方式可以讓有關系的行非常的近,通常行健的設計是網站的域名反轉,比如(org.apache.www, org.apache.mail, org.apache.jira),這樣的話所有的Apache的域名就很接近。
    • Column:列由列簇加上列的標識組成,一般是“列簇:列標識”,創建表的時候不用指定列標識
    • Column Family:列簇在物理上包含了許多的列與列的值,每個列簇都有一些存儲的屬性可配置。例如是否使用緩存,壓縮類型,存儲版本數等。在表中,每一行都有相同的列簇,盡管有些列簇什么東西也沒有存。
    • Column Qualifier:列簇的限定詞,理解為列的唯一標識。但是列標識是可以改變的,因此每一行可能有不同的列標識
    • Cell:Cell是由row,column family,column qualifier包含時間戳與值組成的,一般表達某個值的版本
    • Timestamp:時間戳一般寫在value的旁邊,代表某個值的版本號,默認的時間戳是你寫入數據的那一刻,但是你也可以在寫入數據的時候指定不同的時間戳

    HBase 是一個稀疏的、分布式、持久、多維、排序的映射,它以行鍵(row key),列鍵(column key)和時間戳(timestamp)為索引。

    Hbase在存儲數據的時候,有兩個SortedMap,首先按照rowkey進行字典排序,然后再對Column進行字典排序。

    img

    測試數據

    create 'user','info','ship';put 'user', '524382618264914241', 'info:name', 'zhangsan' put 'user', '524382618264914241', 'info:age',30 put 'user', '524382618264914241', 'info:height',168 put 'user', '524382618264914241', 'info:weight',168 put 'user', '524382618264914241', 'info:phone','13212321424' put 'user', '524382618264914241', 'ship:addr','beijing' put 'user', '524382618264914241', 'ship:email','sina@sina.com' put 'user', '524382618264914241', 'ship:salary',3000put 'user', '224382618261914241', 'info:name', 'lisi' put 'user', '224382618261914241', 'info:age',24 put 'user', '224382618261914241', 'info:height',158 put 'user', '224382618261914241', 'info:weight',128 put 'user', '224382618261914241', 'info:phone','13213921424' put 'user', '224382618261914241', 'ship:addr','chengdu' put 'user', '224382618261914241', 'ship:email','qq@sina.com' put 'user', '224382618261914241', 'ship:salary',5000put 'user', '673782618261019142', 'info:name', 'zhaoliu' put 'user', '673782618261019142', 'info:age',19 put 'user', '673782618261019142', 'info:height',178 put 'user', '673782618261019142', 'info:weight',188 put 'user', '673782618261019142', 'info:phone','17713921424' put 'user', '673782618261019142', 'ship:addr','shenzhen' put 'user', '673782618261019142', 'ship:email','126@sina.com' put 'user', '673782618261019142', 'ship:salary',8000put 'user', '813782218261011172', 'info:name', 'wangmazi' put 'user', '813782218261011172', 'info:age',19 put 'user', '813782218261011172', 'info:height',158 put 'user', '813782218261011172', 'info:weight',118 put 'user', '813782218261011172', 'info:phone','12713921424' put 'user', '813782218261011172', 'ship:addr','xian' put 'user', '813782218261011172', 'ship:email','139@sina.com' put 'user', '813782218261011172', 'ship:salary',10000put 'user', '510824118261011172', 'info:name', 'yangyang' put 'user', '510824118261011172', 'info:age',18 put 'user', '510824118261011172', 'info:height',188 put 'user', '510824118261011172', 'info:weight',138 put 'user', '510824118261011172', 'info:phone','18013921626' put 'user', '510824118261011172', 'ship:addr','shanghai' put 'user', '510824118261011172', 'ship:email','199@sina.com' put 'user', '510824118261011172', 'ship:salary',50000

    Hbase表(Schema)設計要點

    只要是數據庫都存在,模式設計的問題,關系型中有模式設計的范式,Hbase作為列式存儲數據庫,其模式設計也非常重要。

    設計時需要關注的屬性,如何設計這些屬性等

    Hbase與關系型數據庫對比

    屬性HbaseRDBMS
    數據類型只有字符串豐富的數據類型
    數據操作增刪改查,不支持join各種各樣的函數與表連接
    存儲模式基于列式存儲基于表結構和行式存儲
    數據保護更新后仍然保留舊版本替換
    可伸縮性輕易增加節點需要中間層,犧牲性能

    Hbase設計時要考慮的因素

    Hbase關鍵概念:表,rowkey,列簇,時間戳

    • 這個表應該有多少列簇
    • 列簇使用什么數據
    • 每個列簇有有多少列
    • 列名是什么,盡管列名不必在建表時定義,但讀寫數據是要知道的
    • 單元應該存放什么數據
    • 每個單元存儲多少時間版本
    • 行健(rowKey)結構是什么,應該包含什么信息

    設計要點

    行健設計

    關鍵部分,直接關系到后續服務的訪問性能。如果行健設計不合理,后續查詢服務效率會成倍的遞減。

    • 避免單調的遞增行健,因為Hbase的行健是有序排列的,這樣可能導致一段時間內大部分寫入集中在某一個Region上進行操作,負載都在一臺節點上。可以設計成: [metric_type][event_timestamp],不同的metric_type可以將壓力分散到不同的region上
    • 行健短到可讀即可,因為查詢短鍵不必長鍵性能好多少,所以設計時要權衡長度。
    • 行健不能改變,唯一可以改變的方式是先刪除后插入

    列簇設計

    列簇是一些列的集合,一個列簇的成員有相同的前綴,以冒號(:)作為分隔符。

    • 現在Hbase不能很好處理2~3個以上的列簇,所以盡可能讓列簇少一些,如果表有多個列簇,列簇A有100萬行數據,列簇B有10億行,那么列簇A會分散到很多的Region導致掃描列簇A的時候效率底下。
    • 列簇名的長度要盡量小,一個為了節省空間,另外加快效率,比如d表示data,v表示value

    列簇屬性配置

    • HFile數據塊,默認是64KB,數據庫的大小影響數據塊索引的大小。數據塊大的話一次加載進內存的數據越多,掃描查詢效果越好。但是數據塊小的話,隨機查詢性能更好
    > create 'mytable',{NAME => 'cf1', BLOCKSIZE => '65536'}
    • 數據塊緩存,數據塊緩存默認是打開的,如果一些比較少訪問的數據可以選擇關閉緩存
    > create 'mytable',{NAME => 'cf1', BLOCKCACHE => 'FALSE'}
    • 數據壓縮,壓縮會提高磁盤利用率,但是會增加CPU的負載,看情況進行控制
    > create 'mytable',{NAME => 'cf1', COMPRESSION => 'SNAPPY'}

    Hbase表設計是和需求相關的,但是遵守表設計的一些硬性指標對性能的提升還是很有幫助的,這里整理了一些設計時用到的要點。

    Java API操作

    Hbase有多種不同的客戶端,如REST客戶端,Thift客戶端,ORM框架Kundera等等。 Hbase也提供了Java的API來操作表與列簇等信息,它的shell就是對Java的API做了一層封裝。

    Hbase的Java API提供了很多高級的特性:

    • 元數據管理,列簇的數據壓縮,region分隔
    • 創建,刪除,更新,讀取 rowkey

    我們還是直接看代碼這樣理解的更容易

    環境

    • Hbase 0.98
    • Java 1.8
    • Zookeeper 3.4.6
    • Mac OS

    案例

    Hbase的客戶端版本不一致實驗結果很容易出現問題,盡量采用同樣的版本。因為服務端實驗的是Hbase0.98,客戶端也用0.98,另外由于Hadoop 2.x的版本現對于1.x做了很大的提升,建議采用Hbase-hadoop 2.x的客戶端。

    <dependency><groupId>org.apache.hbase</groupId><artifactId>hbase-client</artifactId><version>0.98.24-hadoop2</version></dependency>

    建立連接

  • 直接新建HTable("tableName"),但是這種每次創建表的時候因為都要查詢.meta表,來判斷表是不是存在,導致創建表的過程會有點慢,所以不建議每個請求都創建一個Htable

  • 使用HTablePool,它和HTable的創建方式很像,但是如果采用連接池的話,它就不會給每個請求都單獨創建一個Htable了。

  • 在創建Htable或者HtablePool的時候都可以指定更詳細的配置信息。

    image

    image

    HTablePool hTablePool = new HTablePool(); hTablePool.getTable("user");

    增刪改查

    rowkey是代表Hbase中表的唯一一個行,同時像列簇 ,時間戳等用來定位表中的部分數據,Java的API對Hbas的CURD提供了如下的類:

    • Put
    • Get
    • Delete
    • Scan
    • Increment

    我們詳細的討論幾個類,剩余的可以舉一反三。

    寫數據

    當寫請求收到的時候,默認數據同步的寫到Hlog中和MemStore,同時在兩個地方寫是為了保證數據的持久性,Memstore最終會持久化到磁盤中的Hfile中。每次MemStore進行Flush的時候,就會創建一個新的Hfile。

    Put類用于向Hbase的表中存儲數據,存儲數據時,Put的實例必須要指定Rowkey

    ?

    image

    創建完Put實例后,再向其中添加數據

    ?

    image

    public void put() throws IOException {// 獲取默認的配置Configuration conf = HBaseConfiguration.create();// 獲取Table實例 HTable table = new HTable(conf, "tab1");// 創建Put實例,并且指定rowKey Put put = new Put(Bytes.toBytes("row-1"));// 添加一個 column,值為 "Hello",在 "cf1:greet" 列中put.add(Bytes.toBytes("cf1"), Bytes.toBytes("greet"), Bytes.toBytes("Hello"));// 添加一個 column,值為 "John",在 "cf1:person" 列中put.add(Bytes.toBytes("cf1"), Bytes.toBytes("person"), Bytes.toBytes("John"));table.put(put); table.close();}

    數據也可以批量的進行插入:

    // table對象可以傳入List參數
    table.put(final List<Put> puts)

    執行結果:

    ?

    image

    讀數據

    Hbase使用LRU緩存讀取數據。Htable對象使用下面的方法讀取數據

    image

    而Get實例的構造方法和Put很像,構造方法要指定一個rowkey。

    image

    如果要查找特定的cell,就是特定列的數據,可以采用額外的方法進行更加精細的調控。

    image

    看一下如下的案例代碼:

    public void get() throws IOException {// 獲取默認的配置Configuration conf = HBaseConfiguration.create();// 獲取Table實例HTable table = new HTable(conf, "tab1");// 創建Put實例,并且指定rowKeyGet get = new Get(Bytes.toBytes("row-1"));//get.addColumn(Bytes.toBytes("cf1"), Bytes.toBytes("greet"));// 添加一個 column,值為 "John",在 "cf1:person" 列中Result result = table.get(get);byte[] value = result.getValue(Bytes.toBytes("cf1"), Bytes.toBytes("greet"));System.out.println("獲取到的值" + new String(value));table.close();}

    執行結果

    ?

    image

    更新數據

    更新數據與寫數據基本一致,只是在Put實例賦值的時候,在相同的列上設置不同的值,操作的時候就會更新為新的值。

    代碼如下:

    public void update() throws IOException {Configuration conf = HBaseConfiguration.create();// 獲取Table實例HTable table = new HTable(conf, "tab1");// 創建Put實例,并且指定rowKeyPut put = new Put(Bytes.toBytes("row-1"));// 添加一個 column,值為 "Hello",在 "cf1:greet" 列中put.add(Bytes.toBytes("cf1"), Bytes.toBytes("greet"), Bytes.toBytes("Good Morning"));// 添加一個 column,值為 "John",在 "cf1:person" 列中 // put.add(Bytes.toBytes("cf1"), Bytes.toBytes("person"), Bytes.toBytes("John"));table.put(put);table.close();}

    執行結果:

    ?

    image

    刪除數據

    Delete命令只是標記當前的數據為刪除狀態,而不是立刻的刪除,也就是先進行邏輯刪除。實際上的刪除是在Hfile進行壓縮的時候,這些被標記的記錄就會被刪除掉。

    Delete對象與Put和Get也很像

    image

    構造Delete實例

    ?

    image

    如果想要進行更加詳細的指定,可以再指定具體的列等信息

    ?

    image

    看下面的案例代碼:

    public void delete() throws IOException {Configuration conf = HBaseConfiguration.create();// 獲取Table實例HTable table = new HTable(conf, "tab1");// 創建Delete實例,并且指定rowKeyDelete delete = new Delete(Bytes.toBytes("row-1"));// 刪除 column "cf1:greet" delete.deleteColumn(Bytes.toBytes("cf1"), Bytes.toBytes("greet"));table.delete(delete);table.close();}

    執行結果:連續執行兩次刪除

    image

    操作優化

    一個系統上線之后,開發和調優將一直貫穿系統的生命周期中,HBase也不列外。這里主要說一些Hbase的調優

    Hbase查詢優化

    作為NoSQL數據庫,增刪改查是其最基本的功能,其中查詢是最常用的一項。

    設置Scan緩存

    HBase中Scan查詢可以設置緩存,方法是setCaching(),這樣可以有效的減少服務端與客戶端的交互,更有效的提升掃描查詢的性能。

    /*** Set the number of rows for caching that will be passed to scanners.* If not set, the default setting from {@link HTable#getScannerCaching()} will apply.* Higher caching values will enable faster scanners but will use more memory.* @param caching the number of rows for caching* 設置scanners緩存的行數*/public void setCaching(int caching) {this.caching = caching;}

    顯示的指定列

    當使用Scan或者GET獲取大量的行時,最好指定所需要的列,因為服務端通過網絡傳輸到客戶端,數據量太大可能是瓶頸。如果能有效過濾部分數據,能很大程度的減少網絡I/O的花費。

    /*** Get all columns from the specified family.* <p>* Overrides previous calls to addColumn for this family.* @param family family name* @return this* 獲取指定列簇的所有列*/public Scan addFamily(byte [] family) {familyMap.remove(family);familyMap.put(family, null);return this;}/*** Get the column from the specified family with the specified qualifier.* <p>* Overrides previous calls to addFamily for this family.* @param family family name* @param qualifier column qualifier* @return this* 獲取指定列簇的特定列*/public Scan addColumn(byte [] family, byte [] qualifier) {NavigableSet<byte []> set = familyMap.get(family);if(set == null) {set = new TreeSet<byte []>(Bytes.BYTES_COMPARATOR);}if (qualifier == null) {qualifier = HConstants.EMPTY_BYTE_ARRAY;}set.add(qualifier);familyMap.put(family, set);return this;}

    一般用:
    scan.addColumn(...)

    關閉ResultScanner

    如果在使用table.getScanner之后,忘記關閉該類,它會一直和服務端保持連接,資源無法釋放,從而導致服務端的某些資源不可用。

    所以在用完之后,需要執行關閉操作,這點與JDBS操作MySQL類似

    scanner.close()

    禁用塊緩存

    如果批量進行全表掃描,默認是有緩存的,如果此時有緩存,會降低掃描的效率。

    scan.setCacheBlocks(true|false);

    對于經常讀到的數據,建議使用默認值,開啟塊緩存

    緩存查詢結果

    對于頻繁查詢HBase的應用場景,可以考慮在應用程序和Hbase之間做一層緩存系統,新的查詢先去緩存查,緩存沒有再去查Hbase。

    寫入優化

    寫也是Hbase常有的操作之一,并且Hbase在寫入操作上有著其他NoSQL無法比擬的優勢,下面講如何優化寫入操作

    關閉寫WAL日志

    一般為了保證系統的高可用性,WAL日志默認是開啟狀態,WAL主要用于災難恢復的,如果應用可以容忍一定的數據丟失風險,可以在寫數據的時候,關閉寫WAL。

    風險:?當RegionServer宕機時,寫入的數據出現丟失,且無法恢復

    image.png

    設置AutoFlush

    Htable有一個屬性是AutoFlush,該屬性用于支持客戶端的批量更新,默認是true,當客戶端每收到一條數據,立刻發送到服務端,如果設置為false,當客戶端提交put請求時候,先將該請求在客戶端緩存,到達閾值的時候或者執行hbase.flushcommits(),才向RegionServer提交請求。

    風險?在請求未發送到RegionServer之前客戶端崩潰,數據也會丟失

    table.setAutoFlush(false);table.setWriteBufferSize( 12 * 1024 * 1024 );

    預創建Region

    一般表剛開始只有一個Region,插入該表的數據都會保存在此Region中,插入該表的所有塑化劑都會保存在該Region中,當到達一定的閾值時,才發生分裂。 這樣開始時刻針對該表的寫操作都集中在某臺服務器上,造成這臺服務器的壓力很緊張,同時對整個集群資源的浪費

    建議剛開始的時候預創建Region,可以使用Hbase自帶的RegionSplitter

    延遲日志flush

    默認寫入操作,首先寫入WAL,并且在1S內寫入HDFS,這個時間默認是1S,可以通過參數配置

    hbase.regionserver.optionallogflushinterval

    可以配置大一點的值,比如5s,這段時間數據會保留在內存中,直到RegionServer周期性的執行flush操作。

    Scan的重要參數

    Scan是操作Hbase中非常常用的一個操作,雖然前面的Hbase API操作簡單的介紹了Scan的操作,但不夠詳細,由于Scan非常常用,關于其詳細的整理也是很有必要的。

    Scan

    HBase中的數據表通過劃分成一個個的Region來實現數據的分片,每一個Region關聯一個RowKey的范圍區間,而每一個Region中的數據,按RowKey的字典順序進行組織。

    正是基于這種設計,使得HBase能夠輕松應對這類查詢:"指定一個RowKey的范圍區間,獲取該區間的所有記錄", 這類查詢在HBase被稱之為Scan。

    1 . 構建Scan,指定startRow與stopRow,如果未指定的話會進行全表掃描
    2 . 獲取ResultScanner
    3 . 遍歷查詢結果
    4 . 關閉ResultScanner

    public void stringFilter() throws IOException {Configuration conf = HBaseConfiguration.create();// 獲取Table實例HTable table = new HTable(conf, "user");// 構建ScanScan scan = new Scan();scan = scan.setStartRow(Bytes.toBytes("startRowxxx")).setStopRow(Bytes.toBytes("StopRowxxx"));RowFilter filter = new RowFilter(CompareFilter.CompareOp.EQUAL,new BinaryComparator(Bytes.toBytes("224382618261914241")));scan.setFilter(filter);// 獲取resultScannerResultScanner scanner = table.getScanner(scan);Result result = null;// 處理結果while ((result = scanner.next()) != null) {byte[] value = result.getValue(Bytes.toBytes("ship"), Bytes.toBytes("addr"));if (value == null || value.length == 0) {continue;}System.out.println(new String(value));System.out.println("hello World");}// 關閉ResultScannerscanner.close();table.close();}

    其它的設置參數

    Caching: 設置一次RPC請求批量讀取的Results數量

    下面的示例代碼設定了一次讀取回來的Results數量為100:

    scan.setCaching(100);

    Client每一次往RegionServer發送scan請求,都會批量拿回一批數據(由Caching決定過了每一次拿回的Results數量),然后放到本次的Result Cache中:

    image

    應用每一次讀取數據時,都是從本地的Result Cache中獲取的。如果Result Cache中的數據讀完了,則Client會再次往RegionServer發送scan請求獲取更多的數據。

    Batch: 設置每一個Result中的列的數量

    下面的示例代碼設定了每一個Result中的列的數量的限制值為3:

    scan.setBatch(3);

    該參數適用于一行數據過大的場景,這樣,一行數據被請求的列會被拆成多個Results返回給Client。

    舉例說明如下:

    假設一行數據中共有十個列:
    {Col01,Col02,Col03,Col04,Col05,Col06,Col07,Col08,Col09, Col10}
    假設Scan中設置的Batch為3,那么,這一行數據將會被拆成4個Results返回:

    Result1 -> {Col01,Col02,Col03} Result2 -> {Col04,Col05,Col06} Result3 -> {Col07,Col08,Col09} Result4 -> {Col10}

    關于Caching參數,我們說明了是Client每一次從RegionServer側獲取到的Results的數量,上例中,一行數據被拆成了4個Results,這將會導致Caching中的計數器被減了4次。結合Caching與Batch,我們再列舉一個稍復雜的例子:

    假設,Scan的參數設置如下:

    final byte[] start = Bytes.toBytes("Row1");
    final byte[] stop = Bytes.toBytes("Row5");
    Scan scan = new Scan();
    scan.withStartRow(start).withStopRow(stop);
    scan.setCaching(10);
    scan.setBatch(3);

    待讀取的數據RowKey與所關聯的列集如下所示:

    Row1: {Col01,Col02,Col03,Col04,Col05,Col06,Col07,Col08,Col09,Col10}
    Row2: {Col01,Col02,Col03,Col04,Col05,Col06,Col07,Col08,Col09,Col10,Col11}
    Row3: {Col01,Col02,Col03,Col04,Col05,Col06,Col07,Col08,Col09,Col10}

    再回顧一下Caching與Batch的定義:

    Caching: 影響一次讀取返回的Results數量。

    Batch: 限定了一個Result中所包含的列的數量,如果一行數據被請求的列的數量超出Batch限制,那么這行數據會被拆成多個Results。

    那么, Client往RegionServer第一次請求所返回的結果集如下所示:

    Result1 -> Row1: {Col01,Col02,Col03}
    Result2 -> Row1: {Col04,Col05,Col06}
    Result3 -> Row1: {Col07,Col08,Col09}
    Result4 -> Row1: {Col10}
    Result5 -> Row2: {Col01,Col02,Col03}
    Result6 -> Row2: {Col04,Col05,Col06}
    Result7 -> Row2: {Col07,Col08,Col09}
    Result8 -> Row2: {Col10,Col11}
    Result9 -> Row3: {Col01,Col02,Col03}
    Result10 -> Row3: {Col04,Col05,Col06}

    Limit: 限制一次Scan操作所獲取的行的數量

    同SQL語法中的limit子句,限制一次Scan操作所獲取的行的總量:

    scan.setLimit(10000);

    注意:Limit參數是在2.0版本中新引入的。但在2.0.0版本中,當Batch與Limit同時設置時,似乎還存在一個BUG,初步分析問題原因應該與BatchScanResultCache中的numberOfCompletedRows計數器邏輯處理有關。因此,暫時不建議同時設置這兩個參數。

    CacheBlock: RegionServer側是否要緩存本次Scan所涉及的HFileBlocks

    scan.setCacheBlocks(true);

    e) Raw Scan: 是否可以讀取到刪除標識以及被刪除但尚未被清理的數據

    scan.setRaw(true);

    MaxResultSize: 從內存占用量的維度限制一次Scan的返回結果集

    下面的示例代碼將返回結果集的最大值設置為5MB:

    scan.setMaxResultSize(5 * 1024 * 1024);

    Reversed Scan: 反向掃描

    普通的Scan操作是按照字典順序從小到大的順序讀取的,而Reversed Scan則恰好相反:

    scan.setReversed(true);

    帶Filter的Scan

    Filter可以在Scan的結果集基礎之上,對返回的記錄設置更多條件值,這些條件可以與RowKey有關,可以與列名有關,也可以與列值有關,還可以將多個Filter條件組合在一起,等等。

    最常用的Filter是SingleColumnValueFilter,基于它,可以實現如下類似的查詢:

    "返回滿足條件{列I:D的值大于等于10}的所有行"

    示例代碼如下:

    Filter豐富了HBase的查詢能力,但使用Filter之前,需要注意一點:Filter可能會導致查詢響應時延變的不可控制。因為我們無法預測,為了找到一條符合條件的記錄,背后需要掃描多少數據量,如果在有效限制了Scan范圍區間(通過設置StartRow與StopRow限制)的前提下,該問題能夠得到有效的控制。這些信息都要求使用Filter之前應該詳細調研自己的業務數據模型。

    最后

    本文有點長,作為參考吧

    參考

    • [HBase企業級開發實戰]
    • HBase參考文檔
    • 圖解HBase讀取流程:簡明HBase入門教程4
    • Hbase官方文檔
    • Hbase Shell Command
    • Hbase shell tuturial
    • HBase高性能隨機查詢之道 – HFile原理解析
    《新程序員》:云原生和全面數字化實踐50位技術專家共同創作,文字、視頻、音頻交互閱讀

    總結

    以上是生活随笔為你收集整理的入门HBase的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

    主站蜘蛛池模板: 色婷婷国产精品久久包臀 | 日韩精品一区二区三区不卡在线 | 一区二区日韩欧美 | 免费爱爱网址 | 强开乳罩摸双乳吃奶羞羞www | 欧美福利视频在线观看 | 日韩精彩视频在线观看 | 97久久久久久| 天天操天天干天天干 | 丰满少妇乱子伦精品看片 | 国产精品久久久久91 | 日本特黄一级大片 | 国产麻豆一区二区三区在线观看 | 亚洲AV无码久久精品色三人行 | 9999精品 | 国产精品资源网站 | 久久一二区 | 国产精品乱子伦 | 艳妇臀荡乳欲伦交换在线播放 | 国产富婆一级全黄大片 | 成年人在线观看视频免费 | 日韩欧美二区三区 | 星空大象在线观看免费播放 | 国产精品5区 | 一区二区三区四区五区在线视频 | 麻豆国产在线播放 | 亚洲精品www久久久久久广东 | 欧美性色网站 | 蜜桃久久久 | 亚色在线观看 | 日本在线中文字幕专区 | 亚洲成人黄色 | 风韵丰满熟妇啪啪区老熟熟女 | 国产日韩二区 | 亚洲国产成人va在线观看天堂 | 欧美精品在线观看视频 | 曰批免费视频播放免费 | 久久久久无码精品国产sm果冻 | 野花视频免费在线观看 | 成人音影 | 欧州一级片| 成年人黄色大全 | 四虎国产精品成人免费入口 | 亚洲天堂手机 | 少妇高潮露脸国语对白 | 一本一道久久a久久综合蜜桃 | 少妇av一区二区 | h视频在线观看网站 | 色网站免费在线观看 | 久色国产| 青草视频在线播放 | 亚洲欧美一二三区 | 欧美做受xxxxxⅹ性视频 | 黄色资源网 | 青青视频免费观看 | 成人特级毛片69免费观看 | 黄色无遮挡 | 日本一区二区三区在线看 | 国产精品500部| 欧美一区二区三区在线视频 | 久久婷婷伊人 | 你懂的视频网站 | 日韩久久久久久 | 荫道bbwbbb高潮潮喷 | 欧美色图另类 | 亚洲精品手机在线 | 久久久久久影院 | 色综合天天综合综合国产 | 国内偷拍第一页 | 囯产精品一品二区三区 | 人人射人人 | 秋霞午夜视频 | av基地网 | 奇米影视播放器 | 伊人导航 | 壮汉被书生c到合不拢腿 | 欧美精品久久久久久久多人混战 | 日韩免费在线观看视频 | 91夜色视频 | 国产区欧美区日韩区 | 久久久久亚洲av成人无码电影 | 曰本丰满熟妇xxxx性 | 国产精品一区二区三区在线免费观看 | 亚洲瑟瑟 | 亚洲精选av | 国产一级爱 | 人av在线| 日本在线看片 | 无套中出丰满人妻无码 | 国产一区伦理 | www.人人草| 男人的天堂在线播放 | 少妇一级淫片免费观看 | 交hdsexvideos娇小 | 人妻精品一区二区在线 | 蜜臀av一区二区三区激情综合 | 久久潮 | 日韩中文字幕亚洲精品欧美 | 欧美日韩一区二区三区在线电影 |