- 浏览: 37305 次
- 来自: 杭州
最新评论
HBase通过租约来控制每个scanner的操作时间。
1. 租约线程初始化:
HRegionServer的run方法会调用一次preRegistrationInitialization方法,再调用initializeThreads时,会new lease
这里默认的过期时间是60s:
默认的lease线程周期性检查时间是10s
最终在HRegionServer的startServiceThreads启动lease线程。
2. 租约的创建
在openScanner和addRowLock时会创建租约
openScanner时,对于一个新的scanner会creatLease.
最终将lease以scannerId加入DelayQueue中,
3. 租约的失效
租约线程每10s会检查一次leaseQueue,leaseQueue是一个java.util.concurrent.DelayQueue, 是一个使用优先队列(PriorityQueue)实现的BlockingQueue,优先队列的以指定的时间做为比较的基准值。
poll方法会取出到期的lease并执行其Listener的过期方法。
过期方法中会将此scanner从内存中删除并将scanner关闭。
4. 常见错误
以上常见的错误是因为leaser失效,而client可能没有关闭scanner,使用老的scannerid过来next时,会有一个重新生成lease的过程,过程如下:
1.
在next方法中,先执行一次删除lease的操作,看看lease能不能正常删除
如果这个lease是存在的,自然可以正常删除,一量lease已经失效,则会抛LeaseException,
正常情况下,lease被remove之后,为了一个正常的next能继续运行下去,那么在最后会再增加一个lease,leasename还是原来的scannerid
针对以上错误
1.检查hbase.rpc.timeout(默认60000ms) 是否大于等于hbase.regionserver.lease.period(默认为60000ms), 大于等于才是对的。
2. 检查是否有scanner没有关闭。
1. 租约线程初始化:
HRegionServer的run方法会调用一次preRegistrationInitialization方法,再调用initializeThreads时,会new lease
this.leases = new Leases((int) conf.getLong( HConstants.HBASE_REGIONSERVER_LEASE_PERIOD_KEY, HConstants.DEFAULT_HBASE_REGIONSERVER_LEASE_PERIOD), this.threadWakeFrequency);
这里默认的过期时间是60s:
public static String HBASE_REGIONSERVER_LEASE_PERIOD_KEY = "hbase.regionserver.lease.period"; public static long DEFAULT_HBASE_REGIONSERVER_LEASE_PERIOD = 60000;
默认的lease线程周期性检查时间是10s
/** Parameter name for how often threads should wake up */ public static final String THREAD_WAKE_FREQUENCY = "hbase.server.thread.wakefrequency"; /** Default value for thread wake frequency */ public static final int DEFAULT_THREAD_WAKE_FREQUENCY = 10 * 1000;
最终在HRegionServer的startServiceThreads启动lease线程。
this.leases.setName(n + ".leaseChecker"); this.leases.start();
2. 租约的创建
在openScanner和addRowLock时会创建租约
openScanner时,对于一个新的scanner会creatLease.
protected long addScanner(RegionScanner s) throws LeaseStillHeldException { long scannerId = -1L; while (true) { scannerId = rand.nextLong(); if (scannerId == -1) continue; String scannerName = String.valueOf(scannerId); RegionScanner existing = scanners.putIfAbsent(scannerName, s); if (existing == null) { this.leases.createLease(scannerName, new ScannerListener(scannerName)); break; } } return scannerId; }
最终将lease以scannerId加入DelayQueue中,
public void addLease(final Lease lease) throws LeaseStillHeldException { if (this.stopRequested) { return; } lease.setExpirationTime(System.currentTimeMillis() + this.leasePeriod); synchronized (leaseQueue) { if (leases.containsKey(lease.getLeaseName())) { throw new LeaseStillHeldException(lease.getLeaseName()); } leases.put(lease.getLeaseName(), lease); leaseQueue.add(lease); } }
3. 租约的失效
租约线程每10s会检查一次leaseQueue,leaseQueue是一个java.util.concurrent.DelayQueue, 是一个使用优先队列(PriorityQueue)实现的BlockingQueue,优先队列的以指定的时间做为比较的基准值。
public void run() { while (!stopRequested || (stopRequested && leaseQueue.size() > 0) ) { Lease lease = null; try { lease = leaseQueue.poll(leaseCheckFrequency, TimeUnit.MILLISECONDS); } catch (InterruptedException e) { continue; } catch (ConcurrentModificationException e) { continue; } catch (Throwable e) { LOG.fatal("Unexpected exception killed leases thread", e); break; } if (lease == null) { continue; } // A lease expired. Run the expired code before removing from queue // since its presence in queue is used to see if lease exists still. if (lease.getListener() == null) { LOG.error("lease listener is null for lease " + lease.getLeaseName()); } else { lease.getListener().leaseExpired(); } synchronized (leaseQueue) { leases.remove(lease.getLeaseName()); } } close(); }
poll方法会取出到期的lease并执行其Listener的过期方法。
public void leaseExpired() { RegionScanner s = scanners.remove(this.scannerName); if (s != null) { LOG.info("Scanner " + this.scannerName + " lease expired on region " + s.getRegionInfo().getRegionNameAsString()); try { HRegion region = getRegion(s.getRegionInfo().getRegionName()); if (region != null && region.getCoprocessorHost() != null) { region.getCoprocessorHost().preScannerClose(s); } s.close(); if (region != null && region.getCoprocessorHost() != null) { region.getCoprocessorHost().postScannerClose(s); } } catch (IOException e) { LOG.error("Closing scanner for " + s.getRegionInfo().getRegionNameAsString(), e); } } else { LOG.info("Scanner " + this.scannerName + " lease expired"); } }
过期方法中会将此scanner从内存中删除并将scanner关闭。
4. 常见错误
2013-11-06 16:16:38,684 ERROR org.apache.hadoop.hbase.regionserver.HRegionServer: org.apache.hadoop.hbase.regionserver.LeaseException: lease '-2408052186420749395' does not exist at org.apache.hadoop.hbase.regionserver.Leases.removeLease(Leases.java:231) at org.apache.hadoop.hbase.regionserver.HRegionServer.next(HRegionServer.java:2783) at sun.reflect.GeneratedMethodAccessor55.invoke(Unknown Source) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) at java.lang.reflect.Method.invoke(Method.java:597)
以上常见的错误是因为leaser失效,而client可能没有关闭scanner,使用老的scannerid过来next时,会有一个重新生成lease的过程,过程如下:
1.
lease = this.leases.removeLease(scannerName);
在next方法中,先执行一次删除lease的操作,看看lease能不能正常删除
Lease removeLease(final String leaseName) throws LeaseException { Lease lease = null; synchronized (leaseQueue) { lease = leases.remove(leaseName); if (lease == null) { throw new LeaseException("lease '" + leaseName + "' does not exist"); } leaseQueue.remove(lease); } return lease; }
如果这个lease是存在的,自然可以正常删除,一量lease已经失效,则会抛LeaseException,
正常情况下,lease被remove之后,为了一个正常的next能继续运行下去,那么在最后会再增加一个lease,leasename还是原来的scannerid
if (this.scanners.containsKey(scannerName)) { if (lease != null) this.leases.addLease(lease); }
针对以上错误
1.检查hbase.rpc.timeout(默认60000ms) 是否大于等于hbase.regionserver.lease.period(默认为60000ms), 大于等于才是对的。
2. 检查是否有scanner没有关闭。
发表评论
-
HBase HFile和Hlog的cleaner执行流程和配置项
2013-06-09 14:50 5857HFile和Hlog是HBase中两大文件存在格式,HFile ... -
HLog代码分析及与HBase replication延时
2013-02-19 19:51 2765在分享replication时,有同事提出replicatio ... -
HBase BlockCache 代码分析
2013-02-04 22:08 18361. Cache 读写 调用逻辑: hmaster.handl ... -
HBase replication 代码分析
2013-01-28 17:23 2966随着HBase的大规模应用,HBase的容灾显得特别的重要。 ... -
HBase大集群
2013-01-28 14:02 1229为什么HBase没有大集群? 因为如果一个HBase集群很大, ... -
HBase MVCC基本原理
2012-11-28 16:21 3262HBase MVCC(Multi Version Consi ... -
flush后split和compact后split
2012-10-11 17:51 1585什么时候split? 当某store所有文件总大小大于某个值时 ... -
HBase rpc调用
2012-10-10 18:47 2541HBase rpc 0.94中 例如在client put ... -
HBase keyvalue大小导致OOM
2012-09-27 12:11 1467在HBase上传时,会通过配置参数hbase.client.k ... -
HBase什么时候做minor major compact
2012-10-09 18:11 3795我们都知道compact分为两类,一类叫Minor compa ... -
HBase Put及flush
2012-09-21 10:50 17831. Put及flush a. ...
相关推荐
在HBase Shell中,可以创建表,如创建名为'teacher'的表,包含一个列族'username',设置版本数为5。创建表的命令是`create 'teacher',{NAME=>'username',VERSIONS=>5}`。之后,使用`put`命令向表中插入数据,例如为...
在Java中操作HBase是一种常见的任务,特别是在大数据处理和存储的场景中。HBase是一个分布式的、基于列族的NoSQL数据库,它构建在Hadoop之上,提供了高性能、低延迟的数据存储和访问能力。本教程将详细介绍如何使用...
本文将深入探讨如何进行HBase的安装、节点的添加与移除,以及如何解决常见的问题。 首先,Hadoop是HBase的基础,因此在安装HBase之前,必须先确保Hadoop环境已经正确配置并稳定运行。对于`hadoop-2.5.2-hbase-...
Hbase应用开发实验报告及代码;(1) 列出HBase所有的表的相关信息,例如表名、创建时间等;(2) 在终端打印出指定的表的所有记录数据;(3) 向已经创建好的表添加和删除指定的列族或列;(4) 清空指定的表的所有...
这可以通过修改`hbase-site.xml`文件中的`hbase.master.info.port`和`hbase.master.info.address`属性来实现,指定多个Master节点。例如: ```xml <name>hbase.master.info.address <value>master1:60010,...
### hbase+solr创建二级索引完整操作 #### 一、概述 本文档详细介绍了如何利用HBase和Solr创建二级索引的过程。通过整合HBase与Solr的优势,可以构建高性能的数据存储与检索系统。HBase作为分布式列族数据库,能够...
通过HbaseTemplate,我们可以执行常见的CRUD(创建、读取、更新和删除)操作以及更复杂的查询。 1. **HbaseTemplate的初始化**:在使用HbaseTemplate之前,我们需要在Spring配置文件中配置HBase的相关连接信息,如...
1. **未提前创建分区**:HBase在创建表时默认只有一个Region,如果所有数据都集中在这个单一的Region中,那么所有的读写请求都将被路由到同一个RegionServer上,从而导致热点问题。 2. **RowKey设计不合理**:如果...
新建一个 Java 项目,然后添加相关的 jar 包,包括 hadoop-core-0.20.204.0.jar、hbase-0.90.4.jar、hbase-0.90.4-tests.jar 以及 Hbase 资源包中 lib 目录下的所有 jar 包。 ### 2. 主要程序 下面是一个 Java ...
- 涉及了在HBase中进行模式设计时需要考虑的要素,包括列族的创建、行键设计、版本数量控制等。 - 探讨了支持的数据类型和使用第二索引以及替代查询路径。 - 讨论了设计时的一些限制和用例,以及对操作和性能产生...
假设有一个不知道是干什么表:) 表里需要存入人员和其相对应的部门信息 HBaseAdmin admin = new HBaseAdmin(configuration); List<Put> putuser = new ArrayList();
HBase是一种分布式、基于列族的NoSQL数据库,由Apache软件基金会开发并维护,是Hadoop生态系统中的重要组件。这份“HBase官方文档中文版”提供了全面深入的HBase知识,帮助用户理解和掌握如何在大数据场景下有效地...
在本文中,我们将详细讲解Hbase的安装过程以及基本操作,特别针对在Linux环境下使用清华大学镜像进行下载的情况。Hbase是一个分布式的、面向列的数据库,常用于大数据存储,是Apache Hadoop生态系统的一部分。以下是...
在Python中创建HBase表,需要指定表名、列族以及可能的初始配置。例如,使用`happybase`创建一个名为`my_table`,列族为`cf1`的表: ```python import happybase connection = happybase.Connection('localhost') ...
例如,在Java中,我们可以使用HBase的Admin API创建表,然后使用Put对象添加数据。在导入过程中,需要将JSON对象解析并映射到HBase的行键和列族/列限定符上。 总结来说,从MySQL导入数据到HBase的过程主要包括:1)...
在Java编程环境中,操作HBase并将其数据写入HDFS(Hadoop Distributed File System)是一项常见的任务,特别是在大数据处理和分析的场景下。本篇将详细介绍如何使用Java API实现这一功能,以及涉及到的关键技术和...
在本实验中,我们主要聚焦于HBase,这是一个基于谷歌Bigtable设计的开源NoSQL数据库,广泛应用于大数据存储场景。实验旨在让参与者熟练掌握HBase的Shell操作,包括创建表、输入数据以及进行特定查询。以下是详细步骤...
15. 创建和开发 HBase 15.1. HBase 仓库 15.2. IDEs 15.3. 创建 HBase 12-5-30 HBase 官方文档 3/81 abloz.com/hbase/book.htm 15.4. Publishing a new version of hbase.apache.org 15.5. 测试 15.6. Maven Build ...
HBase是一种分布式的、面向列的数据库管理系统,它利用Hadoop HDFS作为其文件存储系统,使用Hadoop MapReduce来处理HBase中的海量数据,并且使用Zookeeper作为其协同服务。HBase以表的形式存储数据,表由行和列组成...