Hbase学习总结

- Hbase定义

  1. 它基于Hadoop之上的、分布式的、面向列的开源数据库
  2. 它就是用来存储数据查询,查询数据。
  3. 海量数据的存储,海量数据的查询

- Hbase体系架构图

这里写图片描述

  1. Client:
    1. 整个集群的入口
    2. 与Master通信进行表的管理
    3. 通过Zookeeper找到对应的RegionServer进行表的数据的操作
    4. 维护Cache
  2. Zookeeper:
    1. 所有的RegionServer都需要注册到Zookeeper里,提供RegionServer的状态信息,是否存活,实时推送给Master
    2. 存储HBase的schema,table元数据
    3. 保证HBase集群里只有一个Master节点
    4. 存储所有RegionServer的寻址入口
  3. Master:
    1. 管理表
    2. 对RegionServer的负载均衡
    3. 调整Region的分布
    4. RegionServer宕机以后对改RegionServer上的Region数据进行迁徙
  4. RegionServer:
    1. 它是管理Region的。Hbase里的数据是分区域的,每个区与叫做一个Region。

- Hbase表结构

  1. colmunfamily(列簇):拥有一个名称,包含一个或者多个列
  2. column(列):术语某一个列簇,包含在某一列中
  3. tableNam(表名):表的名称
  4. rowkey(唯一标识):每条数据里的唯一标识,如关系型数据库里的主键
  5. cell(数据单元):rowkey + columnfamily + column01 + timestamp:value
  6. vsersion number(版本号):默认是时间戳,long类型

- Hbase的安装(Hadoop是CDH的,所以我们可以去CDH上下载对应的Hbase的CDH版本)

  1. 下载:http://archive.cloudera.com/cdh5/cdh/5/hbase-1.2.0-cdh5.7.0.tar.gz
  2. 上传到Linux服务器上
  3. 解压
  4. 启动Hadoop的NameNode,DataNode
  5. 配置hbase.env.sh环境变量
    export JAVA_HOME=/usr/java/jdk1.8.0_131
    export HBASE_MANAGES_ZK=true #如果想用Hbase自带的Zookeeper可以不用配置这个属性,默认值为true,false为不使用自带的zookeeper

  6. 配置hbase-site.xml

     <property>
        <name>hbase.rootdir</name>
        <value>hdfs://hadoop001:8020/hbase</value> 
      </property>
      <property>
        <name>hbase.cluster.distributed</name>
        <value>true</value>
      </property>
      <property>
        <name>hbase.zookeeper.quorum</name>
        <value>hadoop001</value>
      </property>
  7. 配置RegionServer为hadoop001

  8. 启动Habse,在$HBASE_HOME/bin下运行

    ./start-hbase.sh 

- Hbase的Shell使用

  1. 进入hbase的命令行,在$HBASE_HOME/bin下运行:habse shell
  2. 找到所有的shell操作,进入命令行以后运行:hbase -help
  #对表的管理与操作的shell明令,具体语法的使用为在shell命令行运行 help '具体的指令'
  Group name: ddl  
  Commands: 
          alter     #修改表的
          alter_async     #异步更新,与alter的作用相同。
          alter_status     #状态
          create     #创建表
          describe     #查看表的描述
          disable     #使表无效,删除一个表之前,必须把表disable 
          disable_all     #使所有表无效,删除一个表之前,必须把表disable 
          drop     #删除表,删除一个表之前,必须把表disable 
          drop_all     #删除所有的表,删除一个表之前,必须把表disable 
          enable     #使表有效,删除一个表之前,必须把表disable 
          enable_all     #使所有表有效,删除一个表之前,必须把表disable 
          exists     #查看表是否存在
          get_table     #查看一个表
          is_disabled     #查看一个表是否是无效的
          is_enabled     #查看一个表是否是有效的
          list     #查看所有的表
          locate_region     #
          show_filters     #


  #对命名空间的管理与操作的shell明令     #具体语法的使用为在shell命令行运行 help '具体的指令'
  Group name: namespace
  Commands: 
          alter_namespace :修改命名空间的关键字
          create_namespace :创建一个命名空间
          describe_namespace     #查看命名空间的描述
          drop_namespace     #删除一个命名空间
          list_namespace #查看所有的命名空间
          list_namespace_tables  #查看命名空间里的所有表

  #对表的数据管理与操作的shell明令,具体语法的使用为在shell命令行运行 help '具体的指令'
  Group name: dml
  Commands: 
          append   #追加值
          count     #统计表有多少行数据
          delete     #删除数据
          deleteall     #一次性删除多个cell数据 
          get     #得到某一列或cell的数据。 
          get_counter     #
          get_splits     #
          incr     #
          put     #插入数据
          scan     #扫描数据
          truncate_preserve:

  #tool命令提供了一些工具命令,组名称为Tools,这些命令多用于HBase集群的管理与调优。这些命令涵盖合并、分裂、负载均衡、日志回滚、Region分配和移动以及zookeeper信息查看等方面,具体语法的使用为在shell命令行运行 help '具体的指令'
  Group name: tool
            assign     #分配Region
            balance_switch     #启用或关闭负载均衡器,返回结果是当前均衡器状态
            balancer     #触发集群负载均衡器。如果成果运行则返回TRUE,很可能将所有Region重新分配。
