摘要:慕課網存儲原理剖析學習總結時間年月日星期一說明本文部分內容均來自慕課網。每一列簇包含多個列列標識符。每一列數據包含了版本和值版本。
慕課網《HBase 存儲原理剖析》學習總結
時間:2018年06月11日星期一
說明:本文部分內容均來自慕課網。@慕課網:https://www.imooc.com
教學源碼:無
學習源碼:https://github.com/zccodere/s...
第一章:課程介紹 1-1 課程介紹課程目標
HBase的存儲模式
HBase數據表解析
HBase存儲設計
HBase數據存取解析
第二章:存儲模式 2-1 存儲模式行式存儲與列式存儲介紹
行式存儲與列式存儲特點
行式存儲
維護大量的索引
存儲成本高
不能夠做到線性擴展
隨機讀取效率非常高
對事務的支持非常好
列式存儲
根據同一列數據的相似性原理,利于對數據進行壓縮
存儲成本低
由于每列數據分開存儲,可以并行查找多列的數據
行式存儲與列式存儲場景
行式存儲
表與表之間有關聯關系,數據量不大(小于千萬量級)
強事務關聯的特性
列式存儲
對于單列或者相對比較少的列獲取頻率較高
針對多列查詢,使用并行處理的查詢
利于數據壓縮和線性擴展的存儲
事務使用率不高,讀取的場景頻率不高,同時數據量非常大
隨機更新某一行的頻率不高
列簇式存儲:概念
列簇(多個數據列的組合),HBase表中的每個列都歸屬于某個列簇
列簇是表的schame的一部分,但是列并不是
創建表時,需要給出列簇的名稱,不需要給出列的名稱
列名都是以列簇作為前綴
訪問控制磁盤和內存的使用統計都是在列簇層面進行
HBase準確的說是列簇數據庫,而不是列數據庫
列簇數據庫將列組織為列簇,每列都必須是某個列簇的一部分
訪問數據的單元也是列
HBase表的組成
Table = RowKey + Family + Column + Timestamp + Value
RowKey :HBase中用RowKey去標識唯一的一行數據,一行數據中包含多個列簇
Family:多個列簇。每一列簇包含多個列
Column:列標識符。每一列數據包含了版本和值
Timestamp:版本。可以理解為時間戳,也可以理解為一個數據的版本
Value:數據值。數據本身的值
HBase數據存儲的模式
(Table, RowKey, Family, Column, Timestamp)-> Value
其實就是HBase表反過來看的樣子
【重點】更抽象一點,其實HBase表數據就是Key-Value結構的
圖解
列簇式存儲:列數據屬性
HBase重要特性:列數據版本的概念,默認一列數據可以保存三個版本
列簇式存儲:數據存儲原型
2-2 存儲示例示例表定義
示例表數據
第三章 表的解析 3-1 建表語句示例表語句定義
壓縮算法
算法 | 壓縮率 | 編碼速度 | 解碼速度 |
---|---|---|---|
GZip | 13.4% | 21MB/s | 118MB/s |
LZO | 20.5% | 135MB/s | 410MB/s |
Snappy | 22.2% | 172MB/s | 409MB/s |
在hbase-site.xml文件中配置或查看存儲目錄的節點
hbase.rootdir /home/hbase_data
進入到HBase系統目錄
.tmp
當對表做創建或刪除操作時,將表移動到tmp目錄下,然后再進行處理
臨時交換的表,臨時存儲一些當前需要修改的數據結構
WALs
預寫日志,被HLog實例管理的WAL文件
可以理解為存儲HBase的日志,HBase分布式數據庫系統的操作日志
archive
存儲表的歸檔和快照
HBase在做分割或合并操作完成后,會將Hfile文件移動到該目錄中,然后將之前的Hfile刪除掉
是由Master上的定時任務定期去處理,這個目錄的作用可以簡單理解為去管理HBase的數據
corrupt
用于存放損壞的日志文件,一般是空的
data
HBase存儲數據的核心目錄
系統表和用戶表數據都存儲在這里
hbase.id
HBase啟動運行后,是集群中的唯一ID,用來標識HBase進程用的
hbase.version
表明了集群的文件格式版本信息
其實就是表明了Hfile的版本信息
oldWALs
備份WALs中的日志文件
data目錄解析
HBase元信息表
Row Key | Value |
---|---|
table、key、time | region server |
HBase中的LSM存儲思想
什么是LSM樹
LSM日志結構合并樹,有兩個或兩個以上存儲數據的結構組成的,每一個數據結構各自對應自己的存儲介質
LSM樹的簡易模型描述
LSM思想在HBase中的思想
4-2 存儲模塊HBase數據存儲模塊簡介
RegionServer = Region + Store + MemStore + StoreFile + HFile + HLog
HBase Region解析
什么是Region
每一個Region都會存儲于確定的RegionServer上
Region的特點
是HBase中分布式存儲和負載均衡的最小單元
Region的數據不能低于集群中節點的數量
RegionServer對Region進行拆分
盡量讓Row key分散到不同的Region
HBase HFile解析
Store + MemStore + StoreFile
Store與列簇是一對一的關系
MemStore是一個內存數據結構,保存修改的數據
StoreFile是由內存數據寫入到文件后形成的
> ![image](https://note.youdao.com/yws/api/personal/file/BC358BAF87A44E01AC1E29C9742DF6F2?method=download&shareKey=416cc5492bf4a2243d657a2c6999b735)
HFile 文件
是HBase存儲數據文件的最基本的組織形式
底層是Hadoop的二進制格式文件
是用戶數據的實際載體,存儲Key-Value的數據
Scanned block section:會被讀取,主要是存儲用戶數據
Nonscanned block section:不會被讀取,主要包含元數據塊
Load-on-open section:RegionServer啟動時加載,主要是HFile的元數據
Trailer:HFile的基本信息,HFile元數據的一部分
> ![image](https://note.youdao.com/yws/api/personal/file/27F88E086AC5419F83F5BC9473060F52?method=download&shareKey=416cc5492bf4a2243d657a2c6999b735)
Data Block
HBase中數據的最基本的存儲單元
是實際存儲用戶數據的數據結構
包含很多Key-Value
> ![image](https://note.youdao.com/yws/api/personal/file/6C175A6EF8D546FCB02CED9E10B364DE?method=download&shareKey=416cc5492bf4a2243d657a2c6999b735)
HBase WAL解析
簡介介紹WAL(預寫日志)
WAL最重要的功能就是災難恢復
WAL解決了什么問題:HA(高可用)問題
怎么解決:遠程備份
> ![image](https://note.youdao.com/yws/api/personal/file/993E28018DCA4AD7AABDDF494154F91B?method=download&shareKey=416cc5492bf4a2243d657a2c6999b735)
HLog
WAL是通過HLog模塊實現的
HLog是什么:HLog是實現WAL的類,一個RegionServer對應一個HLog實例
> ![image](https://note.youdao.com/yws/api/personal/file/C7E652C51E564E0A811C1F23FFBB2F0E?method=download&shareKey=416cc5492bf4a2243d657a2c6999b735)
HLogKey
WAL使用Hadoop的序列化文件將記錄存儲為Key-Value的數據集,Key就是HLog的Key
> ![image](https://note.youdao.com/yws/api/personal/file/3F4EADB35EB74A66B9CBD736C7989B07?method=download&shareKey=416cc5492bf4a2243d657a2c6999b735)
HLogSyncer
是日志同步刷寫類
> ![image](https://note.youdao.com/yws/api/personal/file/A9A568573E9042C3BFE4F33042F7DB2B?method=download&shareKey=416cc5492bf4a2243d657a2c6999b735)
HLogRoller
特點的時間去滾動日志,形成新的日志,避免單個日志文件過大
根據HLog的序列化的number對比已經持久化的HFile的序列號,刪除舊的,不需要的日志
> ![image](https://note.youdao.com/yws/api/personal/file/F1AB5E58BBAE435FA5F35957EE3276C3?method=download&shareKey=416cc5492bf4a2243d657a2c6999b735)
HBase Compaction解析
什么是Compaction
Compaction會從一個Region的Store中選擇一些HFile文件進行合并
為什么要Compaction
隨著系統不停的刷寫,會導致存儲目錄中有過多的數據文件
Compaction分類
MinorCompaction:小合并
MajorCompaction:大合并
> ![image](https://note.youdao.com/yws/api/personal/file/053CA3350B764F60B0A2DB01D841FAEA?method=download&shareKey=416cc5492bf4a2243d657a2c6999b735)
Compaction觸發時機
MemStore 內存數據寫入到硬盤上
> ![image](https://note.youdao.com/yws/api/personal/file/C9D3EA024E1848178E3879F80C1536A0?method=download&shareKey=416cc5492bf4a2243d657a2c6999b735)4-3 存取解析
HBase數據存儲流程解析
HBase Client
請求Zookeeper,確定 MetaTable所在RegionServer的地址
在根據RowKey找到歸屬的RegionServer
HBase Client Put(Delete)數據,提交到RegionServer
> ![image](https://note.youdao.com/yws/api/personal/file/FCE4E73CC9774EFEA2C0A060C142CD61?method=download&shareKey=416cc5492bf4a2243d657a2c6999b735)
HBase Server
Region Server 去獲取行鎖,Region更新共享鎖
寫HLog,WAL
寫緩存,MemStore
將日志同步到HDFS
寫滿緩存后,啟動異步線程將數據寫入到硬盤上
可能觸發Compaction或拆分
> ![image](https://note.youdao.com/yws/api/personal/file/C6724DFE164448E694FF61FE657CE68F?method=download&shareKey=416cc5492bf4a2243d657a2c6999b735)
HBase數據獲取流程解析
HBase Client
請求Zookeeper,確定 MetaTable所在RegionServer的地址
去對應的RegionServer地址拿到對應數據
> ![image](https://note.youdao.com/yws/api/personal/file/31D60278867C4C27BDCA35AEBD57436E?method=download&shareKey=416cc5492bf4a2243d657a2c6999b735)
HBase Server
Region Server 構建RegionScanner準備進行檢索
有多少個列簇就構建多少個StoreScanner,用于對確定的列簇數據檢索
> ![image](https://note.youdao.com/yws/api/personal/file/8840F5554C354B39A14D00E2B39CBF5C?method=download&shareKey=416cc5492bf4a2243d657a2c6999b735)4-4 數據存取
HBase數據存取api介紹
新增api void put(Put put)throws IOException Put構造方法 Put(byte[] row) Put(byte[] row,long ts) 填充值 Put add(byte[] family,byte[] qualifier,byte[] value) Put add(byte[] family,byte[] qualifier,long timestamp,byte[] value) Put add(KeyValue kv)throws IOException 原子檢查寫 boolean checkAndPut(add(byte[] row,byte[] family,byte[] qualifier,byte[] value,put)) 刪除api void delete(Delete delete)throws IOException 構造方法 Delete(byte[] row) 填充值 Delete deleteFamily(byte[] family) Delete deleteColumns(byte[] family,byte[] qualifier) Delete deleteColumns(byte[] family,byte[] qualifier,long timestamp) 原子檢查刪除 boolean checkAndDelete(byte[] row,byte[] family,byte[] qualifier,byte[] value,Delete delete)throws IOException 獲取api Result get(Get get)throws IOException 構造方法 Get(byte[] row) 填充值 Get addFamily(byte[] family) Get addColumn(byte[] family,byte[] qualifier) Get setTimeRange(long minStamp,long maxStamp)throws IOException Get setTimeStamp(long timestamp) Get setMaxVersions() Get setMaxVersions(int maxVersions)throws IOException第五章:案例演示 5-1 案列演示
創建名為hbase-demo的maven工程pom如下
4.0.0 com.myimooc hbase-demo 1.0-SNAPSHOT org.springframework.boot spring-boot-starter-parent 2.0.1.RELEASE UTF-8 UTF-8 1.8 org.springframework.boot spring-boot-starter org.yaml snakeyaml 1.10 org.springframework.boot spring-boot-configuration-processor true jdk.tools jdk.tools 1.7 system ${JAVA_HOME}/lib/tools.jar com.spring4all spring-boot-starter-hbase 1.0.0.RELEASE com.alibaba fastjson 1.2.45 org.springframework.boot spring-boot-starter-test test
1.編寫User類
package com.myimooc.hbase.demo.dto; /** *
* 標題: 用戶表
* 描述: 用戶表
* * @author zc * @date 2018/06/21 */ public class User { /** * 行鍵 */ private String row; /** * 基礎信息 */ private BaseInfo baseInfo; /** * 其他信息 */ private OtherInfo otherInfo; public User() { } public User(String row, BaseInfo baseInfo, OtherInfo otherInfo) { this.row = row; this.baseInfo = baseInfo; this.otherInfo = otherInfo; } @Override public String toString() { return "User{" + "row="" + row + """ + ", baseInfo=" + baseInfo + ", otherInfo=" + otherInfo + "}"; } public String getRow() { return row; } public void setRow(String row) { this.row = row; } public BaseInfo getBaseInfo() { return baseInfo; } public void setBaseInfo(BaseInfo baseInfo) { this.baseInfo = baseInfo; } public OtherInfo getOtherInfo() { return otherInfo; } public void setOtherInfo(OtherInfo otherInfo) { this.otherInfo = otherInfo; } /** * 使用內部類表示 b 列簇 基礎信息 */ public static class BaseInfo { /** * 名稱 */ private String name; /** * 年齡 */ private Integer age; /** * 性別 */ private String sex; public BaseInfo() { } public BaseInfo(String name, Integer age, String sex) { this.name = name; this.age = age; this.sex = sex; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Integer getAge() { return age; } public void setAge(Integer age) { this.age = age; } public String getSex() { return sex; } public void setSex(String sex) { this.sex = sex; } } /** * 使用內部類表示 o 列簇 其他信息 */ public static class OtherInfo { /** * 電話 */ private String phone; /** * 地址 */ private String address; public OtherInfo() { } public OtherInfo(String phone, String address) { this.phone = phone; this.address = address; } @Override public String toString() { return "OtherInfo{" + "phone="" + phone + """ + ", address="" + address + """ + "}"; } public String getPhone() { return phone; } public void setPhone(String phone) { this.phone = phone; } public String getAddress() { return address; } public void setAddress(String address) { this.address = address; } } }
2.編寫UserRowMapper類
package com.myimooc.hbase.demo.mapper; import com.myimooc.hbase.demo.dto.User; import com.spring4all.spring.boot.starter.hbase.api.RowMapper; import org.apache.hadoop.hbase.client.Result; import org.apache.hadoop.hbase.util.Bytes; /** *
* 標題: 用戶表ORM
* 描述: 用戶表ORM
* * @author zc * @date 2018/06/21 */ public class UserRowMapper implements RowMapper{ private static byte[] FAMILY_B = "b".getBytes(); private static byte[] FAMILY_B_NAME = "name".getBytes(); private static byte[] FAMILY_B_AGE = "age".getBytes(); private static byte[] FAMILY_B_SEX = "sex".getBytes(); private static byte[] FAMILY_O = "o".getBytes(); private static byte[] FAMILY_O_PHONE = "phone".getBytes(); private static byte[] FAMILY_ADDRESS = "address".getBytes(); @Override public User mapRow(Result result, int i) throws Exception { User.BaseInfo baseInfo = new User.BaseInfo( Bytes.toString(result.getValue(FAMILY_B, FAMILY_B_NAME)), Bytes.toInt(result.getValue(FAMILY_B, FAMILY_B_AGE)), Bytes.toString(result.getValue(FAMILY_B, FAMILY_B_SEX))); User.OtherInfo otherInfo = new User.OtherInfo( Bytes.toString(result.getValue(FAMILY_O, FAMILY_O_PHONE)), Bytes.toString(result.getValue(FAMILY_O, FAMILY_ADDRESS))); return new User(Bytes.toString(result.getRow()),baseInfo,otherInfo); } }
3.編寫HbaseService類
package com.myimooc.hbase.demo.service; import org.apache.hadoop.hbase.client.Mutation; import java.util.List; /** *
* 標題: HBase服務
* 描述: HBase服務
* * @author zc * @date 2018/06/21 */ public interface HbaseService{ /** * 查詢指定行鍵的表數據 * @param tableName 表名 * @param row 行鍵 * @return 數據 */ T findByRow(String tableName,String row); /** * 查詢指定行鍵之間的表數據 * @param tableName 表名 * @param startRow 開始行鍵 * @param endRow 結束行鍵 * @return 數據集合 */ List findByStartEndRow(String tableName,String startRow,String endRow); /** * 保存或修改數據 * @param tableName 表名 * @param datas 數據集合 * @return 數據集合 */ List saveOrUpdate(String tableName,List datas); }
4.編寫UserHbaseServiceImpl類
package com.myimooc.hbase.demo.service.impl; import com.myimooc.hbase.demo.dto.User; import com.myimooc.hbase.demo.mapper.UserRowMapper; import com.myimooc.hbase.demo.service.HbaseService; import com.spring4all.spring.boot.starter.hbase.api.HbaseTemplate; import org.apache.hadoop.hbase.client.Mutation; import org.apache.hadoop.hbase.client.Scan; import org.apache.hadoop.hbase.util.Bytes; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import java.util.List; /** *
* 標題: 用戶服務
* 描述: 用戶服務
* * @author zc * @date 2018/06/22 */ @Service public class UserHbaseServiceImpl implements HbaseService{ @Autowired private HbaseTemplate hbaseTemplate; @Override public User findByRow(String tableName, String row) { return hbaseTemplate.get(tableName, row, new UserRowMapper()); } @Override public List findByStartEndRow(String tableName, String startRow, String endRow) { Scan scan = new Scan(Bytes.toBytes(startRow), Bytes.toBytes(endRow)); return hbaseTemplate.find(tableName, scan, new UserRowMapper()); } @Override public List saveOrUpdate(String tableName, List datas) { hbaseTemplate.saveOrUpdates(tableName, datas); return datas; } }
5.編寫application.properties
# Zookeeper 地址 spring.data.hbase.quorum=192.168.0.104:2181 # HBase 存儲路徑 spring.data.hbase.rootDir=hdfs://zccoder.com:9000/hbase/ # HBase 在 Zookeeper上的根節點名稱 spring.data.hbase.nodeParent=/hbase
6.編寫Application類
package com.myimooc.hbase.demo; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication public class Application { public static void main(String[] args) { SpringApplication.run(Application.class,args); } }
7.編寫UserHbaseServiceImplTest類
package com.myimooc.hbase.demo.service; import com.alibaba.fastjson.JSON; import com.myimooc.hbase.demo.Application; import com.myimooc.hbase.demo.dto.User; import org.apache.hadoop.hbase.client.Delete; import org.apache.hadoop.hbase.client.Mutation; import org.apache.hadoop.hbase.client.Put; import org.apache.hadoop.hbase.util.Bytes; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.context.junit4.SpringRunner; import java.util.ArrayList; import java.util.List; /** *
* 標題: 單元測試類
* 描述: 單元測試類
* * @author zc * @date 2018/06/22 */ @RunWith(SpringRunner.class) @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.NONE,classes = Application.class) public class UserHbaseServiceImplTest { @Autowired private HbaseServiceservice; /** * 數據表名稱 */ private String tableName; @Before public void init(){ tableName = "demo:user"; } @Test public void testFindByRow(){ System.out.println(JSON.toJSONString(service.findByRow(tableName,"root"))); } @Test public void testFindByStartEndRow(){ System.out.println(JSON.toJSONString(service.findByStartEndRow(tableName,"r","z"))); } @Test public void testSaveOrUpdate(){ List datas = new ArrayList<>(); Put put= new Put(Bytes.toBytes("root")); put.addColumn(Bytes.toBytes("b"),Bytes.toBytes("name"),Bytes.toBytes("imooc")); put.addColumn(Bytes.toBytes("b"),Bytes.toBytes("age"),Bytes.toBytes("18")); put.addColumn(Bytes.toBytes("b"),Bytes.toBytes("sex"),Bytes.toBytes("m")); put.addColumn(Bytes.toBytes("o"),Bytes.toBytes("phone"),Bytes.toBytes("123456789")); put.addColumn(Bytes.toBytes("o"),Bytes.toBytes("address"),Bytes.toBytes("北京市朝陽區")); datas.add(put); // Delete delete = new Delete(Bytes.toBytes("root")); // datas.add(delete); List results = service.saveOrUpdate(tableName,datas); System.out.println(results); } }
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/71392.html
摘要:時間年月日星期二說明本文部分內容均來自慕課網。返回對象不同返回持久化實體類對象返回代理對象。與緩存的關系不同只緩存,但不使用緩存查詢緩存除外會使用緩存。 時間:2017年07月11日星期二說明:本文部分內容均來自慕課網。@慕課網:http://www.imooc.com教學源碼:無學習源碼:無 第一章:概述 1-1 概述 課程內容 了解緩存 掌握Hibernate一級緩存的使用 掌握H...
摘要:攔截器學習總結時間年月日星期六說明本文部分內容均來自慕課網。慕課網教學示例源碼暫無。攔截器不依賴與容器,過濾器依賴與容器。攔截器只能對請求起作用,而過濾器則可以對幾乎所有的請求起作用。共性問題在攔截器中處理,可以減少重復代碼,便于維護。 《SpringMVC攔截器》學習總結 時間:2017年2月18日星期六說明:本文部分內容均來自慕課網。@慕課網:http://www.imooc.co...
摘要:時間年月日星期日說明本文部分內容均來自慕課網。當對應的鏈表存在時,從左側插入數據。從右側插入數據。當系統在定時持久化之前出現宕機,還未來得及往硬盤寫入數據,那數據就丟失了。當數據集過大時,可能會導致服務器停止幾百毫秒甚至是秒鐘。 時間:2017年05月21日星期日說明:本文部分內容均來自慕課網。@慕課網:http://www.imooc.com教學示例源碼:無個人學習源碼:https:...
閱讀 1000·2021-11-22 13:52
閱讀 1441·2021-11-19 09:40
閱讀 3122·2021-11-16 11:44
閱讀 1263·2021-11-15 11:39
閱讀 3893·2021-10-08 10:04
閱讀 5333·2021-09-22 14:57
閱讀 3096·2021-09-10 10:50
閱讀 3177·2021-08-17 10:13