大数据系列——Hbase学习笔记

栏目: 数据库 · 发布时间: 5年前

内容简介:​ 耗时约20分钟自己测试10分钟8800000ms,插入15851742tiao数据

1. Hbase简介

  • Hadoop-Database 根据' bigtable '论文实现的
  • 分布式 可扩展 的大数据存储技术
  • 随机访问 实时读写 海量数据
  • 存储数 ' 十亿行 百万列 '的数据
  • 高可靠性、高性能、面向列、可伸缩分布式 存储系统
  • hbase的底层存储基于 hdfs
  • 利用 Zookeeper 作为协调工具

2. Hbase是什么?

  • 分布式开源数据库,基于hadoop分布式文件系统(HDFS)
  • 模仿提供了Google文件系统的BigTable数据库所有功能
  • 处理非常庞大的表

    • 数十亿行 百万列
    • 利用mapreduce计算数据,利用zookeeper协调资源
  • HBase是一款 NoSQL

3. 行存储和列存储

  • 行存储:mysql oracle底层基于行存储数据的

    • 查询数据需要全表扫描,效率较低
    • 对数据压缩支持不太好
  • 列存储:hbase底层基于列存储数据的

    • 查询数据不需做全表扫描
    • 支持较好的数据压缩

4. Hbase的特点

  • 可以分布式存储海量的数据
  • 具有容错能力强,数据高可靠的特点
  • HBase是一个列式NoSQL数据库
  • 数据存储的结构是按照列进行存储

5. Hbase的安装部署

==安装hbase高可用集群之前首先要保证zookeeper和hadoop已经安装完成==

  • 准备安装包

    hbase-1.1.5-bin.tar.gz

  • 集群的规划

    • uplooking01: master
    • uplooking02: master
    • uplooking03: regionserver
    • uplooking04: regionserver
    • uplooking05: regionserver
  • 解压安装包

    [root@uplooking01: /soft]:
            tar -zxvf hbase-1.1.5-bin.tar.gz  -C /opt/
  • 重命名

    [root@uplooking01: /opt]:
            mv hbase-1.1.5/ hbase
  • 配置环境变量

    [root@uplooking01: /opt]:
        #配置HBASE的环境变量
        export HBASE_HOME=/opt/hbase
        export PATH=$PATH:$HBASE_HOME/bin
  • 配置vim hbase-env.sh

    [root@uplooking01: /opt/hbase/conf]:
        vim  hbase-env.sh
    export JAVA_HOME=/opt/jdk
    export HBASE_MANAGES_ZK=false   #不使用hbase自带的zookeeper
    export HBASE_CLASSPATH=/opt/hadoop/etc/hadoop
  • 配置hbase-site.xml

    [root@uplooking01: /opt/hbase/conf]:
        vim  hbase-site.xml
    <configuration>
        <property>
        <name>hbase.rootdir</name>
        <value>hdfs://ns1/hbase</value>
        </property>
    
        <property>
        <name>hbase.tmp.dir</name>
        <value>/opt/hbase/tmp</value>
        </property>
    
        <property>
        <name>hbase.cluster.distributed</name>
        <value>true</value>
        </property>
    
        <property>
        <name>hbase.zookeeper.quorum</name>
        <value>uplooking03:2181,uplooking04:2181,uplooking05:2181</value>
        </property>
    </configuration>
  • 配置regionservers

    [root@uplooking01: /opt/hbase/conf]:
        vim  regionservers
    uplooking03
    uplooking04
    uplooking05
  • 分发文件

    [root@uplooking01: /opt]:
        scp -r hbase uplooking02:/opt
        scp -r hbase uplooking03:/opt
        scp -r hbase uplooking04:/opt
        scp -r hbase uplooking05:/opt
        
        scp /etc/profile uplooking02:/etc/
        scp /etc/profile uplooking03:/etc/
        scp /etc/profile uplooking04:/etc/
        scp /etc/profile uplooking05:/etc/
    source /etc/profile(所有节点都做,要使环境变量生效)
  • 启动hbase集群

    start-hbase.sh
  • 单独启动master

    [root@uplooking02:/]
        hbase-daemon.sh start master
  • 注意事项

    ==启动hbase集群一定要保证整个集群的时间一致==

  • ==附加(一般不会有这种情况)==

    如果启动集群执行start-hbase.sh,master节点可以启动,但是regionserver节点不能启动, 但是单独启动regionserver(hbase-daemon.sh start regionserver)是可以启动的 ,也没有问题,name就需要拷贝一个jar包,

    将HADOOP_HOME/share/hadoop/common/lib下的htrace-core-3.0.4.jar  复制到$HBASE_HOME/lib下

