1.HTable 参数设置
- Scanner Caching hbase.client.scanner.caching 配置项可以设置 HBase scanner 一次从服务端抓取的 数据条数,默认情况下一次一条。通过将其设置成一个合理的值,可以减少 scan 过程中 next() 的时间开销,代价是 scanner 需要通过客户端的内存来维持这些被 cache 的行记录。
有三个地方可以进行配置:
1)在 HBase 的 conf 配置文件中进行配置;
2)通过调用 HTable.setScannerCaching(int scannerCaching)进行配置;
3)通过调用 scan.setCaching(int caching)进行配置。
- Scan Attribute Selection scan 时指定需要的 Column Family,可以减少网络传输数据量,否则默认 scan 操作会返 回整行所有 Column Family 的数据
Close ResultScanner:
通过 scan 取完数据后,记得要关闭 ResultScanner,否则 RegionServer 可能会出现 问题(对应的 Server 资源无法释放)。
2.批量读
通过调用 HTable.get(Get)方法可以根据一个指定的 row key 获取一行记录,同样 HBase 提供了另一个方法:通过调用 HTable.get(List)方法可以根据一个指定的 row key 列表,批量获取多行记录,这样做的好处是批量执行,只需要一次网络 I/O 开销,这对 于对数据实时性要求高而且网络传输 RTT 高的情景下可能带来明显的性能提升。
3.客户端缓存查询结果
对于频繁查询 HBase 的应用场景,可以考虑在应用程序中做缓存,当有新的查询请求 时,首先在缓存中查找,如果存在则直接返回,不再查询 HBase;否则对 HBase 发起读请 求查询,然后在应用程序中将查询结果缓存起来。至于缓存的替换策略,可以考虑 LRU(least recently used 最近最少使用的)等常用的策略。 client -通过网络请求->regionserver(memstore|blockcache) 优化为: client (memcached|redis)-通过网络请求->regionserver(memstore|blockcache)
4.服务器端 Blockcache
HBase 上 Regionserver 的内存分为两个部分,一部分作为 Memstore,主要用来写; 另外一部分作为 BlockCache,主要用于读。 写请求会先写入 Memstore,Regionserver 会给每个 region 提供一个 Memstore, 当 Memstore 满 64MB 以后,会启动 flush 刷新到磁盘。当 Memstore 的总大小超过限 制时(heapsize * hbase.regionserver.global.memstore.upperLimit * 0.9),会强行启 动 flush 进程,从最大的 Memstore 开始 flush 直到低于限制。 读请求先到 Memstore 中查数据,查不到就到 BlockCache 中查,再查不到就会到磁 盘上读,并把读的结果放入 BlockCache。由于 BlockCache 采用的是 LRU 策略,因此 BlockCache 达到上限(heapsize * hfile.block.cache.size * 0.85)后,会启动淘汰机制,淘 汰掉最老的一批数据。 一个 Regionserver 上有一个 BlockCache 和 N 个 Memstore,它们的大小之和不能大于等于 heapsize * 0.8,否则 HBase 不能启动。默认 BlockCache 为 0.2,而 Memstore 为 0.4 。 对 于 注 重 读 响 应 时 间 的 系 统 , 可 以 将 BlockCache 设 大 些 , 比 如 设 置 BlockCache=0.4,Memstore=0.39,以加大缓存的命中率