hbase的查询scan功能注意点(setStartRow, setStopRow)(

本文介绍了HBase中使用Scan查询时应注意的问题,特别是在ASCII码排序下如何精确地获取指定前缀的数据行。通过实例展示了如何避免误取数据,并提供了一种更精确的查询方式。

hbase的scan查询功能注意项:

Scan scan = new Scan();

scan.setStartRow(“5193:”);

scan.setStopRow(“5194:”);

ResultScanner result = table.getScanner(scan);

for (Result r : result) {

   get it......

}

查找

原本期望:

从下列中

5193:1

5193:2

5194:1

51939:1

51942:1

取出5193:---5194:中的元素(5193开头的元素),也就是(程序所使用的查询方式)

5193:1

5193:2

但是,其实很容易被误取了,实际查询得到的结果如下:

5193:1

5193:2

51942:1

原因是:与hbase内的scan的方式有关,hbase会将自己的元素按照key的ASCII码排序,

其实也就是说,我们会看见排列的方式如下:

51939:1

5193:1

5193:2

51942:1

5194:1

如果hbase使用这种查询方式,是实际工作中,因为id都比较长,其实发生的概率比较小,是一种偶现问题。

取出5193:开头的元素相对比较取巧的写法:

scan.setStartRow("5193:#");

scan.setStopRow("5193::");

ResultScanner result = table.getScanner(scan);

for (Result r : result) {

   get it......

}

原因:ASCII排序中:"#" < "0-9" < ":"

取出来的将是5193:后面跟着数字的元素

<think>嗯...用户这次问的是HBasescan操作细节,看来是在做大数据开发相关的工作。从ta引用的4篇资料来看,用户应该已经查阅过一些文档,但可能缺乏系统性的整理。特别是引用2和引用4里提到的参数调优和过滤器用法,用户可能在实际使用中遇到了性能问题。 注意到用户上次对话是关于快速排序的,这次突然切到HBase,可能是新开启的项目需求。用户引用的参考材料里有些表述不太准确,比如引用1说快照"不包括数据"其实不够严谨——确切说是轻量级元数据快照,但实际会通过硬链接关联数据文件。 需要重梳理几个维度:首先是基础scan语法,从引用3提供的例子看,用户可能需要知道如何过滤列和时间戳;其次是性能优化,引用2提到的caching/batch参数特别关键,生产环境经常要调整;最后是过滤器链的应用,引用4展示的SingleColumnValueExcludeFilter只是其中一种。 用户没提具体场景,但HBase scan常见的痛就是全表扫描效率问题。应该强调避免不带条件的scan,以及如何结合RowKey设计。另外引用材料里出现的"感化于全部hbase"这种错别字需要修正,可能是机器翻译导致的。 得补充但引用材料没提到的是:scan的缓存机制与HDFS数据本地性关联,还有MVCC多版本控制对scan结果的影响。用户如果要做实时查询,可能需要知道setMaxVersions()的用法。 </think>以下是关于HBaseScan操作的详细介绍及使用指南,结合引用资料和最佳实践整理: --- ### 一、Scan操作的核心概念 1. **扫描原理** Scan通过顺序遍历HBase表的行键范围获取数据,本质是**多Region的迭代查询**。数据存储在HDFS的HFile中,Scan操作通过RegionServer访问HFile(引用[1])。 2. **快照机制关联** 快照(snapshot)仅保存表结构元数据,实际数据仍存储在HDFS。Scan操作直接读取HDFS数据文件,不受快照影响(引用[1])。 --- ### 二、Scan操作基础使用 #### 1. 基础语法 ```java Scan scan = new Scan(); scan.addColumn(Bytes.toBytes("列族"), Bytes.toBytes("列名")); // 指定列 scan.setStartRow(Bytes.toBytes("起始行键")); scan.setStopRow(Bytes.toBytes("结束行键")); ResultScanner scanner = table.getScanner(scan); for (Result result : scanner) { // 处理结果 } ``` 输出示例(引用[3]): ``` ROW COLUMN+CELL 2013001 column=name:, timestamp=1365846723665, value=zhangsan 2013001 column=score:Chinese, timestamp=1365848492778, value=100 ``` #### 2. 关键参数配置 | **参数** | **作用** | **推荐** | **注意事项** | |-------------------------|---------------------------------------|--------------------|----------------------------------| | `setCaching(int)` | 每次RPC返回的结果行数 | 100~1000 | 过小增加RPC次数,过大易OOM[^2] | | `setBatch(int)` | 每行返回的列数 | 列数较多时设置 | 避免单次数据传输过大 | | `setCacheBlocks(boolean)` | 是否缓存Block到BlockCache | 实时查询:`true`<br>全表扫描:`false` | MR任务需禁用缓存[^2] | | `setMaxResultSize(long)` | 单次Scan最大数据量限制 | 根据内存设定 | 防OOM关键参数 | --- ### 三、高级过滤技巧 #### 1. 过滤器链(FilterList) ```java FilterList filterList = new FilterList(FilterList.Operator.MUST_PASS_ALL); filterList.addFilter(new SingleColumnValueFilter( Bytes.toBytes("info"), Bytes.toBytes("id"), CompareOperator.EQUAL, Bytes.toBytes("1234") )); filterList.addFilter(new PageFilter(1000)); // 限制返回行数 scan.setFilter(filterList); ``` #### 2. 常用过滤器类型 - **列过滤**:`SingleColumnValueFilter` - **行键前缀过滤**:`PrefixFilter` - **分页控制**:`PageFilter` - **列排除**:`SingleColumnValueExcludeFilter`(返回结果不包含该列)[^4] --- ### 四、性能优化实践 1. **RowKey设计优化** - 避免全表扫描:**合理设计RowKey前缀**(如时间反转`20240520` → `02054025`) - 热问题解决:**Salting策略**(`hash_prefix + rowkey`) 2. **服务端配置** 在`hbase-site.xml`中设置全局Scan缓存: ```xml <property> <name>hbase.client.scanner.caching</name> <value>500</value> <!-- 默认通常为100 --> </property> ``` 3. **避免大范围Scan** ```java // 错误示例:未限定范围的Scan可能导致全表扫描 Scan fullScan = new Scan(); // 正确做法:限定RowKey范围 scan.setStartRow(Bytes.toBytes("user_")); scan.setStopRow(Bytes.toBytes("user_~")); ``` --- ### 五、典型应用场景 1. **数据导出作业**:结合MapReduce批量导出数据(需关闭`setCacheBlocks(false)`) 2. **时间范围查询**:按时间戳`setTimeRange()`检索历史数据 3. **实时监控**:按前缀Scan获取设备最新状态(RowKey含设备ID+时间戳) 4. **数据迁移**:快照克隆表后执行Scan验证数据一致性(引用[1]) --- ### 六、注意事项 1. **内存控制** `setCaching`和`setBatch`需根据**单行数据大小**调整,防止ResultScanner占用过多堆内存。 2. **超时问题** 大Scan需增加超时时间: ```java Configuration conf = HBaseConfiguration.create(); conf.setInt("hbase.client.scanner.timeout.period", 600000); // 10分钟 ``` 3. **结果一致性** 默认Scan使用`Consistency.STRONG`,若需高吞吐可切到`Consistency.TIMELINE`(可能读旧数据)。 > **关键实践**:生产环境应在测试集群验证Scan参数,避免大Scan拖垮RegionServer[^2]。 ---
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值