Как сканировать и удалять миллионы строк в HBase - PullRequest
0 голосов
/ 28 сентября 2018

Что случилось
Все данные за прошлый месяц были повреждены из-за ошибки в системе.Поэтому мы должны удалить и повторно ввести эти записи вручную.По сути, я хочу удалить все строки, вставленные в течение определенного периода времени.Однако мне было сложно сканировать и удалять миллионы строк в HBase.

Возможные решения
Я нашел два способа массового удаления:
Первый - установить TTL, чтобы система автоматически удаляла все устаревшие записи.,Но я хочу сохранить записи до прошлого месяца, так что это решение не работает для меня.

Второй вариант - написать клиент с использованием Java API:

 public static void deleteTimeRange(String tableName, Long minTime, Long maxTime) {
    Table table = null;
    Connection connection = null;

    try {
        Scan scan = new Scan();
        scan.setTimeRange(minTime, maxTime);
        connection = HBaseOperator.getHbaseConnection();
        table = connection.getTable(TableName.valueOf(tableName));
        ResultScanner rs = table.getScanner(scan);

        List<Delete> list = getDeleteList(rs);
        if (list.size() > 0) {

            table.delete(list);
        }
    } catch (Exception e) {
        e.printStackTrace();

    } finally {
        if (null != table) {
            try {
                table.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        if (connection != null) {
            try {
                connection.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

}

private static List<Delete> getDeleteList(ResultScanner rs) {

    List<Delete> list = new ArrayList<>();
    try {

        for (Result r : rs) {
            Delete d = new Delete(r.getRow());
            list.add(d);
        }
    } finally {
        rs.close();
    }
    return list;
}

Но при этом подходе все записи хранятся в ResultScanner rs, поэтому размер кучи будет огромным,И если программа рушится, она должна начинаться с самого начала.
Итак, есть ли лучший способ достичь цели?

1 Ответ

0 голосов
/ 28 сентября 2018

Не знаю, сколько «миллионов» вы имеете в своей таблице, но самое простое - не пытаться поместить их все в List сразу, а сделать это более управляемыми шагами, используя.next(n) функция.Примерно так:

for (Result row : rs.next(numRows))
{
Delete del = new Delete(row.getRow());
...
}

Таким образом, вы можете контролировать, сколько строк возвращается с сервера через один RPC через параметр numRows.Убедитесь, что он достаточно большой, чтобы не делать слишком много обращений к серверу, но в то же время не слишком большим, чтобы уничтожить вашу кучу.Вы также можете использовать BufferedMutator для одновременной работы с несколькими Delete.

Надеюсь, это поможет.

...