当前位置:首页 > 数据库 > 正文内容

HBase基础知识共享(一)

邻居的猫1个月前 (12-09)数据库516

写在前面

今日来学习Hbase部分的常识!

Zookeeper的ZAB协议

ZAB(Zookeeper Atomic Broadcast)协议是Zookeeper的中心协议之一,用于保证集群中数据的一致性、次序性和容错性。它包含以下几个要害阶段:

  • Leader推举:推举出一个Leader节点来和谐集群内的操作。
  • 业务提案:客户端提交的业务会被提案并传播到集群中。
  • 投票与提交:集群中的一切节点投票承认业务,然后提交。

ZAB协议的规划创意来自于Paxos协议,但简化了许多过程,使其愈加合适Zookeeper这种首要用作和谐服务的分布式体系。

ZAB协议的特色

  • 保证数据一致性。
  • 经过Leader节点保证次序性。
  • 容错性强,能应对节点毛病或网络分区。
  • 为分布式体系供给强一致性,保证高可用性和稳定性。

HBase的特色

  1. 大规模:支撑百万等级的列和行,合适存储海量数据。
  2. 面向列族:数据存储按列族进行分组,供给灵敏的存储和权限操控。
  3. 稀少:只对有数据的列分配存储空间,节约存储。
  4. 无方式(No Schema):每行能够有不同的列,不强制列的界说。
  5. 数据多版别:支撑多版别数据,每个单元格有多个版别,能够依据时刻戳查询不同版别。
  6. 数据单一类型:一切数据都以字节数组存储,无类型区别。

HBase的三维有序结构

HBase的数据按 行键、列族和时刻戳 三个维度进行排序:

  1. 行键(Row Key):数据按行键的字典次序排序,行键是HBase存储的根本粒度。
  2. 列族(Column Family):数据按列族进行分组,同一个列族内的数据按列名排序。
  3. 时刻戳(Timestamp):同一个单元格内的数据能够有多个版别,按时刻戳的次序排序,支撑多版别数据。

这个规划使得HBase在处理大数据时具有高效的查询、存储和写入才能。


怎么定位到 HBase 的 Cell

  1. 行键(Row Key):HBase中的数据按行键次序存储,因而要查询某个 Cell,需求知道它的行键。经过查询行键,能够定位到包含该行数据的 RegionServer

  2. 列族(Column Family)和列名(Column Qualifier):一旦确认了方针行,下一步是确认方针列。HBase按列族存储数据,每个列族包含多个列,查询时需求指定列族和列名。

  3. 时刻戳(Timestamp):HBase中的每个单元格按时刻戳版别排序。每次写入时,HBase会主动为每个单元格分配一个时刻戳。假如没有显式指定时刻戳,默许运用当时时刻戳。

经过 行键、列族、列名和时刻戳,能够精确地查询到一个 Cell


什么是 Region?经过 RK 定位到 Region

  • Region 是HBase存储数据的最小单元,担任存储一个接连规模的行数据。
  • Region 依据行键规模区分,HBase会依据行键主动将数据区分到不同的 Region
  • 经过 行键(Row Key),HBase能够定位到某个 Region。每个 Region 都有一个行键规模,当查询时,HBase会依据行键判别它所属的Region。
  • HBase经过 ZookeeperMaster节点 来办理Region和RegionServer的分配。查询时,客户端经过行键查询Zookeeper或Master,取得对应的Region和RegionServer信息。

HBase的数据模型

  1. RowKey:用于仅有标识一行数据,是HBase查询数据的主键。

    • 支撑经过单个RowKey、RowKey规模或正则表达式等方法查询。
    • RowKey按字典次序存储,最大长度64KB,一般运用中为10~100字节。
  2. 列簇(Column Family)

    • 列簇是表的结构部分,表创立时有必要指定至少一个列簇。
    • 列簇内的数据按列名排序。
    • HBase中的数据存储、权限操控和版别操控都是按列簇进行的。
  3. 时刻戳

    • 每条数据都会记载时刻戳,支撑多版别数据存储。
    • 按时刻戳倒序存储,获取数据时默许回来最新版别。
    • 设置TTL(Time to Live)时,HBase会依据时刻戳主动删去过期数据。
  4. Cell

    • RowKeyColumn(列簇+列名)Version(时刻戳) 仅有标识。
    • HBase中的数据都以字节数组方式存储。

