基于Lua的TTLB内Servlet批量查询HBase数据方法

文档序号:8258737阅读:555来源:国知局
基于Lua的TTLB内Servlet批量查询HBase数据方法
【技术领域】
[0001]本发明涉及一种数据处理方法,尤其涉及一种基于Lua的TTLB内Servlet批量查询HBase数据方法。
【背景技术】
[0002]HBase是一个支持非结构化存储的高可靠性、高性能、可伸缩的开源数据库。采用Servlet访问HBase可能发生两个线程同时访问同一资源,造成数据不一致,导致线程不安全。Servlet规范、Java教材、Internet和相关文献指出:现有解决线程不安全的方法主要有:实现SingleThreadModel接口、同步共享数据、避免对象实例、增加延时。
[0003]1、实现 SingleThreadModel 接口
[0004]实现了 SingleThreadModel接口,Servlet容器保证只有一个线程servlet实例在运行,而其它请求排队等待。
[0005]2、同步共享数据
[0006]synchronized防止异步调用,每次只有一个线程访问同步代码块。
[0007]3、避免对象实例
[0008]全局变量或者共享变量造成了线程不安全;而局部变量保证了线程安全。
[0009]4、增加延时
[0010]采用sleep函数增加延时,使得只有一个线程修改全局变量或者共享变量,而其它线程处于阻塞状态:还没有将修改的数据刷新到内存。
[0011]以上四种方法虽能设计出线程安全的Servlet,但存在系统开销大、降低系统并发处理性能、难确定阻塞时间。对于实现SingleThreadModel接口方法,Servlet为每个请求创建一个单独Servlet实例,大量Servlet实例将引起系统大量的开销。对于避免使用实例对象方法,采用局部变量将增大每个线程的私有栈。对于同步共享数据方法,每一时刻只允许一个线程执行同步代码,其它线程处于同步阻塞状态,这将降低系统的并发处理性能。对于增加延时方法,如果延时太短,当前线程还没有处理完,而处于阻塞状态的线程因睡眠时间结束开始运行,可能造成线程不安全;如果延时过长(如超过10秒),则根据国际3/5/10原则,用户很难接受长时间等待,增加延时方法很难确定:经过多长延时线程才安全又让等待在用户可接受范围内?
[0012]HBase面向海量数据存储,当大规模用户采用Servlet访问HBase时,以上四种方法的问题在Servlet访问HBase中更为突出。不仅存在系统开销大、降低系统并发处理性能、难确定阻塞时间,而且还会引发更严重的问题:根据HBase规范,HTable.get (Get)和HTable.put (Put)方法在多线程环境下也是不安全的。一般对HBase表记录的查询和存储,需分开处理。

【发明内容】

