Hbase入门知识点入门学习二

一:Hbase读写流程

  1. 读流程
          ⑴client访问Zookeeper中,找到ROOT表的Region所在的RegionServer信息;
          ⑵client连接RegionServer访问ROOT表查询.meta表的region位置信息
          ⑶再去连接.meta表的region所在的regionserver然后访问meta表,找到目标数据在哪个region上
              及region所在的regionserver位置信息
          ⑷然后去访问目标数据所在的regionserver中的region,先在memstore中查询数据,memstore中不存在则在
              BlockCache中读数据,
              BlockCache中还是不存在的话就最后在storefile中读数据,并且将读取到的数据先写入到BlockCache中,然后再返回给客户端
         
  2. 写流程         
         ⑴Client访问Zookeeper集群,查询ROOT表region所在的regionserver地址信息,比如rs1
         ⑵client连接rs1,访问ROOT表,根据写入信息查询.meta表的region位于哪些regionserver上,将得到的结果返回给client;
         ⑶client去连接相应的rs,访问.meta表,根据写入的namespace、表名和rowkey找到对应的region信息   
         ⑷client连接最终的rs,为了持久化和恢复,将数据先写到Hlog(write ahead log)中;
         ⑸再将数据写入到memstore中,当memstore达到预设阈值后,就会创建一个新的memstore,而老的memstore就会加入flush队
            列,由单独的线程flush到磁盘上,形成一个storefile;
         ⑹与此同时,系统会在Zookeeper记录一个checkpoint,表示这个时刻之前的数据变更已经持久化了,当系统出现意外可能导致
              memstore中的数据丢失,就可以通过hlog来恢复checkpoint之后的数据;
         ⑺每次flush就会形成一个storefile文件,而storefile文件是只读的,一旦创建之后就不可修改,因此hbase的更新就是不断追加的            操作;
         ⑻随着storefile的数量不断增多,当达到设定阈值后就会触发compact合并操作,将多个storefile合并成一个大的storefile,同时进           行版本合并和数据删除;
         ⑼当store中的单个storefile文件的大小超过阈值的时候,触发split操作,regionserver把当前的region split成2个新的region
         ⑽父region就会下线,新split出的2个region就会被hmaster分配到两个regionserver上,实现负载均衡,使得原先一个region的压
              力分流到两个region上。
  3.  

二:Hbase中.meta简介

  1.  简介
           当我们在对HBase的读写操作时,都需要提前知道我们需要操作的region的所在位置,即是存在于哪个HRegionServer上,
     因此在HBase中存在一张表元数据表.meta表(属于Hbase的内置表)专门存储了表的元数据信息,以及region位于哪个
     regionserver上。.meta表的结构类似于下图:
     
     .meta表的RowKey由三部分组成:TableName(表名)、StartKey(起始键)、TimeStamp(时间戳),rowkey存储的内容又称为
     region的Name(扩展:用来存放Region的文件夹的名字为RegionName的hash值,因为某些RegionName包含某些非法字符,而
    RegionName为什么会包含非法字符是因为startkey是允许包含任何值的)。将组成rowkey的三个部分用逗号隔开组成了整个完整的
    rowkey。TimeStamp使用十进制的数字字符串来表示。
    .meta表的info为表中最主要的列簇,含有三个column:regioninfo、server、serverstartcode。regioninfo存储的是region的详细信
     息,包括startkey、endkey、以及每个family信息。server存储的是管理这个region的regionserver地址。
    由于.meta存储的是region的信息,如果当hbase中表的数据非常大会被分成很多个region,那么此时在.meta中所占的空间也会变大,而.meta本身也是一张表,在存储数据非常大的情况下,也会被分割成多个region存储于不同的regionserver上,此时要是想把.meta表的region位置信息存储在zookeeper集群中就不太现实,.meta表region的位置信息是会发生变化的。因此,此时我们可以通过另外一张表来存储.meta表的元数据信息,即-ROOT-(根数据表),hbase认为这张表不会太大,因此-ROOT-只会有一个region,这个region的信息存在于hbase中,而管理-ROOT-表的位置信息(regionserver地址)存储在Zookeeper中。
    所以综上所述要想对HBase进行读写首先去访问Zookeeper集群,获得ROOT表的所在regionserver地址信息。          

