hbase数据删除的辛酸

以下是记录公司在删除历史数据的这个过程:

背景:
     公司需要需要一套运营平台,服务器3台(hadoop),怎么安装这里就不在讲解。

删除数据的驱动:
        由于说需要做数据挖掘,不让删除数据,就一直没有删除数据,总共10T产的占用了8-9T了,服务器天天报警,大半夜起来解决问题,真心受不了发火,就算需要做数据挖掘,也不需这样做啊,可以存加工的数据啊,也不会全部把数据存在,还有公司是不允许我们加服务器的抓狂

删除数据过程:
      hbase删除数据,我也是新手,描述有问题的,希望大神给我指出。
      思路一:采用mapreduce来删除数据
      思路二:采用hbase shell来进行数据删除
      思路三:设置ttl
      不管以上哪种数据删除,最后都需要面临一个问题,那就是hbase region不释放的问题。



思路一:
     思路很简单,就是想采用mapreduce来多采用多个机器删除数据,结果是惨败,我们的有一个表数据很大,差不多3-4T,需要删除指定时间范围的数据,由于服务器的原因,内存不够,直接把服务器搞死了,后果严重啊,简单的代码如下:
package com.mapbar.analyzelog.service.mapreduce;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.hbase.KeyValue;
import org.apache.hadoop.hbase.client.Delete;
import org.apache.hadoop.hbase.client.HTable;
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.util.Bytes;
import org.apache.hadoop.io.IntWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Job;

import com.mapbar.analyzelog.service.AbstractMapReduceJob;
import com.mapbar.analyzelog.service.jdbc.DBCounterReducer;
import com.mapbar.analyzelog.service.jdbc.JDBCMapReduceUtil;
/**
 * 
 * 
 * mapreduce删除hbase数据
 */
public class DeleteMapReducer extends AbstractMapReduceJob{
	/**
	 * 
	 * 
	 * delete的map函数
	 */
	public static class DeleteMapper extends TableMapper<Text, IntWritable>{
		protected void map(ImmutableBytesWritable row, Result value, Context context) throws IOException, InterruptedException {
	    	String tableName = context.getConfiguration().get("tableName");
	    	String flag = context.getConfiguration().get("flag");
	    	if("1".equals(flag)){
		    	HTable htbl = new HTable(context.getConfiguration(), tableName);
				List<Delete> lists = new ArrayList<Delete>();
				for (KeyValue kv : value.raw()) {
					Delete dlt = new Delete(kv.getRow());
					dlt.deleteColumn(kv.getFamily(), kv.getQualifier(), kv.getTimestamp());
					lists.add(dlt);
					System.out.println("delete--tableL"+tableName+",rowkey:"+Bytes.toString(kv.getRow())+",family:"+Bytes.toString(kv.getFamily())+",qualifier:"+Bytes.toString(kv.getQualifier())+",timestamp:"+kv.getTimestamp());
				}
				htbl.delete(lists);
				htbl.flushCommits();
				htbl.close();
	    	}else{
				System.out.println("delete--tableL"+tableName+"[失败,如果需要删除数据,请设置\"flag\"]");

	    	}
		};
	}

	/**
	 * 
	 * 
	 * delete的reduce函数(此接口主要是删除,reduce没有任何作用)
	 */
	public static class DeleteReducer extends DBCounterReducer<Text, IntWritable> {
		protected void reduce( Text key, Iterable<IntWritable> values, Context context) throws IOException, InterruptedException {
		}
	};

	/**
	 * 调用的入口方法
	 */
	public void run(Job job) throws IOException, InterruptedException, ClassNotFoundException {
		//删除的hbase表名称
		String tableName = getArguments().getStrTime("-table");
		//开始时间戳
    	String timeStamp = getArguments().getStrTime("-stime");
    	//结束时间戳
    	String timeEtamp = getArguments().getStrTime("-etime");
    	//是否进行删除的标识(1:删除,0不删除)
    	String flag = getArguments().getStrTime("-flag");
    	//重新设置变量到上下文配置
    	Configuration config = job.getConfiguration();
    	config.set("tableName", tableName);
    	config.set("flag",flag);
    	//查询的条件器
    	Scan scan = new Scan();
    	scan.setCaching(500);        
    	//不使用缓存
    	scan.setCacheBlocks(false);  
        scan.setTimeRange(Long.valueOf(timeStamp), Long.valueOf(timeEtamp));
		TableMapReduceUtil.initTableMapperJob(tableName, scan, DeleteMapper.class, Text.class, IntWritable.class,job);
		JDBCMapReduceUtil.initTableReducerJob("la_event_edrive_stat_result", new String[] { "date", "clnt","label" },
				new String[] { "count" }, DeleteReducer.class, job);
		job.waitForCompletion(true);
	}
}


思路二:
     有mapreduce来进行删除删除数据,一旦任务执行了,发现服务器报警都停不下来,后来采用hbase shell,直接与数据文件打交道,我们的思路是,监控tps,当执行我的删除数据说话,监控tps,发现tps高于某个值,直接暂停进程,不浪费资源。
     大体步骤:
            1:先采用shell 脚本scan数据,将rowkey记录到文件。
            2:然后调用deleteall 删除rowkey
     感受:
           执行还不错,就是删除的太慢,删除的还没有新增的快,这样熬不住啊。就像有一座金山,想一勺子一勺子的去拿走。
           也算失败告终吧!!!

思路三:就是直接设置ttl,这个就需要disable表,需要丢数据,实在是没有办法了,然后设置了ttl
            
1:disable "table"
2:alter 'table' , {NAME=>'la',TTL=>'15768000'} 
3:enable "table"
然后日志就一直刷屏,在合并,更新。删除数据文件。
疑问:执行以上三条命令,时间差不多3分钟,就恢复了,但是后日志一直在合并,我查询了下数据,数据也正常记录,但是查询报错“region not online”,region还在合并呗。就是说影响数据就影响了几分钟,hdfs的数据在慢慢的删除,大概执行了6小时,删除了完毕,服务器恢复正常。



最严重的一个问题:
       hbase不释放region,把数据删除了,region还不释放,那在分析的时候,很消耗内存。
       思路:删除hdfs regionID、删除meta表的region指向.

删除hdfs 
#!/bin/sh
if [ $# -lt 3 ] ; then
    echo "please input 3 parameter[file_name_path、hadoop_path、input_path]"
    exit
else
    cat $1 | while read row
    do
        regionpath=`echo "$row" | awk -F '.' '{print $2}'`
        table=`echo "$row" | awk -F ',' '{print $1}'`
        #删除hdfs的region
        if [ -z $table ] ; then
           echo "table is null"
           exit;
        fi

        if [ -z $regionpath ] ; then
           echo "regionpath is null"
           exit;
        fi

        cd $2
        ./hadoop fs -rmr  /hbase/$table/$regionpath
        #删除meta表的region
        echo "deleteall '.META.','$row'">>$3
        echo "$regionpath"
    done
fi

       
删除meta
#!/bin/sh
if [ $# -lt 2 ] ; then
    echo "please input 2 parameter[hbase_path、file_path]"
    exit
else
    if [ -z $1 ] ; then
        echo " hbase_path is null!!!"
        exit
    fi

    if [ -z $2 ] ; then
        echo " file_path is null!!!"
        exit
    fi
    cd $1
    ./hbase shell< $2
fi
~                


总结:
      1:hbase的rowkey定义,一定要根据业务来进行好好的定义,不是后期你就等着受苦吧。
       2:mapreduce任务的可控性比较差,资源占用太严重。
              

     

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值