IT博客汇
  • 首页
  • 精华
  • 技术
  • 设计
  • 资讯
  • 扯淡
  • 权利声明
  • 登录 注册

    [原]HBase1.1.2 row lock

    fansy1990发表于 2016-05-19 10:31:21
    love 0

    版本:

    HBase:1.1.2;Hadoop2.6.0;Eclipse:Mars.1 Release (4.5.1);


    应用场景:HBase中有一个表,里面有一条记录,如下:


    现在需要根据value的值,比如当其为“true”的时候进行更新操作(也就是插入操作,表设置Versions为100),更新为false;

    问题描述:

    1) 当只有一个线程来操作的时候,可以直接取得值,然后根据值来判断即可进行插入;

    2)如果有多个线程的话(比如10个线程),那么1)的方法就不行了,会直接插入10条记录(因为有多个版本,所以会查到11条记录);

    3)如果使用rowlock的话,可以解决这个问题,在进行put的时候,去获取rowlock,如果获取不了(其他线程已经先获得了rowlock),那么就不插入;

    4)但是,rowlock在hbase之前的版本是有的,但是后面的版本就没有了(性能影响,所以hbase把client的rowlock去掉了);

    那么,怎么办?

    参考:http://www.ngdata.com/hbase-row-locks/ 

    使用HTable.checkAndPut() 即可解决这个问题;

    测试代码:

    main:

    package demo;
    
    import java.io.IOException;
    import java.text.SimpleDateFormat;
    import java.util.Date;
    
    import org.apache.hadoop.conf.Configuration;
    import org.apache.hadoop.hbase.HBaseConfiguration;
    import org.apache.hadoop.hbase.client.Connection;
    import org.apache.hadoop.hbase.client.ConnectionFactory;
    
    public class TestMultiPut {
    /**
     * 
     * @param args
     */
    	public static final String TABLE = "multiput";
    	public static final String FAMILY = "cf1";
    	public static final String COL1 = "q1";
    	public static final String ROWKEY1 = "rk1";
    	public static final SimpleDateFormat sf = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss SSS") ;
    	public static void main(String[] args) throws IOException {
    		Configuration conf = HBaseConfiguration.create();
    		conf.set("hbase.master", "node2:16000");// 指定HMaster
    		conf.set("hbase.rootdir", "hdfs://node1:8020/hbase");// 指定HBase在HDFS上存储路径
    		conf.set("hbase.zookeeper.quorum", "node2,node3,node4");// 指定使用的Zookeeper集群
    		conf.set("hbase.zookeeper.property.clientPort", "2181");// 指定使用Zookeeper集群的端口
    
    		Connection connection = ConnectionFactory.createConnection(conf);
    		for(int i=0;i<10;i++){
    //			new Thread(new PutThread(connection)).start();
    			new Thread(new PutThread2(connection)).start();
    		}
    		System.out.println("all done");
    	}
    
    	public static String getTimeStr(){
    		return sf.format(new Date(System.currentTimeMillis()));
    	}
    }
    

    thread:

    package demo;
    
    import static demo.TestMultiPut.COL1;
    import static demo.TestMultiPut.FAMILY;
    import static demo.TestMultiPut.ROWKEY1;
    import static demo.TestMultiPut.TABLE;
    
    import java.io.IOException;
    
    import org.apache.hadoop.hbase.TableName;
    import org.apache.hadoop.hbase.client.Connection;
    import org.apache.hadoop.hbase.client.Put;
    import org.apache.hadoop.hbase.client.Table;
    import org.apache.hadoop.hbase.filter.CompareFilter.CompareOp;
    import org.apache.hadoop.hbase.util.Bytes;
    public class PutThread2 implements Runnable {
    	Connection connection ;
    	public PutThread2(Connection conn) {
    		this.connection= conn;
    	}
    	@Override
    	public void run() {
    		try {
    			Table table = connection.getTable(TableName.valueOf(TABLE));
    			
    			
    			Put put = new Put(Bytes.toBytes(ROWKEY1));
    			put.addColumn(FAMILY.getBytes(), COL1.getBytes(), "false".getBytes());
    			
    			
    			boolean flag = table.checkAndPut(Bytes.toBytes(ROWKEY1), Bytes.toBytes(FAMILY), Bytes.toBytes(COL1),
    					CompareOp.EQUAL, "true".getBytes(), put);
    			
    			table.close();
    			if(flag){
    				System.out.println(TestMultiPut.getTimeStr()
    					+" ,thread:"+Thread.currentThread().getName()+" 插入成功--------");
    			}else{
    				System.out.println(TestMultiPut.getTimeStr()
    						+" ,thread:"+Thread.currentThread().getName()+" 插入失败XXXXXXX");
    			}
    			
    		} catch (IOException e) {
    			System.out.println(TestMultiPut.getTimeStr()
    					+" 报错:thread:"+Thread.currentThread().getName());
    			e.printStackTrace();
    			
    		}
    	}
    
    }
    

    运行main,得到下面的日志:


    同时,查看HBase表,


    也只是插入了一条记录;


    总结:

    1. 使用HTable.checkAndPut(),可以解决row lock的问题;

    2. 为什么插入成功的,其线程时间不是最小的?

    可能是因为网络延时;



    分享,成长,快乐

    脚踏实地,专注

    转载请注明blog地址:http://blog.csdn.net/fansy1990




沪ICP备19023445号-2号
友情链接