0

HBase 0.94.0 をインストールしました。スキャンによって読み取りパフォーマンスを改善する必要がありました。ランダムに 100000 レコードを挿入しました。

パフォーマンスを設定したときsetCache(100);、100000 レコードで 16 秒でした。

私が自分のパフォーマンスに設定したときsetCache(50)、100000 レコードで 90 秒でした。

私のパフォーマンスに設定するとsetCache(10);、100000 レコードで 16 秒でした

public class Test {
    public static void main(String[] args) {

    long start, middle, end;

    HTableDescriptor descriptor = new HTableDescriptor("Student7");
    descriptor.addFamily(new HColumnDescriptor("No"));
    descriptor.addFamily(new HColumnDescriptor("Subject"));

    try {   
    HBaseConfiguration config = new HBaseConfiguration();
    HBaseAdmin admin = new HBaseAdmin(config);

    admin.createTable(descriptor);
            HTable table = new HTable(config, "Student7");
            System.out.println("Table created !");

    start = System.currentTimeMillis();

    for(int i =1;i<100000;i++) {
        String s=Integer.toString(i);
        Put p = new Put(Bytes.toBytes(s));
        p.add(Bytes.toBytes("No"), Bytes.toBytes("IDCARD"),Bytes.toBytes("i+10"));
        p.add(Bytes.toBytes("No"), Bytes.toBytes("PHONE"),Bytes.toBytes("i+20"));
        p.add(Bytes.toBytes("No"), Bytes.toBytes("PAN"),Bytes.toBytes("i+30"));
        p.add(Bytes.toBytes("No"), Bytes.toBytes("ACCT"),Bytes.toBytes("i+40"));
        p.add(Bytes.toBytes("Subject"), Bytes.toBytes("English"),Bytes.toBytes("50"));
        p.add(Bytes.toBytes("Subject"), Bytes.toBytes("Science"),Bytes.toBytes("60"));
        p.add(Bytes.toBytes("Subject"), Bytes.toBytes("History"),Bytes.toBytes("70"));

        table.put(p);
    }
    middle = System.currentTimeMillis();

    Scan s = new Scan();
    s.setCaching(100);      
    ResultScanner scanner = table.getScanner(s);

    try {
        for (Result rr = scanner.next(); rr != null; rr=scanner.next()) {
            System.out.println("Found row: " + rr);
        }
        end = System.currentTimeMillis(); 
    } finally {
        scanner.close();
    }       
        System.out.println("TableCreation-Time: " + (middle - start));
        System.out.println("Scan-Time: " + (middle - end));
    } catch (IOException e) {
        System.out.println("IOError: cannot create Table.");
        e.printStackTrace();
        }
    }
}

なぜこうなった?

4

1 に答える 1

1

100000 レコード テーブルのすべてのレコードを返す必要があるのはなぜですか? テーブル全体のスキャンを実行していますが、大規模なデータベースと同様に低速です。

レコードの一部の列またはレコードの範囲を返したい、より有用な使用例について考えてみてください。

HBase のテーブルには、行キーという 1 つのインデックスしかありません。それを利用してください。ロウキーを指定するだけで必要なデータが取得できるように、ロウキーを定義してみてください。

Subject:History行キーが 80000 から 80100 の間の行の値を知りたいとします。 ( setCaching(100)HBase は RPC ごとに 100 レコードをフェッチすることに注意してください。この場合は 1 つです。100 行をフェッチするには、フェッチするよりも明らかに多くのメモリが必要です。 、たとえば 1 行です。大規模なマルチユーザー環境では、この点に注意してください)。

Long start, end;
start = System.currentTimeMillis();

Scan s = new Scan(String.valueOf(80000).getBytes(), String.valueOf(80100).getBytes());
s.setCaching(100);
s.addColumn("Subject".getBytes(), "History".getBytes());

ResultScanner scanner = table.getScanner(s);
try {
    for (Result rr = scanner.next(); rr != null; rr=scanner.next()) {
        System.out.println("Found row: " + new String(rr.getRow(), "UTF-8") + " value: " + new String(rr.getValue("Subject".getBytes(), "History".getBytes()), "UTF-8")));
    }
    end = System.currentTimeMillis(); 
} finally {
    scanner.close();
}       
System.out.println("Scan: " + (end - start));

これはばかげているように見えるかもしれません。なぜなら、必要な行を整数だけで知るにはどうすればよいのでしょうか? その通りですが、そのため、従来のデータベースのように増分値を使用するのではなく、クエリしようとしている内容に応じて行キーを設計する必要があります。

この例を試してください。それは速いはずです。

注: この例は実行しませんでした。ここに入力しただけです。修正すべき小さな構文エラーがいくつかあるかもしれませんが、アイデアが明確であることを願っています。

于 2013-02-06T13:42:04.217 に答える