2011-01-06 2 views
8

Есть ли эффективный способ удаления нескольких строк в HBase или мой запах использования, который не подходит для HBase?Эффективный способ удаления нескольких строк в HBase

В таблице указано «диаграмма», которая содержит элементы, которые находятся в диаграммах. Ключи строк в следующем формате: chart|date_reversed|ranked_attribute_value_reversed|content_id

Иногда я хочу, чтобы восстановить таблицу для данной даты, поэтому я хочу, чтобы удалить все строки, начинающиеся с «графика | date_reversed_1» до «графика | date_reversed_2». Есть ли лучший способ, чем выдавать Delete для каждой строки, найденной при сканировании? Все строки, которые нужно удалить, будут близки друг к другу.

Мне нужно удалить строки, потому что я не хочу, чтобы один элемент (один content_id) имел несколько записей, которые он будет иметь, если бы его ranked_attribute_value было изменено (его изменение является причиной того, что диаграмма должна быть восстановлена) ,

Будучи новичком в HBase, возможно, я мог бы злоупотреблять строками для чего-то, что было бы лучше, если бы у вас были дизайнерские предложения, круто! Или, может быть, диаграммы лучше сгенерированы в файле (например, нет HBase для вывода)? Я использую MapReduce.

ответ

7

Во-первых, приближаясь к точке дальности удаления, в HBase, AFAIK еще не удаляется диапазон. Но есть способ удалить более одного ряда за раз в HTableInterface API. Для этого просто создайте объект Delete с ключами строки из сканирования и поместите их в список и используйте API! Чтобы ускорить сканирование, не включайте никакое семейство столбцов в результат сканирования, поскольку все, что вам нужно, это ключ строки для удаления целых строк.

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

Для моего предположения я бы предложил использовать три таблицы - auto_id, content_charts и generate_order. Ключ строки для content_charts будет его идентификатором содержимого, а ключ строки для generate_order будет длинным, который будет автоматически уменьшенным с использованием HTableInterface API. Для уменьшения используйте «-1» в качестве суммы для смещения и инициализации значения Long.MAX_VALUE в таблице auto_id при первом запуске приложения или вручную. Итак, теперь, если вы хотите удалить данные диаграммы, просто очистите семейство столбцов, используя delete, а затем верните новые данные и затем введите их в таблицу сгенерированных_порядков. Таким образом, последняя вставка также будет находиться в верхней части последней таблицы вставки, которая будет содержать идентификатор содержимого в качестве значения ячейки. Если вы хотите, чтобы generate_order имел только одну запись для каждого контента, сначала сохраните идентификатор сгенерированной_идентификационной единицы и берете значение и сохраняйте его в content_charts при установке и перед удалением семейства столбцов сначала удалите строку из generate_order. Таким образом, вы можете искать и создавать диаграммы для контента, используя 2, с максимальным и не требующим сканирования для диаграмм.

Надеюсь, это полезно.

2

Вы можете использовать BulkDeleteProtocol, который использует сканирование, которое определяет соответствующий диапазон (начальная строка, конечная строка, фильтры).

here См

+1

Этот объект не входит в 96 – Adelin

2

Я выбежала в вашей ситуации, и это мой код, чтобы осуществить то, что вы хотите

Scan scan = new Scan(); 
    scan.addFamily("Family"); 
    scan.setStartRow(structuredKeyMaker.key(starDate)); 
    scan.setStopRow(structuredKeyMaker.key(endDate + 1)); 
try { 
    ResultScanner scanner = table.getScanner(scan); 


    Iterator<Entity> cdrIterator = new EntityIteratorWrapper(scanner.iterator(), EntityMapper.create(); // this is a simple iterator that maps rows to exact entity of mine, not so important ! 

    List<Delete> deletes = new ArrayList<Delete>(); 
    int bufferSize = 10000000; // this is needed so I don't run out of memory as I have a huge amount of data ! so this is a simple in memory buffer 
    int counter = 0; 
    while (entityIterator.hasNext()) { 
     if (counter < bufferSize) { 
          // key maker is used to extract key as byte[] from my entity 
      deletes.add(new Delete(KeyMaker.key(entityIterator.next()))); 
      counter++; 

     } else { 
      table.delete(deletes); 
      deletes.clear(); 
      counter = 0; 
     } 
    } 

    if (deletes.size() > 0) { 
     table.delete(deletes); 
     deletes.clear(); 
    } 

} catch (IOException e) { 
    e.printStackTrace(); 
}