0

我已经安装了 HBase 0.94.0。我必须通过扫描来提高我的阅读性能。我已经随机插入了 100000 条记录。

当我设置setCache(100);我的性能是 16 秒 100000 条记录。

当我将其设置setCache(50)为 100000 条记录时,我的性能为 90 秒。

当我将它设置为setCache(10);我的性能是 16 秒 100000 条记录

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 的表上只有一个索引,即行键。好好利用它。尝试定义行键,以便您只需指定行键即可获取所需的数据。

假设您想知道Subject:History行键在 80000 到 80100 之间的行的值。(请注意,这setCaching(100)意味着 HBase 将在每个 RPC 中获取 100 条记录,因此是这种情况。获取 100 行显然需要更多内存而不是获取,比方说,一行。在大型多用户环境中请记住这一点。)

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 回答