我已经安装了 HBase 0.94.0。我必须通过扫描来提高我的阅读性能。我随机插入了 100000 条记录。
当我设置 setCache(100);
时,100000 条记录的性能为 16 秒。
当我将其设置为 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();
}
}
}
为什么会发生这种情况?
最佳答案
为什么要返回 100000 条记录表中的每条记录?你正在做一个完整的 表扫描就像在任何大型数据库中一样,速度很慢。
尝试考虑一个更有用的用例,在该用例中您希望返回一条记录或一系列记录的某些列。
HBase 在其表上只有一个索引,即行键。利用这一点。尝试定义您的行键,以便您只需指定行键即可获取所需的数据。
假设您想知道带有 a 的行的 Subject:History
值
row key 介于 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));
这可能看起来很愚蠢,因为您如何仅通过整数知道需要哪些行?嗯,确实如此,但这就是为什么您需要根据要查询的内容设计行键,而不是像在传统数据库中那样仅使用增量值。
试试这个例子。应该很快。
注意:我没有运行该示例。我刚刚在这里输入的。也许有一些小的语法错误你应该纠正,但我希望这个想法是清楚的。
关于java - Hbase读取性能异常变化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14729779/