6. Hbase的体系结构(模型)

6.1 逻辑结构(模型)

  • 表(table)

    • 划分数据集合的概念,和传统的db中的表的概念是一样的
  • 行键(rowKey)

    • 对应关系数据库中的主键,作用就是 唯一标示一行记录
    • 获取hbase中的一个记录(数据),要通过 行键 来获取
    • 行键是 字节数组, 任何字符串 都可以作为行键
    • 表中的行根据行键(row key)进行 排序 ,数据按照Row key的 字节序 (byte order)排序存储
  • 列簇(列族)columnFamily

    • 简单的认为是一系列 “列”的集合
  • 列限定符(column Qualifier)

    • 或者叫
    • 每个列簇都可以有多个列
  • 时间戳(version)

    • 在单元格中可以存放 多个版本 的数据
  • 单元格(cell)

    • 主要用来 存储数据
    • 单元格的定位要通过 三级定位 才能定位到具体的单元格
  • 三级定位

    • 行键+(列族:列)+时间戳

6.2 物理结构(模型)

  • Zookeeper

    • 分布式协调
  • Master

    • HMaster没有单点问题,HBase中可以启动多个HMaster
    • 负责Table和Region的管理工作
    • 管理用户对Table的增、删、改、查操作
    • RegionServer的负载均衡
    • 调整Region分布 ,在Region Split后,负责新Region的分配
    • 在HRegionServer停机后,负责失效HRegionServer上的Regions迁移
  • RegionServer

    • RegionServer主要负责响应用户I/O请求
    • 向HDFS文件系统中读写数据,是HBase中最核心的模块
    • HLog部分和多个Region部分
  • Hlog

    • HLog保存着用户操作hbase的日志
    • == 实现了Write Ahead Log (WAL)预写日志 ==
    • Hlog会删除已存储到StoreFile中的数据
  • Region

    • 区域
    • 保存了row-key的固定区域范围的数据
    • 一个Hregion对应一个Region
    • 一个Hregion对应多个Hstore
  • Hstore

    • 对应一个列簇(列族)
    • 一个Hstore包含一个MemStore(内存储) 和多个StoreFile
  • MemStore

    • 内存储
    • 内存中的一块区域,一个Hstore对应一个MemStore
    • 当MemStore中的内容存放不下了就会刷出到硬盘以一个个的StoreFile存储
  • StoreFile

    • 其实就是数据的存储位置
    • 对HFile的封装 * *
  • Hfile

    • Hadoop File
    • Hdfs的一个文件对象

7. Hbase读写数据的流程

  • zookeeper(寻找元数据信息)

    • get /hbase/meta-region-server
  • 找到提供元数据信息访问的regionserver
  • 找"hbase:meta"表,再去查找要请求哪个regionser来读写数据

8. Hbase的 Shell 操作

  • 列出所有的命名空间(相当于 mysql 中的show databases)

    • list_namespace
  • 列出指定命名空间下的所有表

    • list_namespace_tables 'ns1'
  • 创建命名空间

    • create_namespace 'ns1'
  • 创建表

    • create 'ns1:t1','f1'
  • 禁用表,因为删除表之前首先需要禁用了

    • disable 'ns1:t1'
  • 启用表

    • enable 'ns1:t1'
  • 删除表

    • drop 'ns1:t1'
  • 添加数据

    • put 'ns1:t1','row001','f1:name','xiaohua'
  • 查询数据

    • get 'ns1:t1','row001',{COLUMN=>'f1:name'}
  • 删除数据

    • delete 'ns1:t1','row001','f1:name'
  • 删除一行数据

    • deleteall 'ns1:t1','row001'
  • 统计表的行数

    • count 'ns1:t1'

9. Hbase中的版本数据

  • 创建Hbase表时指定列族的显示版本数

    • create 'ns1:t1',{NAME=>'f1',VERSIONS=>3}
  • 修改Hbase表中的列族的显示版本数

    • alter 'ns1:t1',{NAME=>'f1',VERSIONS=>5}
  • 查询指定版本数的数据

    • get 'ns1:t1',{COLUMN=>'f1:name',VERSIONS=>3}
  • ==版本号的作用==

    根据显示的版本数,查询出来想要版本的时间戳,根据时间戳找出具体值