如果FALSE,说明某些Region在rit状态,不会执行该命令
            balancer_enabled     #
            catalogjanitor_enabled     #
            catalogjanitor_run     #
            catalogjanitor_switch     #
            close_region     #关闭某个Region
            compact     #合并表或者Region
            compact_mob     #
            compact_rs     #
            flush     #flush表或Region
            major_compact     #大合并表或Region
            major_compact_mob     #
            merge_region     #
            move     #移动Region。如果没有目标regionserver,则随机选择一个节点
            normalize     #
            normalizer_enabled     #
            normalizer_switch     #
            split     #分裂表或Region
            trace     #
            unassign     #解除某个指定的Region
            wal_roll     #zk_dump

   #对数据复制的一下管理命令,具体语法的使用为在shell命令行运行 help '具体的指令'
  Group name: replication
  Commands: 
          add_peer     #为两个集群添加复制管理
          append_peer_tableCFs #为两个集群添加复制管理
          disable_peer     #禁用复制关系
          disable_table_replication     #关闭表的复制关系
          enable_peer     #启用复制关系
          enable_table_replication     #启用表的复制关系
          list_peers     #显示当前集群的复制关系
          list_replicated_tables     #显示一个hbase集群下处于复制状态的表
          remove_peer     #禁用并删除复制关系
          remove_peer_tableCFs     #禁用并删除peer下的表、列族复制关系
          set_peer_tableCFs     #设置peer下的表、列族复制关系
          show_peer_tableCFs    #显示peer下表、列族复制关系

  #HBase Snapshots允许你对一个表进行快照(即可用副本),它不会对Region Servers产生很大的影响,它进行复制和 恢复操作的时候不包括数据拷贝。导出快照到另外的集群也不会对Region Servers产生影响
  Group name: snapshots
  Commands: 
          clone_snapshot     #克隆一个快照
          delete_all_snapshot     #删除所有快照
          delete_snapshot     #删除一个快照
          list_snapshots     #查看所有快照
          restore_snapshot     #恢复快照
          snapshot

  Group name: configuration
  Commands: 
          update_all_config     #更新所有配置
          update_config     #更新单个配置

  #HBase中限流是通过Quota语句来操作的,限流的方式有两种,一种是针对用户进行限流;另一种是针对表来进行限流
  Group name: quotas
  Commands:  
          list_quotas     #
          set_quota     #

  ##表权限管理,安全管理 ,包括授权,收回,查看权限等等
  Group name: security
  Commands:  
          grant     #
          list_security_capabilities     #
          revoke     #
          user_permission

  Group name: procedures
  Commands:  
          abort_procedure     #
          list_procedures:

  Group name: visibility labels
  Commands:  
          add_labels     #
          clear_auths     #
          get_auths     #
          list_labels     #
          set_auths     #
          set_visibility

- Hbase的物理模型

这里写图片描述
这里写图片描述
这里写图片描述

  1. Table中的所有行都按照RowKey的字典排序
  2. Table在行的方向上进行分割,分割成的每个区域为Region,Region是按照大小进行分割的,每个表一开始只有一个Region,随着Region的数据越来越大达到一定的阈值,那么Region就会被拆分两个Region。
  3. Region是Hbase中分布式存储和负载均衡中的最小单元,不同的Region分布在RegionServer上。
  4. Region由一个或者多个Store组成,每个Store只保存一个Columns family,每个Store由两部分组成,第一个是一个MemStore,存储在内存中,第二个是多个StoreFile,存储在HDFS上。