三:JAVA api操作Hbase

  1. 在maven项目中添加依赖
     
     配置文件:
     
  2. HbaseDemo.java类     
     ⑴判断表是否存在
           
     ⑵创建表
           
          
     
     ⑶删除表
           
     ⑷添加一行数据
           
     
     ⑸删除一行数据
          
     ⑹删除多行数据
           
     ⑺扫描数据
            
            
     ⑻获取一个列簇的数据
            

 

四:MapReduce 

  1.  简介
           通过 HBase 的相关 JavaAPI,我们可以实现伴随 HBase 操作的 MapReduce 过程,比如使用
    MapReduce 将数据从本地文件系统导入到 HBase 的表中,比如我们从 HBase 中读取一些原始数
    据后使用 MapReduce 做数据分析。 
     
  2.  查看 HBase 的 MapReduce 任务所需的依赖
     
  3. 执行环境变量的导入 
     
  4. 运行官方的 MapReduce 任务 ,统计 Student 表中有多少行数据 
     
      
  5.  让环境变量永久生效,修改/etc/profile配置文件
     

五: 案例一:使用 MapReduce 将本地数据导入到 HBase 

  1. 在本地创建一个 tsv 格式的文件:fruit.tsv 
     
     
  2.   在 HDFS 中创建 input_fruit 文件夹并上传 fruit.tsv 文件 
     
     
  3. 创建 HBase 的fruit表
     
  4. 执行 MapReduce 到 HBase 的 fruit 表中 
      
     
  5.   进入hbase,查看fruit表
       