HBase的架构及读写流程

HBase的架构首要包含以下组件:

  • Client:提交读写恳求。
  • HMaster:担任办理Region和RegionServer的分配。
  • RegionServer:担任存储和处理Region数据。
  • Zookeeper:和谐HBase集群中的节点,保护元数据。

HBase读写流程:

  • 写入流程:客户端恳求写入数据,HBase首先将数据写入 MemStore,然后异步刷写到HFile中。当数据到达阈值时,会触发Region的割裂。
  • 读取流程:客户端恳求读取数据,HBase依据行键定位到对应的RegionServer,并从MemStore或HFile中读取数据。
    HBase架构及读写流程

常用的HBase比较器与过滤器

比较器(Comparator)

  1. BinaryComparator:按字节索引次序比较字节数组。
  2. BinaryPrefixComparator:比较字节数组的前缀是否匹配。
  3. RegexStringComparator:运用正则表达式比较字符串。
  4. SubstringComparator:判别一个子串是否存在于方针字符串中。
  • HBase有哪些常用的过滤器?

单列值过滤器:SingleColumnValueFilter
SingleColumnValueFilter会回来满意条件的cell所内行的一切cell的值(即会回来一行数据)
经过SingleColumnValueFilter与查询文科班一切学生信息

    @Test
    // 经过SingleColumnValueFilter与查询文科班一切学生信息
    public void RegexStringComparatorFilter() throws IOException {
        Table students = conn.getTable(TableName.valueOf("students"));
        SingleColumnValueFilter singleColumnValueFilter = new SingleColumnValueFilter(
                "info".getBytes(),
                "clazz".getBytes(),
                CompareFilter.CompareOp.EQUAL,
                new RegexStringComparator("^文科.*")
        );

        Scan scan = new Scan();
        scan.setFilter(singleColumnValueFilter);
        ResultScanner scanner = students.getScanner(scan);

        Result rs = scanner.next();
        while (rs != null) {
            String id = Bytes.toString(rs.getRow());
            String name = Bytes.toString(rs.getValue("info".getBytes(), "name".getBytes()));
            int age = Bytes.toInt(rs.getValue("info".getBytes(), "age".getBytes()));
            String gender = Bytes.toString(rs.getValue("info".getBytes(), "gender".getBytes()));
            String clazz = Bytes.toString(rs.getValue("info".getBytes(), "clazz".getBytes()));

            System.out.println(id + "\t" + name + "\t" + age + "\t" + gender + "\t" + clazz + "\t");

            rs = scanner.next();
        }

    }

列值扫除过滤器:SingleColumnValueExcludeFilter
与SingleColumnValueFilter相反,会扫除去指定的列,其他的列悉数回来
经过SingleColumnValueExcludeFilter与BinaryComparator查询文科一班一切学生信息,终究不回来clazz列

    @Test
    // 经过SingleColumnValueExcludeFilter与BinaryComparator查询文科一班一切学生信息,终究不回来clazz列
    public void RegexStringComparatorExcludeFilter() throws IOException {
        Table students = conn.getTable(TableName.valueOf("students"));
        SingleColumnValueExcludeFilter singleColumnValueExcludeFilter = new SingleColumnValueExcludeFilter(
                "info".getBytes(),
                "clazz".getBytes(),
                CompareFilter.CompareOp.EQUAL,
                new BinaryComparator("文科一班".getBytes())
        );

        Scan scan = new Scan();
        scan.setFilter(singleColumnValueExcludeFilter);
        ResultScanner scanner = students.getScanner(scan);

        Result rs = scanner.next();
        while (rs != null) {
            String id = Bytes.toString(rs.getRow());
            String name = Bytes.toString(rs.getValue("info".getBytes(), "name".getBytes()));
            int age = Bytes.toInt(rs.getValue("info".getBytes(), "age".getBytes()));
            String gender = Bytes.toString(rs.getValue("info".getBytes(), "gender".getBytes()));
            // clazz列为空
            String clazz = Bytes.toString(rs.getValue("info".getBytes(), "clazz".getBytes()));

            System.out.println(id + "\t" + name + "\t" + age + "\t" + gender + "\t" + clazz + "\t");

            rs = scanner.next();
        }

    }