- Hbase数据的写入流程:

  1. 首先先写入日志文件(Hlog)里,防止写入数据的时候机器宕机造成数据的丢失。
  2. 第二步写入内存中(MemStore
  3. 写入HDFS

- Hbase检索数据的三种方式:

  1. get rowkey 最快的
  2. scan range 用的最多的
  3. scan 权标扫描,基本很少用

- Hbase架构图

  1. 存储过程模型
    这里写图片描述

  2. 根据架构图解析Hbase对数据的读写流程,以下为写入数据的流程:

    1. client ---> zookeeper:当我们连接Zookeeper的时候,会读取Zookeeper下的Hbase目录下的RegionServer地址,根据RegionServer找到Region,根据Region我们会找到Meta表,Meta表里存的就是用户表的RegionServer,然后我们会根据RegionServer找到Region,然后开始扫描数据。
    2. Client ---> Hlog --->HDFS:欲写文件,防止宕机数据丢失,HLog是Hadoop上的Sequence file(序列文件,用于恢复数据),
    3. Client ---> MemStore---> HFile:存储到内存中,当达到一定阈值写到HFile中,HFile是二进制文件格式。StoreFile就是对Hfile的封装,当StoreFile的数量达到一定的阈值就会触发Compact合并操作,所有的更新与删除操作都是在Compact阶段执行的。
    4. HFile ---> HDFS:写到HDFS中

- Hbase的API使用

  1. pom.xml添加依赖(具体版本由自己Hadoop版本决定,我用的是hadoop-2.6.0-cdh5.7.0

    <!--hbase依赖-->
    <dependency>
        <groupId>org.apache.hbase</groupId>
        <artifactId>hbase-client</artifactId>
        <version>1.2.0-cdh5.7.0</version>
    </dependency>
    
    <!--hbase依赖-->
    <dependency>
        <groupId>org.apache.hbase</groupId>
        <artifactId>hbase-server</artifactId>
        <version>1.2.0-cdh5.7.0</version>
    </dependency>
    
    <!--hadoop依赖-->
    <dependency>
        <groupId>org.apache.hadoop</groupId>
        <artifactId>hadoop-client</artifactId>
        <version>2.6.0-cdh5.7.0</version>
    </dependency>
  2. 拷贝 ${HADOOP_HOME}/etc/hadoop/下的core-site.xml配置文件和hdfs-site.xml,以及${HBASE}/conf/下的hbase-site.xml配置文件到项目下resource目录中
    这里写图片描述

  3. 编写基本的操作Hbase的代码,其余的api可以对照着Shell命令进行编写。

    package hbase;
    
    import org.apache.hadoop.conf.Configuration;
    import org.apache.hadoop.hbase.Cell;
    import org.apache.hadoop.hbase.CellUtil;
    import org.apache.hadoop.hbase.HBaseConfiguration;
    import org.apache.hadoop.hbase.TableName;
    import org.apache.hadoop.hbase.client.*;
    import org.apache.hadoop.hbase.util.Bytes;
    import org.apache.hadoop.io.IOUtils;
    
    import java.io.IOException;
    import java.util.ArrayList;
    import java.util.List;
    
    /**
     * 类的注释
     *
     * @Package hbase
     * @ClassName HbaseClient
     * @Description 连接Hbase
     * @Author liyuzhi
     * @Date 2018-05-12 21:54
     */
    
    public class HbaseClient {
        public static void main(String[] args) throws IOException {
            Connection conn = getConnection();
            Table user = getTableByTableName(conn);
            get(user);
            conn.close();
        }
    
    
      //Hbase里的scan api 条件扫描
       private static void scanOther(Table user) throws IOException {
           Scan scan1 = new Scan();
           ResultScanner scanner1 = user.getScanner(scan1); // co ScanExample-2-GetScanner Get a scanner to iterate over the rows.
           for (Result res : scanner1) {
               System.out.println(res);
           }
           scanner1.close();
    
           System.out.println("Scanning table #2...");
           Scan scan2 = new Scan();
           scan2.addFamily(Bytes.toBytes("colfam1"));
           ResultScanner scanner2 = user.getScanner(scan2);
           for (Result res : scanner2) {
               System.out.println(res);
           }
           scanner2.close();
    
           System.out.println("Scanning table #3...");
           Scan scan3 = new Scan();
           scan3.addColumn(Bytes.toBytes("colfam1"), Bytes.toBytes("col-5")).
                   addColumn(Bytes.toBytes("colfam2"), Bytes.toBytes("col-33")).
                   setStartRow(Bytes.toBytes("row-10")).
                   setStopRow(Bytes.toBytes("row-20"));
           ResultScanner scanner3 = user.getScanner(scan3);
           for (Result res : scanner3) {
               System.out.println(res);
           }
           scanner3.close();
    
    
           System.out.println("Scanning table #4...");
    
           Scan scan4 = new Scan();
           scan4.addColumn(Bytes.toBytes("colfam1"), Bytes.toBytes("col-5")).
                   setStartRow(Bytes.toBytes("row-10")).
                   setStopRow(Bytes.toBytes("row-20"));
           ResultScanner scanner4 = user.getScanner(scan4);
           for (Result res : scanner4) {
               System.out.println(res);
           }
           scanner4.close();
    
    
           System.out.println("Scanning table #5...");
    
           Scan scan5 = new Scan();
    
           scan5.addColumn(Bytes.toBytes("colfam1"), Bytes.toBytes("col-5")).
                   setStartRow(Bytes.toBytes("row-20")).
                   setStopRow(Bytes.toBytes("row-10")).
                   setReversed(true);
           ResultScanner scanner5 = user.getScanner(scan5);
           for (Result res : scanner5) {
               System.out.println(res);
           }
           scanner5.close();
    
           user.close();
       }
    
       //Hbase里的scan api 全表扫描
       private static void scanAll(Table user) throws IOException {
           Scan scan = new Scan();
    
           ResultScanner scanner = user.getScanner(scan);
           for (Result result : scanner) {
               System.out.println(result.listCells());
           }
           user.close();
       }
    
       //Hbase里的delete api
       private static void delete(Table user) throws IOException {
           Delete delete = new Delete(Bytes.toBytes("10001"));
           delete.addFamily(Bytes.toBytes("info"));
           user.delete(delete);
           user.close();
       }
    
       //Hbase里的put api
       private static void put(Table user) throws IOException {
           try {
               Put put = new Put(Bytes.toBytes("10002"));
               put.addColumn(Bytes.toBytes("info"), Bytes.toBytes("name"), Bytes.toBytes("liyuzhi"));
               put.addColumn(Bytes.toBytes("info"), Bytes.toBytes("age"), Bytes.toBytes(20));
               put.addColumn(Bytes.toBytes("info"), Bytes.toBytes("addrees"), Bytes.toBytes("dashiqiao"));
               put.addColumn(Bytes.toBytes("info"), Bytes.toBytes("phone"), Bytes.toBytes(12345));
               user.put(put);
           } catch (IOException e) {
               e.printStackTrace();
           } finally {
               IOUtils.closeStream(user);
           }
    
           user.close();
       }
    
       //Hbase里的get api
       private static void get(Table user) throws IOException {
    
           Get get = new Get(Bytes.toBytes("row1"));
           get.addColumn(Bytes.toBytes("colfam1"), Bytes.toBytes("qual1"));
           Result result = user.get(get);
           byte[] val = result.getValue(Bytes.toBytes("colfam1"), Bytes.toBytes("qual1"));
           System.out.println("Value: " + Bytes.toString(val));
    
       }
    
       //Hbase里的get api
       private static void getList(Table user) throws IOException {
    
           byte[] cf1 = Bytes.toBytes("colfam1");
           byte[] qf1 = Bytes.toBytes("qual1");
           byte[] qf2 = Bytes.toBytes("qual2");
           byte[] row1 = Bytes.toBytes("row1");
           byte[] row2 = Bytes.toBytes("row2");
    
           List<Get> gets = new ArrayList<Get>();
    
           Get get1 = new Get(row1);
           get1.addColumn(cf1, qf1);
           gets.add(get1);
    
           Get get2 = new Get(row2);
           get2.addColumn(cf1, qf1);
           gets.add(get2);
    
           Get get3 = new Get(row2);
           get3.addColumn(cf1, qf2);
           gets.add(get3);
    
           Result[] results = user.get(gets);
    
           System.out.println("First iteration...");
           for (Result result : results) {
               String row = Bytes.toString(result.getRow());
               System.out.print("Row: " + row + " ");
               byte[] val = null;
               if (result.containsColumn(cf1, qf1)) {
                   val = result.getValue(cf1, qf1);
                   System.out.println("Value: " + Bytes.toString(val));
               }
               if (result.containsColumn(cf1, qf2)) {
                   val = result.getValue(cf1, qf2);
                   System.out.println("Value: " + Bytes.toString(val));
               }
           }
    
           System.out.println("Second iteration...");
           for (Result result : results) {
               for (Cell cell : result.listCells()) {
                   System.out.println(  "Row: " + Bytes.toString(cell.getRowArray(), cell.getRowOffset(), cell.getRowLength()) + // co GetListExample-7-GetValue2 Two different ways to access the cell data.
    " Value: " + Bytes.toString(CellUtil.cloneValue(cell)));
               }
           }
           for (Result result : results) {
               System.out.println(result);
           }
           user.close();
       }
       //初始化连接
       private static Connection getConnection() throws IOException {
           Configuration configuraton = HBaseConfiguration.create();
           return ConnectionFactory.createConnection(configuraton);
       }
       //设置要操作的表
       private static Table getTableByTableName(Connection conn) throws IOException {
           return conn.getTable(TableName.valueOf("user"));
       }
    
    }
    

- Hbase与MapReduce集成

  1. 编码

    package hbase.mapreduce;
    
    import org.apache.hadoop.conf.Configuration;
    import org.apache.hadoop.conf.Configured;
    import org.apache.hadoop.hbase.Cell;
    import org.apache.hadoop.hbase.CellUtil;
    import org.apache.hadoop.hbase.HBaseConfiguration;
    import org.apache.hadoop.hbase.client.Put;
    import org.apache.hadoop.hbase.client.Result;
    import org.apache.hadoop.hbase.client.Scan;
    import org.apache.hadoop.hbase.io.ImmutableBytesWritable;
    import org.apache.hadoop.hbase.mapreduce.TableMapReduceUtil;
    import org.apache.hadoop.hbase.mapreduce.TableMapper;
    import org.apache.hadoop.hbase.mapreduce.TableReducer;
    import org.apache.hadoop.hbase.util.Bytes;
    import org.apache.hadoop.io.Text;
    import org.apache.hadoop.mapreduce.Job;
    import org.apache.hadoop.util.Tool;
    import org.apache.hadoop.util.ToolRunner;
    
    import java.io.IOException;
    
    /**
     * 类的注释
     *
     * @Package hbase.mapreduce
     * @ClassName UserToSubuser
     * @Description
     * @Author liyuzhi
     * @Date 2018-05-13 19:15
     */
    
    public class UserToSubuser extends Configured implements Tool {
    
    
        public static class UserInputMapper extends TableMapper<Text, Put> {
            /**
             * 方法的注释
             *
             * @return void
             * @description 从Hbase里获取数据传给Reduce,将数据插入新的表
             * @methodName map
             * @Param: key 封装了二进制的rowkey
             * @Param: value 就是rowkey下边的所有数据
             * @Param: context
             * @author liyuzhi
             * @createTime 2018-05-13 21:10
             * @version v1.0
             */
            @Override
            protected void map(ImmutableBytesWritable key, Result value, Context context) throws IOException, InterruptedException {
    
                //得到字符串的rowkey
                String rowkey = Bytes.toString(key.get());//封装了
                //创建一个Put对象,,传给TableReducer
                Put put = new Put(key.get());
                //以下就是根据具体的业务需求进行逻辑处理
                for (Cell cell : value.listCells()) {
                    if ("info".equals(Bytes.toString(CellUtil.cloneFamily(cell)))) {
                        if ("name".equals(Bytes.toString(CellUtil.cloneQualifier(cell)))) {
                            put.add(cell);
                        }
                        if ("age".equals(Bytes.toString(CellUtil.cloneQualifier(cell)))) {
                            put.add(cell);
                        }
                    }
                }
                //写入数据
                context.write(new Text(rowkey), put);
            }
        }
    
    
        public static class UserOutputReducer extends TableReducer<Text, Put, ImmutableBytesWritable> {
    
            @Override
            protected void reduce(Text key, Iterable<Put> values, Context context) throws IOException, InterruptedException {
                for (Put put : values) {
                    context.write(null, put);
                }
            }
        }
    
    
        public int run(String[] strings) throws Exception {
            //创建job
            Job job = Job.getInstance(this.getConf(), this.getClass().getSimpleName());//创建Job
            job.setJarByClass(this.getClass());//设置运行jar的class
    
            Scan scan = new Scan();//
            scan.setCaching(100);
            scan.setCacheBlocks(false);//不需要缓存,因为这是抽取数据
    
            //初始化Map类的
            TableMapReduceUtil.initTableMapperJob("user", scan, UserInputMapper.class, Text.class, Put.class, job);
                //初始化Reduce类的
            TableMapReduceUtil.initTableReducerJob("sub_user", UserOutputReducer.class, job);
            job.setNumReduceTasks(1);
            //提交任务
            boolean states = job.waitForCompletion(true);
    
    
            return states ? 0 : 1;
        }
    
        public static void main(String[] args) throws Exception {
            Configuration conf = HBaseConfiguration.create();//获取配置文件
            int states = ToolRunner.run(conf, new UserToSubuser(), args);
            System.exit(states);
        }
    }
    
  2. 运行jar包

    HADOOP_CLASSPATH=`${HADOOP_HOME}/lib/hbase mapredcecp` haodop jar /opt/jar/example.jar

- Hbase批量迁徙数据

  1. (利用importtsv方法迁徙tsv数据,这个缺点是数据只保存在内存中,并没有保存磁盘中)

    HADOOP_CLASSPATH=`${HBASE_HOME}/bin/hbase classpath` \
    ${HADOOP_HOME}/bin/hadoop jar ${HBASE_HOME}/lib/hbase-server-1.2.0-cdh5.7.0.jar \
    importtsv  -Dimporttsv.columns=HBASE_ROW_KEY,info:name,info:age,info:address,info:phone \
    student hdfs://hadoop001:8020/opt/testfile/importtsv    
  2. (最常用的方法,而且能够大批量的迁徙数据,必会的):
    (1)先将数据变成Hfile

    HADOOP_CLASSPATH=`${HBASE_HOME}/bin/hbase classpath` ${HADOOP_HOME}/bin/hadoop jar \
    ${HBASE_HOME}/lib/hbase-server-1.2.0-cdh5.7.0.jar importtsv  -Dimporttsv.columns=HBASE_ROW_KEY,info:name,info:age,info:address,info:phone \
    -Dimporttsv.bulk.output=hdfs://hadoop001:8020/opt/testfile/hfileoutput \
    student2 hdfs://hadoop001:8020/opt/testfile/importtsv

    (2)将Hfile同步到Hbase数据库里

    HADOOP_CLASSPATH=`${HBASE_HOME}/bin/hbase classpath` ${HADOOP_HOME}/bin/hadoop jar ${HBASE_HOME}/lib/hbase-server-1.2.0-cdh5.7.0.jar \
    completebulkload hdfs://hadoop001:8020/opt/testfile/hfileoutput student2

    注意:当我们在向Hbase迁徙大量数据的时候,在创建表的时候需要创建多个Region,因为默认创建一张表值创建一个Region,那么当我们向表中插入大量数据的时候,由于只有一个Region,而Region是被RegionServer管理的,由此会增加单个服务器的内存压力,有可能宕机。所以我们在创建表的时候应该多创建Region,根据预估rowkey来创建


- Hbase表的属性

{
    NAME => 'info', #列簇
    BLOOMFILTER => 'ROW', 
    VERSIONS => '1', #版本 
    IN_MEMORY => 'false', #在写的时候缓存(占RegionServer40%的内存),达到一定大小就会flush到磁盘中,还有一中功能是缓存meta元数据 
    KEEP_DELETED_CELLS => 'FALSE', 
    DATA_BLOCK_ENCODING => 'NONE', 
    TTL => 'FOREVER',
    COMPRESSION => 'NONE',#压缩,如果需要配置压缩:1.配制hadoop压缩,2.配制Hbase压缩,将hadoop-snappy.jar方到Hbase的lib目录下,然后将
                                                        hadoop的里lib下的native软连接到Hbase下的lib目录下的native,并且名称一定要命名为
                                                        Linux-amd64-643.在hbase的habse.core-site.xml配置hbase.regionserver.codecs为snappy
                                                        重启regionserver
    MIN_VERSIONS => '0',#最小版本,
    BLOCKCACHE => 'true', #在读的时候缓存(占RegionServer40%的内存),当同步数据或者分支数据的时候一般设置为false
    BLOCKSIZE => '65536', 
    REPLICATION_SCOPE => '0'
 }

Hbase数据查询流程:用户-->MemStore-->BlockCache(每一个RegionServer一个)--->HFile-->meger-->返回给用户

- Hbase主表与索引表

  1. 索引表:功能就是辅助作用,来充当索引
  2. 主表和索引表怎么建立同步方式:
    1. phoenix,只能用JDBC的方式才能实现同步
    2. 利用solr,将重要字段建立索引存在solr中,从solr get出来,拿到rowkey,再从主表get出来,同步方式利用lily实现同步,或者用cloudera search方式实现同步。

- Hbase表的压缩

  1. 配置Hadoop压缩:https://blog.csdn.net/suubyy/article/details/80397176
  2. 配置Hbase

    1. 拷贝hadoop-snappy.jar${HBASE_HOME}/lib目录下,hadoop-snappy.jar需要自己提前编译出来
    2. 运行命令:

      ln -s ${HADOOP_HOME}/lib/native ${HBASE_HOME}/lib/native/Linux-amd64-64
    3. 在RegionServer上配置hbase.site.xml里配置压缩

      <property>
          <name>hbase.regionserver.codecs</name>
          <value>snappy</value>
      </property>

- Hbase与Hive集成(由于CDH已经帮我们集成好了,所以不需要配置与操作就可以利用hive操作hbase表)

  1. 创建管理表(Hbase不存在的表)

    
    #单列
    
    CREATE TABLE hbase_table_1(key int, value string)
    STORED BY 'org.apache.hadoop.hive.hbase.HBaseStorageHandler'
    WITH SERDEPROPERTIES ("hbase.columns.mapping" = ":key,cf1:val")
    TBLPROPERTIES ("hbase.table.name" = "xyz", "hbase.mapred.output.outputtable" = "xyz");
    
    #多列
    
    CREATE TABLE hbase_table_1(key int, value1 string, value2 int, value3 int) 
    STORED BY 'org.apache.hadoop.hive.hbase.HBaseStorageHandler'
    WITH SERDEPROPERTIES (
    "hbase.columns.mapping" = ":key,a:b,a:c,d:e"
    );
    INSERT OVERWRITE TABLE hbase_table_1 SELECT foo, bar, foo+1, foo+2 
    FROM pokes WHERE foo=98 OR foo=100;
    
    
    #(key int, value string):代表的是Hbase里表的字段,Key为rowkey,value为列簇下对应列的值
    
    
    #("hbase.columns.mapping" = ":key,cf1:val")::key为固定写法,cf1:val,就是指定具体的列簇与列,一定要与上边table里的一一对应
    
    
    #"hbase.table.name":为Hbase里表名
    
    
  2. 创建外部表(Hbase已经存在的表)

    CREATE EXTERNAL TABLE hbase_table_2(key int, value string) 
    STORED BY 'org.apache.hadoop.hive.hbase.HBaseStorageHandler'
    WITH SERDEPROPERTIES ("hbase.columns.mapping" = "cf1:val")
    TBLPROPERTIES("hbase.table.name" = "some_existing_table", "hbase.mapred.output.outputtable" = "some_existing_table");
  3. 插入数据

    INSERT OVERWRITE TABLE hbase_table_1 SELECT rowkey,value FROM pokes WHERE foo=98;
    
    #具体插入的数据的列数要与Hbase里的列数要一致
    

- Hbase完全分布式集群搭建

  1. 配置hbase.site.xml

    <property> 
        <name>hbase.rootdir</name> 
        <value>hdfs://hadoop001:8020/hbase</value> 
      </property> 
    <property> 
       <name>hbase.cluster.distributed</name> 
       <value>true</value> 
    </property> 
    <property> 
       <name>hbase.zookeeper.quorum</name> 
       <value>hadoop001,hadoop002,hadoop003</value> 
    </property> 
  2. 配置${HBASE_HOME}/conf/regionserver

    hadoop002
    hadoop003
  3. 拷贝该机器刚才配置好的Hbase目录到其他两台机器上

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值