六:自定义 HBase-MapReduce1 

  1. 需求
     目标:将 fruit 表中的一部分数据,通过 MR 迁入到 fruit_mr 表中。 
  2.  创建MAVEN项目
     
     
  3. 创建ReadFruitMapper.java类
     
    package com.kgf.mr1;
    
    import java.io.IOException;
    
    import org.apache.hadoop.hbase.Cell;
    import org.apache.hadoop.hbase.CellUtil;
    import org.apache.hadoop.hbase.client.Put;
    import org.apache.hadoop.hbase.client.Result;
    import org.apache.hadoop.hbase.io.ImmutableBytesWritable;
    import org.apache.hadoop.hbase.mapreduce.TableMapper;
    import org.apache.hadoop.hbase.util.Bytes;
    import org.apache.hadoop.mapreduce.Mapper;
    
    /***
     * 创建mapper类,读数据
     * ImmutableBytesWritable:可以看做是rowkey,代表一行数据
     * Put:这里面封装了一条一条数据
     * @author KGF
     *
     */
    public class ReadFruitMapper extends TableMapper<ImmutableBytesWritable,Put> {
    	
    	/***
    	 * map方法处理数据
    	 */
    	@Override
    	protected void map(ImmutableBytesWritable key, Result value,
    			Mapper<ImmutableBytesWritable, Result, ImmutableBytesWritable, Put>.Context context)
    			throws IOException, InterruptedException {
    		//读取数据,使用Put封装数据
    		Put put = new Put(key.get());
    		//遍历column
    		for (Cell cell : value.rawCells()) {
    			//筛选,我们只需要info列簇的数据
    			if("info".equals(Bytes.toString(CellUtil.cloneFamily(cell)))) {
    				//我们只要列名为name的数据
    				if("name".equals(Bytes.toString(CellUtil.cloneQualifier(cell)))) {
    					//将数据添加到put中
    					put.add(cell);
    				}
    			}
    		}
    		//将数据写出
    		context.write(key, put);
    	}
    	
    }
    

     

  4.  创建WriteFruitMRReducer.java类
     
    package com.kgf.mr1;
    
    import java.io.IOException;
    
    import org.apache.hadoop.hbase.client.Mutation;
    import org.apache.hadoop.hbase.client.Put;
    import org.apache.hadoop.hbase.io.ImmutableBytesWritable;
    import org.apache.hadoop.hbase.mapreduce.TableReducer;
    import org.apache.hadoop.io.NullWritable;
    import org.apache.hadoop.mapreduce.Reducer;
    
    /***
     * 创建reducer类
     * @author KGF
     *
     */
    public class WriteFruitMRReducer extends TableReducer<ImmutableBytesWritable, Put,NullWritable>{
    
    	@Override
    	protected void reduce(ImmutableBytesWritable key, Iterable<Put> values,
    			Reducer<ImmutableBytesWritable, Put, NullWritable, Mutation>.Context context)
    			throws IOException, InterruptedException {
    		for (Put put : values) {
    			context.write(NullWritable.get(),put);
    		}
    	}
    }
    

     

  5.  创建Fruit2FruitMRRunner.java类
     
    package com.kgf.mr1;
    
    import org.apache.hadoop.conf.Configuration;
    import org.apache.hadoop.hbase.HBaseConfiguration;
    import org.apache.hadoop.hbase.client.Put;
    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.mapreduce.Job;
    import org.apache.hadoop.util.Tool;
    import org.apache.hadoop.util.ToolRunner;
    
    /***
     * 创建Runner
     * @author KGF
     *
     */
    public class Fruit2FruitMRRunner implements Tool {
    
    	private Configuration conf;
    	
    	public void setConf(Configuration conf) {
    		//创建hbase的conf
    		this.conf = HBaseConfiguration.create();
    	}
    
    	public Configuration getConf() {
    		return this.conf;
    	}
    
    	public int run(String[] args) throws Exception {
    		//创建Job
    		Job job = Job.getInstance();
    		//设置入口jar
    		job.setJarByClass(Fruit2FruitMRRunner.class);
    		//配置job
    		Scan scan = new Scan();
    		//设置mapper
    		TableMapReduceUtil.initTableMapperJob("fruit", 
    				scan, 
    				ReadFruitMapper.class,ImmutableBytesWritable.class, 
    				Put.class, job);
    		//设置reducer
    		TableMapReduceUtil.initTableReducerJob("fruit_mr",WriteFruitMRReducer.class, job);
    		job.setNumReduceTasks(1);
    		boolean result = job.waitForCompletion(true);
    		return result?0:1;
    	}
    	
    	public static void main(String[] args) {
    		try {
    			int status = ToolRunner.run(new Fruit2FruitMRRunner(), args);
    			System.out.println(status);
    		} catch (Exception e) {
    			e.printStackTrace();
    		}
    	}
    	
    }
    

     

  6.  打成jar包,上传Linux
     
  7.   在Hbase上创建fruit_mr表
     
  8.   执行jar包
     
     
  9.  效果,数据成功导入
     