rowkey前缀过滤器:PrefixFilter
经过PrefixFilter查询以150010008最初的一切前缀的rowkey

    @Test
    // 经过PrefixFilter查询以150010008最初的一切前缀的rowkey
    public void PrefixFilterFilter() throws IOException {
        Table students = conn.getTable(TableName.valueOf("students"));
        PrefixFilter prefixFilter = new PrefixFilter("150010008".getBytes());
        Scan scan = new Scan();
        scan.setFilter(prefixFilter);
        ResultScanner scanner = students.getScanner(scan);
        Result rs = scanner.next();
        while (rs != null) {
            String id = Bytes.toString(rs.getRow());
            String name = Bytes.toString(rs.getValue("info".getBytes(), "name".getBytes()));
            int age = Bytes.toInt(rs.getValue("info".getBytes(), "age".getBytes()));
            String gender = Bytes.toString(rs.getValue("info".getBytes(), "gender".getBytes()));
            // clazz列为空
            String clazz = Bytes.toString(rs.getValue("info".getBytes(), "clazz".getBytes()));

            System.out.println(id + "\t" + name + "\t" + age + "\t" + gender + "\t" + clazz + "\t");

            rs = scanner.next();
        }
    }

分页过滤器PageFilter

经过PageFilter查询第三页的数据,每页10条
运用PageFilter分页功率比较低,每次都需求扫描前面的数据,直到扫描到所需求查的数据
可规划一个合理的rowkey来完成分页需求

    @Test
    // 经过PageFilter查询第三页的数据,每页10条
    public void PageFilter() throws IOException {
        Table students = conn.getTable(TableName.valueOf("students"));
        int PageNum = 3;
        int PageSize = 10;
        Scan scan = new Scan();
        if (PageNum == 1) {
            scan.withStartRow("".getBytes());
            //运用分页过滤器,完成数据的分页
            PageFilter pageFilter = new PageFilter(PageSize);
            scan.setFilter(pageFilter);
            ResultScanner scanner = students.getScanner(scan);
            printRS(scanner);
        } else {
            String current_page_start_rows = "";
            int scanDatas = (PageNum - 1) * PageSize + 1;
            PageFilter pageFilter = new PageFilter(scanDatas);
            scan.setFilter(pageFilter);
            ResultScanner scanner = students.getScanner(scan);
            for (Result rs : scanner) {
                current_page_start_rows = Bytes.toString(rs.getRow());
            }
            scan.withStartRow(current_page_start_rows.getBytes());
            PageFilter pageFilter1 = new PageFilter(PageSize);
            scan.setFilter(pageFilter1);
            ResultScanner scanner1 = students.getScanner(scan);
            printRS(scanner1);

        }

    }

经过合理的设置rowkey来完成分页功用

    @Test
    // 经过合理的设置rowkey来完成分页功用,进步功率
    public void PageFilterTest2() throws IOException {
        Table students = conn.getTable(TableName.valueOf("students"));
        int PageSize = 10;
        int PageNum = 3;

        int baseId = 1500100000;
        int start_row = baseId + (PageNum - 1) * PageSize + 1;
        int end_row = start_row + PageSize;
        Scan scan = new Scan();
        scan.withStartRow(String.valueOf(start_row).getBytes());
        scan.withStopRow(String.valueOf(end_row).getBytes());

        ResultScanner scanner = students.getScanner(scan);

        printRS(scanner);


    }

多过滤器归纳查询

