`
brianf
  • 浏览: 37302 次
  • 来自: 杭州
社区版块
存档分类
最新评论

HBase中Lease创建、失效、及常见问题

阅读更多
HBase通过租约来控制每个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没有关闭。



分享到:
评论

相关推荐

    hadoop中安装hbase及创建表等.docx

    在HBase Shell中,可以创建表,如创建名为'teacher'的表,包含一个列族'username',设置版本数为5。创建表的命令是`create 'teacher',{NAME=>'username',VERSIONS=>5}`。之后,使用`put`命令向表中插入数据,例如为...

    java操作Hbase之实现表的创建删除源码

    在Java中操作HBase是一种常见的任务,特别是在大数据处理和存储的场景中。HBase是一个分布式的、基于列族的NoSQL数据库,它构建在Hadoop之上,提供了高性能、低延迟的数据存储和访问能力。本教程将详细介绍如何使用...

    hbase安装,节点添加,移除,常见问题解决

    本文将深入探讨如何进行HBase的安装、节点的添加与移除,以及如何解决常见的问题。 首先,Hadoop是HBase的基础,因此在安装HBase之前,必须先确保Hadoop环境已经正确配置并稳定运行。对于`hadoop-2.5.2-hbase-...

    Hbase应用开发实验报告及代码

    Hbase应用开发实验报告及代码;(1) 列出HBase所有的表的相关信息,例如表名、创建时间等;(2) 在终端打印出指定的表的所有记录数据;(3) 向已经创建好的表添加和删除指定的列族或列;(4) 清空指定的表的所有...

    java大数据作业_3HBase

    这可以通过修改`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与Solr的优势,可以构建高性能的数据存储与检索系统。HBase作为分布式列族数据库,能够...

    HbaseTemplate 操作hbase

    通过HbaseTemplate,我们可以执行常见的CRUD(创建、读取、更新和删除)操作以及更复杂的查询。 1. **HbaseTemplate的初始化**:在使用HbaseTemplate之前,我们需要在Spring配置文件中配置HBase的相关连接信息,如...

    HBase常见热点问题及几种解决方案.docx

    1. **未提前创建分区**:HBase在创建表时默认只有一个Region,如果所有数据都集中在这个单一的Region中,那么所有的读写请求都将被路由到同一个RegionServer上,从而导致热点问题。 2. **RowKey设计不合理**:如果...

    Java操作Hbase进行建表、删表以及对数据进行增删改查

    新建一个 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 官方中文文档

    - 涉及了在HBase中进行模式设计时需要考虑的要素,包括列族的创建、行键设计、版本数量控制等。 - 探讨了支持的数据类型和使用第二索引以及替代查询路径。 - 讨论了设计时的一些限制和用例,以及对操作和性能产生...

    hbase-0.90.2中创建表、插入数据,更新数据,删除数据

    假设有一个不知道是干什么表:) 表里需要存入人员和其相对应的部门信息 HBaseAdmin admin = new HBaseAdmin(configuration); List<Put> putuser = new ArrayList();

    HBase官方文档中文版-HBase手册中文版

    HBase是一种分布式、基于列族的NoSQL数据库,由Apache软件基金会开发并维护,是Hadoop生态系统中的重要组件。这份“HBase官方文档中文版”提供了全面深入的HBase知识,帮助用户理解和掌握如何在大数据场景下有效地...

    Hbase的安装过程及基本操作

    在本文中,我们将详细讲解Hbase的安装过程以及基本操作,特别针对在Linux环境下使用清华大学镜像进行下载的情况。Hbase是一个分布式的、面向列的数据库,常用于大数据存储,是Apache Hadoop生态系统的一部分。以下是...

    Python-HBase中文参考指南

    在Python中创建HBase表,需要指定表名、列族以及可能的初始配置。例如,使用`happybase`创建一个名为`my_table`,列族为`cf1`的表: ```python import happybase connection = happybase.Connection('localhost') ...

    mysql中数据经处理导入到hbase中

    例如,在Java中,我们可以使用HBase的Admin API创建表,然后使用Put对象添加数据。在导入过程中,需要将JSON对象解析并映射到HBase的行键和列族/列限定符上。 总结来说,从MySQL导入数据到HBase的过程主要包括:1)...

    java操作Hbase之从Hbase中读取数据写入hdfs中源码

    在Java编程环境中,操作HBase并将其数据写入HDFS(Hadoop Distributed File System)是一项常见的任务,特别是在大数据处理和分析的场景下。本篇将详细介绍如何使用Java API实现这一功能,以及涉及到的关键技术和...

    Hbase实验报告.pdf

    在本实验中,我们主要聚焦于HBase,这是一个基于谷歌Bigtable设计的开源NoSQL数据库,广泛应用于大数据存储场景。实验旨在让参与者熟练掌握HBase的Shell操作,包括创建表、输入数据以及进行特定查询。以下是详细步骤...

    Hbase中文文档

    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企业应用开发】工作中自己总结的Hbase文档,非常全面!

    HBase是一种分布式的、面向列的数据库管理系统,它利用Hadoop HDFS作为其文件存储系统,使用Hadoop MapReduce来处理HBase中的海量数据,并且使用Zookeeper作为其协同服务。HBase以表的形式存储数据,表由行和列组成...

Global site tag (gtag.js) - Google Analytics