整套大数据学习资料(视频+笔记)百度网盘无门槛下载:http://www.edu360.cn/news/content?id=3377

13.5.3 Web 查询

hadoop 花牛 11℃ 0评论

为了实现Web应用,我们将直接使用HBaseJava API。在这里,我们将 深刻体会到选择模式和存储格式的重要性。

最简单的査询就是获取静态的观测站信息。这一类査洵在传统数据库中也 很简单,但HBase提供了额外的控制功能和灵活性。我们把info列族作为 键/值字典(列名作为键,列值作为值),代码如下所示:

public Map<String, String> getStationInfo(HTable table. String stationld) 
    throws IOException {
    Get get = new Get(Bytes.toBytes(stationld)); get.addColumn(INFO_COLUMNFAMILY);
    Result res = table.get(get); 
    if (res == null) { 
        return null;
    }
    Map<String, String〉resultMap = new HashMap<String, String>(); 
    resultMap.put(” name” , getValue(res, INFOJIOLUMNFAMILY, NAME一QUALIFIER)); 
    resultMap.put("location", getValue(res) INFO—COLUMNFAMILY, LOCATION—QUALIFIER)); 
    resultMap.put("description", getValue(res, INFO_COLUMNFAMILY, DESCRIPTION_QUALIFIER)); 
    return resultMap;
    private static String getValue(Result res, byte [] cf, byte [] qualifier) { 
        byte [] value = res.getValue(cf^ qualifier); 
        return value == null? : Bytes.toString(value);
    }

    

在这个示例中,getStationInfo()接收一个HTable实例和一个观测站 ID。为了获取观测站的信息,我们使用HTable.get()来传递一个Get实 例。它被设置为用于获取已定义列族INFO_COLUMNFAMILY中由观测站ID

所指明的列的值。

get()的结果返回给Result。它包含数据行,你可以通过操作需要的列单


元格来取得单元格的值。getStationInfo()方法把Result Map转换为更 便于使用的由String类型的键和值构成的Map

我们已经看出在使用HBase时为什么需要工具函数了。在HBase上,为了 处理底层的交互,我们已经开发出越来越多的抽象。但是,理解它们的工 作机理以及各个存储选项之间的差异,非常重要。

和关系型数据库相比,HBase的优势之一是不需要我们预先设定列。所以 在将来,如果每个观测站在这三个必有的属性以外还有几百个可选的属 性,我们便可以直接插入这些属性而不需要修改模式。当然,你的应用中 读和写的代码是需要修改的。在示例中,我们可以循环遍历Result来获取 每个值,而不用显式获取各个值。

我们将在Web应用中使用HBase扫描器(scanner)来检索观测数据。

在这里,需要的是Map<ObservationTimeObservedTemp>结果。我们将 使用NavigableMap<LongInteger〉,因为它提供的结果是有序的,且 有一个descendingMap()方法。这样,我们既可以用升序也可以用降序来 访问观测数据了。代码如范例13-4所示。

范例13-4.检索HBase表中某范围内气象站观测数据行的方法

public NavigableMap<Long, Integer〉 getStationObsenvations(HTable table, 
    String stationld, long maxStamp, int maxCount) throws IOException { 
    byte[] startRow = RowKeyConverter.makeObservationRowKey(stationId, maxStamp); 
    NavigableMap<Longi Integer〉 resultMap = new TreeMap<LongJ Integer>();
    Scan scan = new Scan(startRow);
    scan.addColumn(DATA_COLUMNFAMILY, AIRTEMP_QUALIFIER);
    ResultScanner scanner = table.getScanner(scan);
    Result res = null; 
    int count = 0; 
    try {
    while ((res = scanner.next())!= null && count++ < maxCount) { 
        byte[] row = res.getRow();
        byte[] value = res.getValue(DATA_COLUMNFAMILY, AIRTEMP_QUALIFIER);
        Long stamp = Long.MAX_VALUE
            Bytes.toLong(row> row.length -Bytes.SIZEOF_LONG, Bytes.SIZEOF__LONG); 
            Integer temp = Bytes.tolnt(value); 
            resultMap.put(stamp, temp);
        }
    } finally {
        scanner.close();
    }
    return resultMap;
}
public NavigableMap<Long, Integer〉 getStationObservations(HTable table, 
    String stationld) throws IOException { 
    return getStationObservations(table, stationld, Long.MAX_VALUE, 10);

getStationObservations()方法接受观测站ID、由maxStamp定义的范 围以及最大数据行数(maxCount)作为参数。注意,返回的NavigableMap 实际上是按降序排列的。如果想以升序读它,需要使用NavigableMapdescendingMap()。

扫描器

HBase扫描器(scanner)和传统数据库中的游标(cursor)Java中的迭代器 (iterator)类似。它和后者的不同在于在使用后需要关闭。扫描器按次序返 回数据行。用户使用已设置的Scan对象实例作为scan参数,调用 HTable.getScanner(scan),以此来获取HBase中一个表上的扫描器。 通过Scan实例,你可以传递担描开始位置和结束位置的数据行、返回结 果中要包含的列以及(可选的)运行在服务器端的过滤器。ResultScanner 接口是调用HTable.getScanner()时返回的接口。它的定义如下:

public interface ResultScanner extends Closeable, Iterable<Result> { 
    public Result next() throws IOException; 
    public Result [] next(int nbRows) throws IOException; 
    public void close();
}

可以查看接下来的一个或多个数据行。每次调用next()都会访问一次 regionserver.因此,一次获取多行可以显著提升性能。

在前面的示例中,把数据存成Long.MAX_VALUE – stamp,其优势还不是

特别明显。如果要根据“偏移量”offset)和“限制范围”limit)来获取最新 观测数据,这种存储方式就显得更为有用。而这种查询在Web应用中是屡 见不鲜的。如果观测数据直接用实际的时间戳来存放,我们就只能根据偏 移量和限制范围高效地获取最老的观测数据。要获取最新的数据意味着要 拿到所有的数据,直到最后才能获得结果。从RDBMS转向HBase的一个主要原因就是HBase允许这种“提早过滤”early-out)情况。

转载请注明:全栈大数据 » 13.5.3 Web 查询

喜欢 (0)or分享 (0)
发表我的评论
取消评论

表情

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址