問題描述, 我們的業務需要我們對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 修改操作的問題