查询文科班中的学生中学号以150010008最初而且年纪小于23的学生信息

    @Test
    // 查询文科班中的学生中学号以150010008最初而且年纪小于23的学生信息
    public void FilterListFilter() throws IOException {
        Table students = conn.getTable(TableName.valueOf("students"));
        Scan scan = new Scan();
        SingleColumnValueFilter singleColumnValueFilter = new SingleColumnValueFilter(
                "info".getBytes()
                , "clazz".getBytes()
                , CompareFilter.CompareOp.EQUAL
                , new RegexStringComparator("^文科.*"));
        PrefixFilter prefixFilter = new PrefixFilter("150010008".getBytes());
        SingleColumnValueFilter singleColumnValueFilter1 = new SingleColumnValueFilter(
                "info".getBytes()
                , "age".getBytes()
                , CompareFilter.CompareOp.LESS
                , new BinaryComparator(Bytes.toBytes(23)));

        FilterList filterList = new FilterList();
        filterList.addFilter(singleColumnValueFilter);
        filterList.addFilter(prefixFilter);
        filterList.addFilter(singleColumnValueFilter1);
        scan.setFilter(filterList);
        ResultScanner scanner = students.getScanner(scan);
        printRS(scanner);

    }

今日的共享就到这了,之后会持续共享hbase相关的内容。

扫描二维码推送至手机访问。

版权声明:本文由51Blog发布,如需转载请注明出处。

本文链接:https://www.51blog.vip/?id=578

标签: hbase
分享给朋友:

“HBase基础知识共享(一)” 的相关文章

Redis【2】- SDS源码剖析

Redis【2】- SDS源码剖析

1 简介&根底用法 Redis 中用得最多的便是字符串,在 C 言语中其实能够直接运用 char* 字符数组来完成字符串,也有许多能够直接运用得函数。可是 Redis 并没有运用 C 言语原生的字符串,而是自己完成了一个 SDS(简略动态字符串,Simple Dynamic String)...

Sql高档

Sql高档

1. sql高档 1.1. 索引与视图 1.1.1. 常见的数据结构 1.1.2. 索引 1.1.2.1. 效果 1.1.2.2. 界说 1.1.2.3. 分类 1.1.2.4. 规划准则 1.1.2.5. 语法 1.1.3. 视图 1.2. 业务与锁 1.2.1. 业务的原理 1.2.2. 业...

陕西大数据集团董事长,引领数据新时代,助力陕西经济腾飞

陕西大数据集团董事长,引领数据新时代,助力陕西经济腾飞

张喜平,男,现任陕西省大数据集团有限公司党委书记、董事长。他曾任陕西省工业和信息化厅副巡视员,并于2018年10月被任命为陕西省大数据集团有限公司董事长。张喜平在任职期间,带领公司积极推动陕西省大数据产业的发展,致力于盘活政府数据,带动社会数据,引导产业发展陕西大数据集团:引领数据新时代,助力陕西经...

mysql数据库增删改查,mysql数据库增删改查基本语句

mysql数据库增删改查,mysql数据库增删改查基本语句

MySQL 是一种关系型数据库管理系统,它使用 SQL(结构化查询语言)进行数据管理。以下是关于如何在 MySQL 中进行增删改查(CRUD)操作的基本指南: 1. 增(Create)创建数据库:```sqlCREATE DATABASE 数据库名;```创建表:```sqlCREATE TABLE...

mysql增加索引,提升数据库查询效率的关键策略

mysql增加索引,提升数据库查询效率的关键策略

MySQL中增加索引可以通过以下几种方式来实现:1. 使用`CREATE INDEX`语句创建索引。2. 使用`ALTER TABLE`语句添加索引。3. 在创建表时,使用`PRIMARY KEY`或`UNIQUE`约束创建索引。4. 使用`EXPLAIN`语句来分析查询并确定是否需要添加索引。以下...

手机数据库软件,高效数据管理的移动解决方案

手机数据库软件,高效数据管理的移动解决方案

1. MySQL Viewer 平台:安卓 特点:这款软件是一个优秀的安卓Mysql客户端,支持Mysql和MariaDB。它实用、美观,功能齐全,操作简单,适合进行远程管理。2. DBeaver 平台:安卓 特点:DBeaver社区版支持多种数据库平台,包括SQLite、P...