七:自定义 HBase-MapReduce2 

  1. 需求:实现将 HDFS 中的数据(fruit.tsv)写入到 HBase 表中(先将fruit表数据清空)。 
  2. 创建ReadFruitFromHDFSMapper.java类
     
    package com.kgf.mr2;
    
    import java.io.IOException;
    
    import org.apache.hadoop.hbase.client.Put;
    import org.apache.hadoop.hbase.io.ImmutableBytesWritable;
    import org.apache.hadoop.hbase.util.Bytes;
    import org.apache.hadoop.io.LongWritable;
    import org.apache.hadoop.io.Text;
    import org.apache.hadoop.mapreduce.Mapper;
    
    /**
     * 创建mapper类,因为我们是从HDFS上读取数据,所以我们继承的是普通的mapper,
     * 我们读取数据向HBASE中写所以使用ImmutableBytesWritable,Put写出,
     * 读取HDFS上的fruit.tsv中的数据
     * @author KGF
     *
     */
    public class ReadFruitFromHDFSMapper extends Mapper<LongWritable, Text, ImmutableBytesWritable,Put> {
    
    	@Override
    	protected void map(LongWritable key, Text value,
    			Mapper<LongWritable, Text, ImmutableBytesWritable, Put>.Context context)
    			throws IOException, InterruptedException {
    		//读取一行数据
    		String[] split = value.toString().split("\t");
    		byte[] rowkey = Bytes.toBytes(split[0]);
    		byte[] name = Bytes.toBytes(split[1]);
    		byte[] color = Bytes.toBytes(split[2]);
    		//创建Put对象
    		Put put = new Put(rowkey);
    		//为指定的列族,列添加数据
    		put.addColumn(Bytes.toBytes("info"), Bytes.toBytes("name"), name);
    		put.addColumn(Bytes.toBytes("info"), Bytes.toBytes("color"),color);
    		
    		//写出
    		context.write(new ImmutableBytesWritable(rowkey),put);
    	}
    	
    }
    

     

  3.  创建Writer2HbaseReducer.java类
     
    package com.kgf.mr2;
    
    import java.io.IOException;
    
    import org.apache.hadoop.hbase.client.Mutation;
    import org.apache.hadoop.hbase.client.Put;
    import org.apache.hadoop.hbase.io.ImmutableBytesWritable;
    import org.apache.hadoop.hbase.mapreduce.TableReducer;
    import org.apache.hadoop.io.NullWritable;
    import org.apache.hadoop.mapreduce.Reducer;
    
    public class Writer2HbaseReducer extends TableReducer<ImmutableBytesWritable, Put,NullWritable>{
    
    	@Override
    	protected void reduce(ImmutableBytesWritable key, Iterable<Put> values,
    			Reducer<ImmutableBytesWritable, Put, NullWritable, Mutation>.Context context)
    			throws IOException, InterruptedException {
    		for (Put put : values) {
    			context.write(NullWritable.get(),put);
    		}
    	}
    	
    }
    

     

  4. 创建HDFS2HbaseRunner.java
     
    package com.kgf.mr2;
    
    import org.apache.hadoop.conf.Configuration;
    import org.apache.hadoop.fs.Path;
    import org.apache.hadoop.hbase.HBaseConfiguration;
    import org.apache.hadoop.hbase.client.Put;
    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.mapreduce.Job;
    import org.apache.hadoop.mapreduce.lib.input.FileInputFormat;
    import org.apache.hadoop.util.Tool;
    import org.apache.hadoop.util.ToolRunner;
    
    import com.kgf.mr1.Fruit2FruitMRRunner;
    
    public class HDFS2HbaseRunner implements Tool {
    
    	private Configuration conf;
    	
    	public void setConf(Configuration conf) {
    		//创建hbase的conf
    		this.conf = HBaseConfiguration.create();
    	}
    
    	public Configuration getConf() {
    		return this.conf;
    	}
    
    	public int run(String[] args) throws Exception {
    		//创建Job
    		Job job = Job.getInstance();
    		//设置入口jar
    		job.setJarByClass(HDFS2HbaseRunner.class);
    		//设置mapper
    		job.setMapperClass(ReadFruitFromHDFSMapper.class);
    		job.setMapOutputKeyClass(ImmutableBytesWritable.class);
    		job.setMapOutputValueClass(Put.class);
    		
    		//设置reducer,OutPutFormat
    		TableMapReduceUtil.initTableReducerJob("fruit",Writer2HbaseReducer.class, job);
    		
    		//设置FileInputFormat
    		FileInputFormat.addInputPath(job, new Path("/input_fruit/"));
    		job.setNumReduceTasks(1);
    		boolean result = job.waitForCompletion(true);
    		return result?0:1;
    	}
    	
    	public static void main(String[] args) {
    		try {
    			int status = ToolRunner.run(new Fruit2FruitMRRunner(), args);
    			System.out.println(status);
    		} catch (Exception e) {
    			e.printStackTrace();
    		}
    	}
    }
    

     

  5. 打成jar包,上传Linux
     
  6. 进入/usr/local/module/hadoop-2.7.2目录下执行jar包
     
     
  7. 查看fruit表信息
            
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值