[0013]本发明旨在提供一种基于Lua的TTLB内Tomcat批量查询HBase数据方法,通过Lua表缓存TTLB内查询请求,该方法确保了 Servlet并发查询HBase的线程安全,允许Tomcat能接纳更大规模的用户访问,还减少了 HBase集群网络I/O。
[0014]为达到上述目的,本发明是采用以下技术方案实现的:
[0015]本发明公开的基于Lua的TTLB内Servlet批量查询HBase表数据方法,包括以下步骤:
[0016]步骤1、建立 Wrapper 类、LuaScript 函数和 ReadHBase 类,
[0017]所述Wrapper类用于将查询请求缓存在Lua表中,以及从Lua表中快速检索查询结果;
[0018]所述LuaScript函数用于打包TTLB内所有线程并发查询请求,调用ReadHBase类的Java API完成批量查询HBase表记录,解包返回结果并生成每个线程的返回结果;
[0019]所述ReadHBase类用于解包从LuaScript传过来的参数,调用Java API函数HTable.get (List〈Get>),打包该get函数的返回结果;
[0020]步骤2、获取Wrapper类对象实例:包括获取欲查询HBase表和欲查询表行,产生查询请求标识;
[0021]步骤3、将欲查询HBase表、欲查询HBase表行和查询请求标识缓存在Lua表Readqueue 中;
[0022]步骤4、通过LuaScript打包TTLB内批量查询请求;
[0023]步骤5、通过ReadHBase解包TTLB内批量查询请求;
[0024]步骤6、调用 Java API 函数 HTable.get (List〈Get>);
[0025]步骤7、通过ReadHBase打包批量查询的结果;
[0026]步骤8、通过LuaScript解包批量查询的结果;
[0027]步骤9、生成线程调用结果;
[0028]步骤10、获取查询结果。
[0029]进一步的,在步骤3结束时,检测布尔型变量startscheduler,当startscheduler为false时,将startscheduler赋值为true并进入步骤4,在步骤9结束时将startscheduler 赋值为 false ;当 startscheduler 为 true 时,直接转到步骤 10。
[0030]进一步的,在步骤10完成后,还包括检测查询是否完成,当检测查询完成为真时,清空检测查询,然后结束;当检测查询完成为假时,直接结束。
[0031]优选的,在步骤2中,通过查询请求标识作为下标索引快速定位Lua表中的嵌套表元素。
[0032]优选的,在步骤4中,所述打包是将欲查询HBase表行关键字打包成字符串;
[0033]在步骤5中,所述解包是将所述字符串解包成HBase表行关键字。
[0034]本发明针对HBase表的查询。HTable.get (Get)是单条记录查询,每次查询都需要HBase集群网络一次I/O ;HTable.get (List〈Get>)支持批量查询,与单条查询相比较,批量查询的优势在于:完成一次批量查询只需要一次HBase集群网络1/0,节省了 HBase集群网络带宽,因此本发明针对HBase批量查询。
[0035]要采用HTable.get (List〈Get>)实现批量查询HBase数据,需缓存Servlet批量查询请求。通常方法是通过vector缓存批量查询请求实现HBase表查询,其原理(要点)如下:
[0036]1、将HBase表的列族和列成员(标签)封装为事件类;
[0037]2、将Tomcat批量查询请求缓存在vector中;
[0038]3、注册查询事件;
[0039]4、查询HBase表完成,触发查询事件。
[0040]利用vector缓存查询请求存在以下3个问题:首先,对于每个HBase表都要设计一个事件类,一个事件类不适用于所有HBase表;其次,HBase表最大可以支持上百万列数据的存储,事件类的数据成员数量非常庞大,运行这种事件类要占用很大内存,但很多记录数据又是稀疏的,将造成内存大量浪费;最后,在批量查询结果中,很难检测出HBase表没有欲查询记录的空返回。Lua表支持key-value键值对存储、表中元素类型异构、表中嵌套表,可以采用Lua表缓存TTLB内Servlet批量查询请求。
[0041]本发明的有益效果如下:
[0042](I)采用Lua表缓存TTLB内查询请求,保证了 Servlet的多线程安全。
[0043](2)采用TTLB内批量查询,既在用户可接受的请求响应时间内返回查询结果,又减少了 HBase集群网络I/O。
[0044](3)通过打包解包批量查询请求和查询结果,能够查询任意HBase表记录。
[0045](4) Lua表支持字符串作为嵌套表元素索引,能够快速检索查询结果。
[0046](5)单实例类和仅仅处理HBase表有数据的列,减少了系统内存开销,使得Tomcat能接纳更大规模的用户访问。
【附图说明】
[0047]图1为本发明的处理流程图。
【具体实施方式】
[0048]为了使本发明的目的、技术方案及优点更加清楚明白,以下结合附图,对本发明进行进一步详细说明。
[0049]如图1所示,本发明公开的基于Lua的TTLB内Servlet批量查询HBase表数据方法,包括以下步骤:
[0050]步骤1、建立 Wrapper 类、LuaScript 函数和 ReadHBase 类,
[0051]所述Wrapper类用于将查询请求缓存在Lua表中,以及从Lua表中快速检索查询结果;
[0052]所述LuaScript函数用于打包TTLB内所有线程并发查询请求,调用ReadHBase类的Java API完成批量查询HBase表记录,解包返回结果并生成每个线程的返回结果;
[0053]所述ReadHBase类用于解包从LuaScript传过来的参数,调用Java API函数HTable.get (List〈Get>),打包该get函数的返回结果;
[0054]步骤2、获取Wrapper类对象实例:包括获取欲查询HBase表tabIename和欲查询表行rowkey,产生查询请求标识uui ;由于Lua表支持key-value键值对缓存,所以可通过uuid作为下标索引能快速定位Lua表中的嵌套表元素;
[0055]步骤3、将欲查询HBase表tabIename、欲查询HBase表行rowkey和查询请求标识uui 缓存在 Lua 表 Readqueue 中;检测布尔型变量 startscheduler,当 startscheduler 为false时,将startscheduler赋值为true并进入步骤4,在步骤9结束时将startscheduler赋值为false ;当startscheduler为true时,直接转到步骤10 ;
[0056]步骤4、通过LuaScript打包TTLB内批量查询请求;
[0057]步骤5、通过ReadHBase解包TTLB内批量查询请求;
[0058]步骤6、调用 Java API 函数 HTable.get (List〈Get>);
[0059]步骤7、通过ReadHBase打包批量查询的结果;
[0060]步骤8、通过LuaScript解包批量查询的结果;
[0061]步骤9、生成线程调用结果;
[0062]步骤10、获取查询结果:检测查询是否完成,当检测查询完成为真时,清空检测查询,然后结束;当检测查询完成为假时,直接结束。
[0063]在LuaScript中,打包TTLB内所有线程并发查询请求,调用ReadHBase类的JavaAPI完成批量查询HBase表记录,解包返回结果并生成每个线程的返回结果。在ReadHBase类中,解包从LuaScript传过来的参数,调用Java API函数HTable.get (List〈Get>),打包该get函数的返回结果。在LuaScript中对欲查询HBase表行关键字打包成字符串,在ReadHBase类中将该字符串解包成HBase表行关键字;同时,在ReadHBase类中对get (List<Get>)的返回结果打包成字符串,在LuaScript中将返回结果解包,通过这种打包解包批量查询请求和批量查询结果,能实现对任意HBase表的批量查询,增强了本发明的通用性和实用性。
[0064]本发明所涉及的类和函数及实施方式如下:
[0065]一'Wrapper 类
[0066]初始化ReadHBase 类,通过 Luajava 插件调用 LuaScript 的 Lua API 向 Servlet提供服务:setReadParameter将查询请求缓存到LuaScript的Readqueue表中;getResult从Readqueue中快速查找查询结果。另外,由TTLB内的第一个线程调用schedule完成批量查询(其它线程返回,等待或者查找查询结果)。
[0067]Wrapper类的数据成员:
[0068]K private Boolean startscheduler ;//是否已经启动批量查询请求执行线程
[0069]private static W
当前第1页1 2 3 
网友询问留言 已有0条留言
  • 还没有人留言评论。精彩留言会获得点赞!
1