栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java > SpringBoot

慕课网《HBase 存储原理剖析》学习总结

SpringBoot 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

慕课网《HBase 存储原理剖析》学习总结

慕课网《Hbase 存储原理剖析》学习总结
  • 时间:2018年06月11日星期一
  • 说明:本文部分内容均来自慕课网。@慕课网:https://www.imooc.com
  • 教学源码:无
  • 学习源码:https://github.com/zccodere/study-imooc
第一章:课程介绍 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
3-2 存储目录

在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
第四章:存储设计 4-1 存储思想

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是由内存数据写入到文件后形成的

  • HFile 文件
    • 是Hbase存储数据文件的最基本的组织形式
    • 底层是Hadoop的二进制格式文件
    • 是用户数据的实际载体,存储Key-Value的数据
    • Scanned block section:会被读取,主要是存储用户数据
    • Nonscanned block section:不会被读取,主要包含元数据块
    • Load-on-open section:RegionServer启动时加载,主要是HFile的元数据
    • Trailer:HFile的基本信息,HFile元数据的一部分

  • Data Block
    • Hbase中数据的最基本的存储单元
    • 是实际存储用户数据的数据结构
    • 包含很多Key-Value

Hbase WAL解析

  • 简介介绍WAL(预写日志)
    • WAL最重要的功能就是灾难恢复
    • WAL解决了什么问题:HA(高可用)问题
    • 怎么解决:远程备份

  • HLog
    • WAL是通过HLog模块实现的
    • HLog是什么:HLog是实现WAL的类,一个RegionServer对应一个HLog实例

  • HLogKey
    • WAL使用Hadoop的序列化文件将记录存储为Key-Value的数据集,Key就是HLog的Key

  • HLogSyncer
    • 是日志同步刷写类

  • HLogRoller
    • 特点的时间去滚动日志,形成新的日志,避免单个日志文件过大
    • 根据HLog的序列化的number对比已经持久化的HFile的序列号,删除旧的,不需要的日志

Hbase Compaction解析

  • 什么是Compaction
    • Compaction会从一个Region的Store中选择一些HFile文件进行合并
  • 为什么要Compaction
    • 随着系统不停的刷写,会导致存储目录中有过多的数据文件
  • Compaction分类
    • MinorCompaction:小合并
    • MajorCompaction:大合并

  • Compaction触发时机
    • MemStore 内存数据写入到硬盘上
4-3 存取解析

Hbase数据存储流程解析

  • Hbase Client
    • 请求Zookeeper,确定 metaTable所在RegionServer的地址
    • 在根据RowKey找到归属的RegionServer
    • Hbase Client Put(Delete)数据,提交到RegionServer

  • Hbase Server
    • Region Server 去获取行锁,Region更新共享锁
    • 写HLog,WAL
    • 写缓存,MemStore
    • 将日志同步到HDFS
    • 写满缓存后,启动异步线程将数据写入到硬盘上
    • 可能触发Compaction或拆分

Hbase数据获取流程解析

  • Hbase Client
    • 请求Zookeeper,确定 metaTable所在RegionServer的地址
    • 去对应的RegionServer地址拿到对应数据

  • Hbase Server
    • Region Server 构建RegionScanner准备进行检索
    • 有多少个列簇就构建多少个StoreScanner,用于对确定的列簇数据检索

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;


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;
    }

    
    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;
 }
    }

    
    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;


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;


public interface HbaseService {

    
    T findByRow(String tableName,String row);

    
    List findByStartEndRow(String tableName,String startRow,String endRow);

    
    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;


@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;


@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.NONE,classes = Application.class)
public class UserHbaseServiceImplTest {

    @Autowired
    private HbaseService service;

    
    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);
    }
}
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/235681.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号