10. Hbase中API的基本操作

<properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <hbase-version>1.1.5</hbase-version>
</properties>
<dependencies>
    <dependency>
        <groupId>org.apache.hbase</groupId>
        <artifactId>hbase-client</artifactId>
        <version>${hbase-version}</version>
    </dependency>
    <dependency>
        <groupId>org.apache.hbase</groupId>
        <artifactId>hbase-server</artifactId>
        <version>${hbase-version}</version>
    </dependency>
    <dependency>
        <groupId>org.apache.hive</groupId>
        <artifactId>hive-hbase-handler</artifactId>
        <version>2.1.0</version>
    </dependency>

    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>4.12</version>
    </dependency>
</dependencies>
public class HbaseTest {
    //添加数据
    @Test
    public void testPut() throws IOException {
        Configuration conf = HBaseConfiguration.create();
        //指定zk的地址
        conf.set("hbase.zookeeper.quorum", "uplooking03:2181,uplooking04:2181,uplooking05:2181");
        Connection conn = ConnectionFactory.createConnection(conf);
        Table table = conn.getTable(TableName.valueOf("ns1:t1"));
        Put put = new Put(Bytes.toBytes("row001"));
        put.addColumn(Bytes.toBytes("f1"), Bytes.toBytes("name"), Bytes.toBytes("admin02"));
        table.put(put);
    }


    //删除数据
    @Test
    public void testDelete() throws IOException {
        Configuration conf = HBaseConfiguration.create();
        //指定zk的地址
        conf.set("hbase.zookeeper.quorum", "uplooking03:2181,uplooking04:2181,uplooking05:2181");
        Connection conn = ConnectionFactory.createConnection(conf);
        Table table = conn.getTable(TableName.valueOf("ns1:t1"));
        Delete delete = new Delete(Bytes.toBytes("row001"));
        table.delete(delete);
    }

    //查询数据
    @Test
    public void testGet() throws IOException {
        Configuration conf = HBaseConfiguration.create();
        //指定zk的地址
        conf.set("hbase.zookeeper.quorum", "uplooking03:2181,uplooking04:2181,uplooking05:2181");
        Connection conn = ConnectionFactory.createConnection(conf);
        Table table = conn.getTable(TableName.valueOf("ns1:t1"));
        Get get = new Get(Bytes.toBytes("row001"));
        Result result = table.get(get);
        String s = Bytes.toString(result.getValue(Bytes.toBytes("f1"),Bytes.toBytes("name")));
        System.out.println(s);
    }
}

11. Hbase中的API的管理操作

public class HbaseAdminTest {

    private Connection connection;

    @Before
    public void init() throws Exception {
        Configuration conf = new Configuration();
        conf.set("hbase.zookeeper.quorum", "uplooking03:2181,uplooking04:2181,uplooking05:2181");
        connection = ConnectionFactory.createConnection(conf);
    }

    /**
     * 创建表
     *
     * @throws Exception
     */
    @Test
    public void testCreateTable() throws Exception {
        //获取管理对象
        Admin admin = connection.getAdmin();
        HTableDescriptor htd = new HTableDescriptor(TableName.valueOf("t2"));
        HColumnDescriptor hcd = new HColumnDescriptor(Bytes.toBytes("f1"));
        htd.addFamily(hcd);
        admin.createTable(htd);
    }


    /**
     * 列出所有的表
     * @throws Exception
     */
    @Test
    public void testListTableNames() throws Exception {
        //获取管理对象
        Admin admin = connection.getAdmin();
        TableName[] tableNames = admin.listTableNames("ns1:.*");
        for (TableName tableName : tableNames) {
            System.out.println(tableName);
        }
    }

}

12. Hbase高级查询

//查询数据
@Test
public void testScan() throws IOException {
    Configuration conf = HBaseConfiguration.create();
    //指定zk的地址
    conf.set("hbase.zookeeper.quorum", "uplooking03:2181,uplooking04:2181,uplooking05:2181");
    Connection conn = ConnectionFactory.createConnection(conf);
    Table table = conn.getTable(TableName.valueOf("ns1:t1"));
    Scan scan = new Scan();
    byte[] cf = Bytes.toBytes("f1");
    byte[] column = Bytes.toBytes("name");
    Filter filter = new SingleColumnValueFilter(cf, column, CompareFilter.CompareOp.EQUAL, Bytes.toBytes("admin123"));
    scan.setFilter(filter);
    //获取包含多行数据的对象
    ResultScanner resultScanner = table.getScanner(scan);
    for (Result result : resultScanner) {
        System.out.println(Bytes.toString(result.getValue(Bytes.toBytes("f1"), Bytes.toBytes("age"))));
    }
}

