使用spark 對hbase 進行先刪除,後插入 ,部分數據沒有插入成功,

問題描述, 我們的業務需要我們對hbase 中的數據進行修改操作, 因此需要對數據先刪除,後插入,  期間發現部分hbase  rowkey  確實刪除了, 但是沒有插入數據?

問題產生的原因,   delete  和put 默認使用的  timestamp 插入當前hbase 服務器最後的時間, 如果  put的時間<=delete 的時間,當前rowkey  對應的列 都保存這刪除的時間,  我們查詢數據, 默認是獲取時間戳最新的數據,  因此查詢不到當前插入的數據

問題解決方案:put  和delete  都支持自己設置 timestamp  通過設置put時間戳大於delete的時間戳的方式,來避免這個問題

重現問題,這裏我就不寫spark 了 ,直接用hbase 的api 操作單條記錄

 private static Logger logger = LoggerFactory.getLogger(SparkSolrByLocal.class);
    static Configuration conf;

    static Connection connection;

    static {
        conf = HBaseConfiguration.create();
        conf.set("hbase.zookeeper.quorum", "192.168.1.38,192.168.1.39,192.168.1.40");
        try {
            connection = ConnectionFactory.createConnection(conf);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

測試  先往hbase 表中添加數據

重現問題,使得 put 的時間戳小於或者等於 delete的時間戳

 public static void main(String[] args) throws IOException, InterruptedException {
        String tableName = "two";
        Table table = connection.getTable(TableName.valueOf(tableName));// 獲取表
        String str = "A0000";
        int s = 0000;
        Date date=new Date();
        long time = date.getTime();
        System.out.println(time);
        Delete delete = new Delete(Bytes.toBytes("r2"),time);
        table.delete(delete);
        Put put = new Put(Bytes.toBytes("r2"), time);

        for (int i = 0; i < 4; i++) {
            s++;
            String s1 = s + "";
            int length = s1.length();
            String substring = str.substring(0, str.length() - length);
            str = substring + s1;
            put.addColumn(Bytes.toBytes("cf"), Bytes.toBytes(str), Bytes.toBytes("1"));

        }
        table.put(put);
    }

執行main後再去hbase shell中查看  two 表中的r2

發現 當put 和delete 時間相等的時候, 再次查詢 就沒有結果了 ,重現了問題

使用手動設置時間戳的方式,將put 時間戳設置爲 delete  之後, 

 public static void main(String[] args) throws IOException, InterruptedException {
        String tableName = "two";
        Table table = connection.getTable(TableName.valueOf(tableName));// 獲取表
        String str = "A0000";
        int s = 0000;
        Date date=new Date();
        long time = date.getTime();
        System.out.println(time);
        Delete delete = new Delete(Bytes.toBytes("r2"),time);
        table.delete(delete);
        Put put = new Put(Bytes.toBytes("r2"), time+1);

        for (int i = 0; i < 4; i++) {
            s++;
            String s1 = s + "";
            int length = s1.length();
            String substring = str.substring(0, str.length() - length);
            str = substring + s1;
            put.addColumn(Bytes.toBytes("cf"), Bytes.toBytes(str), Bytes.toBytes("1"));

        }
        table.put(put);
    }

這樣就能確保 delete之後put 數據能夠被查到, 

解決了使用spark 程序 對hbase 修改操作的問題

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章