|
@@ -0,0 +1,182 @@
|
|
|
|
+package com.winhc.phoenix.example.framework.hbase;
|
|
|
|
+
|
|
|
|
+import com.google.common.util.concurrent.ThreadFactoryBuilder;
|
|
|
|
+import com.winhc.phoenix.example.util.HbaseResultUtils;
|
|
|
|
+import lombok.SneakyThrows;
|
|
|
|
+import lombok.extern.slf4j.Slf4j;
|
|
|
|
+import org.apache.hadoop.hbase.HRegionLocation;
|
|
|
|
+import org.apache.hadoop.hbase.TableName;
|
|
|
|
+import org.apache.hadoop.hbase.client.*;
|
|
|
|
+import org.apache.hadoop.hbase.util.Bytes;
|
|
|
|
+
|
|
|
|
+import java.util.ArrayList;
|
|
|
|
+import java.util.List;
|
|
|
|
+import java.util.Map;
|
|
|
|
+import java.util.concurrent.ArrayBlockingQueue;
|
|
|
|
+import java.util.concurrent.RejectedExecutionException;
|
|
|
|
+import java.util.concurrent.ThreadPoolExecutor;
|
|
|
|
+import java.util.concurrent.TimeUnit;
|
|
|
|
+import java.util.function.Consumer;
|
|
|
|
+
|
|
|
|
+/**
|
|
|
|
+ * @author: XuJiakai
|
|
|
|
+ * 2020/11/16 11:35
|
|
|
|
+ */
|
|
|
|
+@Slf4j
|
|
|
|
+public class HbaseFastScan {
|
|
|
|
+ private int thread_num = 1;
|
|
|
|
+ private int batchSize = 500;
|
|
|
|
+
|
|
|
|
+ private Connection connection;
|
|
|
|
+ private TableName tableName;
|
|
|
|
+
|
|
|
|
+ private Consumer<List<Map<String, Object>>> func;
|
|
|
|
+
|
|
|
|
+ public HbaseFastScan(Connection connection, String tableName, Consumer<List<Map<String, Object>>> func) {
|
|
|
|
+ this.connection = connection;
|
|
|
|
+ this.tableName = TableName.valueOf(tableName);
|
|
|
|
+ this.func = func;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ public HbaseFastScan thread_num(int thread_num) {
|
|
|
|
+ this.thread_num = thread_num;
|
|
|
|
+ return this;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ public HbaseFastScan batchSize(int batchSize) {
|
|
|
|
+ this.batchSize = batchSize;
|
|
|
|
+ return this;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ private class Task extends Thread {
|
|
|
|
+ private byte[] startKey;
|
|
|
|
+ private byte[] endKey;
|
|
|
|
+ private String regionName;
|
|
|
|
+ private String tn;
|
|
|
|
+
|
|
|
|
+ public Task(RegionInfo regionInfo) {
|
|
|
|
+ this.regionName = regionInfo.getRegionNameAsString();
|
|
|
|
+ this.startKey = regionInfo.getStartKey();
|
|
|
|
+ this.endKey = regionInfo.getEndKey();
|
|
|
|
+ this.tn = regionName + "-" + getKeyAsString(startKey) + "_" + getKeyAsString(endKey);
|
|
|
|
+ log.info("{}:{} {}", regionName, getKeyAsString(startKey), getKeyAsString(endKey));
|
|
|
|
+ setName(tn);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ @Override
|
|
|
|
+ public void run() {
|
|
|
|
+ log.info("start。。。");
|
|
|
|
+ List<Map<String, Object>> list = new ArrayList<>();
|
|
|
|
+ try (Table table = connection.getTable(tableName)) {
|
|
|
|
+ Scan scan = new Scan();
|
|
|
|
+ if (startKey.length != 0) {
|
|
|
|
+ scan.withStartRow(startKey);
|
|
|
|
+ }
|
|
|
|
+ if (endKey.length != 0) {
|
|
|
|
+ scan.withStopRow(endKey);
|
|
|
|
+ }
|
|
|
|
+ scan.setCaching(batchSize);
|
|
|
|
+
|
|
|
|
+ ResultScanner scanner = table.getScanner(scan);
|
|
|
|
+ for (Result result : scanner) {
|
|
|
|
+ Map<String, Object> columnMap = HbaseResultUtils.parseResult(result);
|
|
|
|
+ list.add(columnMap);
|
|
|
|
+ if (list.size() >= batchSize) {
|
|
|
|
+ func.accept(list);
|
|
|
|
+ list.clear();
|
|
|
|
+ log.info("current rowkey: {}", columnMap.getOrDefault("rowkey", null));
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ if (!list.isEmpty()) {
|
|
|
|
+ func.accept(list);
|
|
|
|
+ list.clear();
|
|
|
|
+ }
|
|
|
|
+ log.info("{} 执行完成!", tn);
|
|
|
|
+ } catch (Exception e) {
|
|
|
|
+ log.error(e.getMessage(), e);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ @SneakyThrows
|
|
|
|
+ public void scan() {
|
|
|
|
+ try (RegionLocator regionLocator = connection.getRegionLocator(tableName);) {
|
|
|
|
+
|
|
|
|
+ List<HRegionLocation> allRegionLocations = regionLocator.getAllRegionLocations();
|
|
|
|
+
|
|
|
|
+ int poolSize = 10;
|
|
|
|
+ ArrayBlockingQueue<Runnable> objects = new ArrayBlockingQueue<>(poolSize);
|
|
|
|
+ ThreadPoolExecutor executorService = new ThreadPoolExecutor(
|
|
|
|
+ poolSize, poolSize,
|
|
|
|
+ 0L, TimeUnit.MILLISECONDS,
|
|
|
|
+ objects, // 未处理的任务的等待队列
|
|
|
|
+ new ThreadFactoryBuilder().setNameFormat("ScanHbase-pool-").build(),
|
|
|
|
+ (r, executor) -> {
|
|
|
|
+ try {
|
|
|
|
+ executor.getQueue().put(r);
|
|
|
|
+ } catch (InterruptedException e) {
|
|
|
|
+ throw new RejectedExecutionException("interrupted", e);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ );
|
|
|
|
+
|
|
|
|
+ for (int i = 0; i < allRegionLocations.size(); i++) {
|
|
|
|
+ HRegionLocation hRegionLocation = allRegionLocations.get(i);
|
|
|
|
+ log.info("region host: {}", hRegionLocation.getHostname());
|
|
|
|
+ RegionInfo regionInfo = hRegionLocation.getRegion();
|
|
|
|
+
|
|
|
|
+ String regionName = regionInfo.getRegionNameAsString();
|
|
|
|
+ byte[] startKey = regionInfo.getStartKey();
|
|
|
|
+ byte[] endKey = regionInfo.getEndKey();
|
|
|
|
+ String tn = regionName + "-" + getKeyAsString(startKey) + "_" + getKeyAsString(endKey);
|
|
|
|
+ Scan scan = new Scan();
|
|
|
|
+ if (startKey.length != 0) {
|
|
|
|
+ scan.withStartRow(startKey);
|
|
|
|
+ }
|
|
|
|
+ if (endKey.length != 0) {
|
|
|
|
+ scan.withStopRow(endKey);
|
|
|
|
+ }
|
|
|
|
+ new Task(regionInfo).start();
|
|
|
|
+
|
|
|
|
+// executorService.submit(new Task(regionInfo));
|
|
|
|
+ /* executorService.submit(() -> {
|
|
|
|
+ log.info("start。。。");
|
|
|
|
+ List<Map<String, Object>> list = new ArrayList<>();
|
|
|
|
+ try (Table table = connection.getTable(tableName)) {
|
|
|
|
+
|
|
|
|
+ scan.setCaching(batchSize);
|
|
|
|
+
|
|
|
|
+ ResultScanner scanner = table.getScanner(scan);
|
|
|
|
+ for (Result result : scanner) {
|
|
|
|
+ Map<String, Object> columnMap = HbaseResultUtils.parseResult(result);
|
|
|
|
+ list.add(columnMap);
|
|
|
|
+ if (list.size() >= batchSize) {
|
|
|
|
+ func.accept(list);
|
|
|
|
+ list.clear();
|
|
|
|
+ log.info("current rowkey: {}", columnMap.getOrDefault("rowkey", null));
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ if (!list.isEmpty()) {
|
|
|
|
+ func.accept(list);
|
|
|
|
+ list.clear();
|
|
|
|
+ }
|
|
|
|
+ log.info("{} 执行完成!", tn);
|
|
|
|
+ } catch (Exception e) {
|
|
|
|
+ log.error(e.getMessage(), e);
|
|
|
|
+ }
|
|
|
|
+ });*/
|
|
|
|
+
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ private static String getKeyAsString(byte[] b) {
|
|
|
|
+ if (b.length == 0) {
|
|
|
|
+ return "0";
|
|
|
|
+ } else {
|
|
|
|
+ return Bytes.toString(b);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+}
|