13. 百万数据的插入

13.1 mysql百万数据写入

​ 耗时约20分钟

自己测试10分钟

8800000ms,插入15851742tiao数据

13.2 hbase百万数据的写入

/**
 * 百万数据的插入
 */
public class HbaseMiTest {

    private Connection connection;

    @Before
    public void init() throws Exception {
        Configuration conf = new Configuration();
        conf.set("hbase.zookeeper.quorum", "uplooking03:2181,uplooking04:2181,uplooking05:2181");
        connection = ConnectionFactory.createConnection(conf);
    }

    @Test
    public void test01() throws IOException {
        HTable table = (HTable) connection.getTable(TableName.valueOf("ns1:t1"));
        //不使用每个put操作都刷出一次
        table.setAutoFlush(false);
        long startTime = System.currentTimeMillis();
        for (int i = 0; i < 1000000; i++) {
            Put put = new Put(Bytes.toBytes("row" + i));
            //关闭预写日志,但是不建议使用,因为这样做不安全
            put.setWriteToWAL(false);
            put.addColumn(Bytes.toBytes("f1"), Bytes.toBytes("name"), Bytes.toBytes("admin" + i));
            table.put(put);
            if (i % 100000 == 0) {
                table.flushCommits();
            }
        }
        table.flushCommits();
        long endTime = System.currentTimeMillis();
        System.out.println("总耗时:" + (endTime - startTime) + "ms");
    }
}

大约耗时27s

自己测试,1分20秒 590/80=7.4倍

查询一行是9秒

97602ms,插入15851742tiao数据 8800/175=50倍

14. Hbase中的手动切分region

split 'ns1:t1','row040'

15. Hbase手动移动region

move 'f6e6164514db53d660c5414df1f3864e','uplooking05,1602

**0,1539222350164'**

16. Hbase中row-key的设计

  • 行健的热点问题

​ 是由于行健相似、连续且数据量过大操作成单region的数据量过大,进而影响读写效率

​ 行健应该尽量的随机、不要出现连续行健。

​ 常见的行健设计就是,比如手机号码倒置+时间戳,比如随机前缀+关系型数据库中的主键

​ 因为hbase提供的查询内容非常非常low,但是所有关于hbase的查询只能通过rowkey,所以

​ 在设计行健的时候,应该考虑将尽量多的查询条件放到rowkey中去,形成的行健就成为复合键

列族的设计:

​ cf1----->"columnFamily"

​ cf2----->"cf"

​ 建议hbase表是高表,不建议宽表,因为宽表拥有的列族很多,操作并跨越的文件(HFile)就很多,效率会有相应影响,

​ 反之建议使用高表,列族不宜过多(列族一般使用一个)。

​ 在设计表的时候,各个列/列族名称不宜过长,因为hbase需要对这些数据在内存中做缓存,做索引,进而影响内存容量,所以建议不易过长,以便能够在内存中容纳更多的数据。至于阅读性,有项目文档搞定。

17. Hbase中客户端工具

HbaseExplorer


以上所述就是小编给大家介绍的《大数据系列——Hbase学习笔记》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

JavaScript设计模式

JavaScript设计模式

Ross Harmes、Dustin Diaz / 谢廷晟 / 人民邮电出版社 / 2008 / 45.00元

本书共有两部分。第一部分给出了实现具体设计模式所需要的面向对象特性的基础知识,主要包括接口、封装和信息隐藏、继承、单体模式等内容。第二部分则专注于各种具体的设计模式及其在JavaScript语言中的应用,主要介绍了工厂模式、桥接模式、组合模式、门面模式等几种常见的模式。为了让每一章中的示例都尽可能地贴近实际应用,书中同时列举了一些JavaScript 程序员最常见的任务,然后运用设计模式使其解决方......一起来看看 《JavaScript设计模式》 这本书的介绍吧!

JS 压缩/解压工具
JS 压缩/解压工具

在线压缩/解压 JS 代码

html转js在线工具
html转js在线工具

html转js在线工具

HEX HSV 转换工具
HEX HSV 转换工具

HEX HSV 互换工具