2011-01-06 19 views
8

HBaseで複数の行を削除する効率的な方法はありますか、HBaseには適していないようなユースケースの匂いはありますか?HBaseの複数の行を効率的に削除する

「chart」という表があります。この表には、チャートにある項目が含まれています。行キーは、次の形式である: chart|date_reversed|ranked_attribute_value_reversed|content_id

時々私は、与えられた日付のチャートを再生成したいので、私はから始まるすべての行を削除したい「チャート| date_reversed_1」まで「チャート| date_reversed_2」。スキャンで見つかった行ごとに削除を発行するよりも良い方法はありますか?削除されるすべての行は、互いに近くになります。

rank_attribute_valueが変更された場合に1つのアイテム(1つのcontent_id)に複数のエントリを持たせたくないので、その行を削除する必要があります(その変更がチャートを再生成する必要がある理由です) 。

HBaseの初心者であるため、列がうまくいくために行を誤っている可能性があります。デザインの提案があれば、クール!または、ファイルでチャートを生成したほうが良いでしょう(例:出力用HBaseなし)。私はMapReduceを使用しています。

答えて

7

まず、範囲削除の対象となるのは、HBase、AFAIKで範囲削除がまだありません。しかし、HTableInterface APIでは一度に複数の行を削除する方法があります。このためには、スキャンから行キーを持つDeleteオブジェクトを単純に作成し、リストに入れてAPIを使用してください。スキャンを高速化するには、スキャン結果に列ファミリを含めないでください。必要なのは、行全体を削除するための行キーだけです。

第2に、デザインについてです。最初の要件の私の理解は、コンテンツIDを持つコンテンツがあり、各コンテンツはそれらに対して生成されたチャートを持っていて、それらのデータが格納されています。日付ごとにコンテンツごとに複数のチャートがあり、ランクによって異なります。さらに、最後に生成されたコンテンツのグラフを表の上部に表示する必要があります。

私は、auto_id、content_charts、およびgenerated_orderという3つのテーブルを使用することを前提にしています。 content_chartsの行キーはコンテンツIDになり、generated_orderの行キーはが自動的にデクリメントされるとなり、HTableInterface APIを使用します。デクリメントするには、アプリケーションの最初の起動時または手動でauto_idテーブルの値Long.MAX_VALUEをオフセットおよび初期化する量として '-1'を使用します。したがって、チャートデータを削除する場合は、deleteを使用して列ファミリを消去し、新しいデータを戻してからgenerated_orderテーブルに配置します。このようにして、最新の挿入は、コンテンツIDをセル値として保持する最新の挿入テーブルの最上部にも挿入されます。 generated_orderがコンテンツごとに1つのエントリしか持たないようにするには、まずgenerated_order idを保存し、値を取得してそれをcontent_chartsに保存してから列ファミリを削除する前に、まずgenerated_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(); 
} 
関連する問題