利用DataImportHandler建索引时一直无法完成
问题研究
项目中需要利用DataImportHandler从hive中sync数据到solr。发现有时候hive sql已经执行完几个小时了,sync任务还没有完成,貌似哪里卡住了。重启solr后重新sync又成功了,所以之前虽然遇到很多次这个问题也没有去深究。今天又出现了同样的问题,决定花点时间研究下到底是什么原因造成的。
利用jstack dump了几遍线程栈,发现很多个线程都卡在同一个地方,at java.net.SocketInputStream.socketRead0(Native Method),显然这些进程都在等待jdbc从hive中读取数据。初步判断可能是网络原因导致网络中断,TcpIp没有侦测到连接已经失败,我们在data-config.xml中配置hive数据源的时候又没有设置超时时间,导致线程一直傻傻等待接收数据sync任务一直无法完成,也没有任何异常抛出。之所以问题出现的这么频繁应该是因为我们的hive服务器设在美国,而solr服务器在国内。看来加上超时时间是很有必要的,难怪很多文章都提到为了不让比较慢的客户端拖垮服务器程序的性能必须加上超时时间。这些无限等待的线程都是在做无用功啊,又浪费服务器资源,设置超时时间后就会在超时时间到达时抛出timeout异常,退出线程。
"Thread-32" prio= tid=0x00007f077c052800 nid=0x3b04 runnable [0x00007f06fec7d000]
java.lang.Thread.State: RUNNABLE
at java.net.SocketInputStream.socketRead0(Native Method)
at java.net.SocketInputStream.read(SocketInputStream.java:)
at java.net.SocketInputStream.read(SocketInputStream.java:)
at java.io.BufferedInputStream.fill(BufferedInputStream.java:)
at java.io.BufferedInputStream.read1(BufferedInputStream.java:)
at java.io.BufferedInputStream.read(BufferedInputStream.java:)
- locked <0x00000000d8ccf078> (a java.io.BufferedInputStream)
at org.apache.thrift.transport.TIOStreamTransport.read(TIOStreamTransport.java:)
at org.apache.thrift.transport.TTransport.readAll(TTransport.java:)
at org.apache.thrift.transport.TSaslTransport.readLength(TSaslTransport.java:)
at org.apache.thrift.transport.TSaslTransport.readFrame(TSaslTransport.java:)
at org.apache.thrift.transport.TSaslTransport.read(TSaslTransport.java:)
at org.apache.thrift.transport.TSaslClientTransport.read(TSaslClientTransport.java:)
at org.apache.thrift.transport.TTransport.readAll(TTransport.java:)
at org.apache.thrift.protocol.TBinaryProtocol.readAll(TBinaryProtocol.java:)
at org.apache.thrift.protocol.TBinaryProtocol.readI32(TBinaryProtocol.java:)
at org.apache.thrift.protocol.TBinaryProtocol.readMessageBegin(TBinaryProtocol.java:)
at org.apache.thrift.TServiceClient.receiveBase(TServiceClient.java:)
at org.apache.hive.service.cli.thrift.TCLIService$Client.recv_ExecuteStatement(TCLIService.java:)
at org.apache.hive.service.cli.thrift.TCLIService$Client.ExecuteStatement(TCLIService.java:)
at org.apache.hive.jdbc.HiveStatement.execute(HiveStatement.java:)
at org.apache.solr.handler.dataimport.JdbcDataSource$ResultSetIterator.<init>(JdbcDataSource.java:)
at org.apache.solr.handler.dataimport.JdbcDataSource.getData(JdbcDataSource.java:)
at org.apache.solr.handler.dataimport.JdbcDataSource.getData(JdbcDataSource.java:)
at org.apache.solr.handler.dataimport.SqlEntityProcessor.initQuery(SqlEntityProcessor.java:)
at org.apache.solr.handler.dataimport.SqlEntityProcessor.nextRow(SqlEntityProcessor.java:)
at org.apache.solr.handler.dataimport.EntityProcessorWrapper.nextRow(EntityProcessorWrapper.java:)
at org.apache.solr.handler.dataimport.DocBuilder.buildDocument(DocBuilder.java:)
at org.apache.solr.handler.dataimport.DocBuilder.buildDocument(DocBuilder.java:)
at org.apache.solr.handler.dataimport.DocBuilder.doDelta(DocBuilder.java:)
at org.apache.solr.handler.dataimport.DocBuilder.execute(DocBuilder.java:)
at org.apache.solr.handler.dataimport.DataImporter.doDeltaImport(DataImporter.java:)
at org.apache.solr.handler.dataimport.DataImporter.runCmd(DataImporter.java:)
扩展阅读
遇到这个问题以后想了解下jdbc的超时机制,所以google了一把,看到两篇文档对我很有帮助,文档链接在文章的最后。一篇是关于jdbc超时机制的,另一篇是关于socket的keepalive。
总结一下jdbc相关的timeout有以下几种:
Transaction Timeout,用来限制一个事务的执行时间。
Statement Timeout,限制一条查询的执行时间,设置方法:java.sql.Statement.setQueryTimeout(int timeout)。
Socket Timeout,又包含connection timeout和read/write timeout,限制建立连接的时间和等待读取或者等待写数据的时间。
OS level socket Timeout,这个其实是Linux系统环境下的Socket的KeepAlive机制。java的Socket类里有个setKeepAlive(boolean on)方法可能就是用来设置KeepAlive机制是否生效。
KeepAlive的作用:
之前一直不明白为什么很多系统都要自己实现一个心跳机制,比如微信,导致信令风暴啊什么的很多问题。看完KeepAlive的文章后才有这样的感觉,原来如此啊!
1,检查连接是否活着
KeepAlive可以侦测到一些原因造成的失效的socket连接,比如内核错误或者连接的进程强制退出,还比如虽然连接的机器和进程都正常,但是网络已经出现故障。这些情况下,TCP是不知道连接已经失效的。
考虑下面这种情况,A发送SYN给B发起连接,B回复一个ACK/SYN,A又发送ACK到B,完成TCP的三次握手,连接建立成功。这个时候如果B突然崩溃,没有发送任何消息给A告知其已经崩溃,A就会一直以为B还活着。如果A正在等待B发送过来的数据,那么就会一直在那傻等着,而B即使重启成功它也不知道之前和A有连接,所以A永远等不到B的数据。如果有KeepAlive的话,它就会定时的发送数据给B,B收到数据后找不到对应的连接就会回复一个reset信息,那么A收到reset信息以后就知道连接已经失效。
_____ _____
| | | |
| A | | B |
|_____| |_____|
^ ^
|--->--->--->-------------- SYN -------------->--->--->---|
|---<---<---<------------ SYN/ACK ------------<---<---<---|
|--->--->--->-------------- ACK -------------->--->--->---|
| |
| system crash ---> X
|
| system restart ---> ^
| |
|--->--->--->-------------- PSH -------------->--->--->---|
|---<---<---<-------------- RST --------------<---<---<---|
| | 2,防止连接长时间无数据传输而被断开
比如下图的情况,NAT会监控A和B之间的所有连接,如果连接长时间处于闲置状态就会被断开。KeepAlive定期的发送数据可以促使连接不会被断开。
_____ _____ _____
| | | | | |
| A | | NAT | | B |
|_____| |_____| |_____|
^ ^ ^
|--->--->--->---|----------- SYN ------------->--->--->---|
|---<---<---<---|--------- SYN/ACK -----------<---<---<---|
|--->--->--->---|----------- ACK ------------->--->--->---|
| | |
| | <--- connection deleted from table |
| | |
|--->- PSH ->---| <--- invalid connection |
| | |
下午的时候还做了个小测试,在一台机器上运行一个SocketServer的程序,另外一台运行Socket程序去连接SocketServer,这个时候我并没有设置Socket的任何timeout。然后断开网线,发现Socket抛出ReadTimeout异常。当时觉得很奇怪,还以为是底层有KeepAlive呢。后来想想可能是操作系统侦测到网线被拔掉了吧O(∩_∩)O~。
参考文献
http://www.cubrid.org/blog/dev-platform/understanding-jdbc-internals-and-timeout-configuration/
http://www.tldp.org/HOWTO/html_single/TCP-Keepalive-HOWTO/
利用DataImportHandler建索引时一直无法完成的更多相关文章
- [慢查优化]建索引时注意字段选择性 & 范围查询注意组合索引的字段顺序
文章转自:http://www.cnblogs.com/zhengyun_ustc/p/slowquery2.html 写在前面的话: 之前曾说过"不要求每个人一定理解 联表查询(join/ ...
- java web轻量级开发面试教程读书笔记:建索引时我们需要权衡的因素
场景一,数据表规模不大,就几千行,即使不建索引,查询语句的返回时间也不长,这时建索引的意义就不大.当然,若就几千行,索引所占的空间也不多,所以这种情况下,顶多属于"性价比"不高. ...
- oracle建索引的可选项
oracle中建索引可能大家都会,但是建索引是有几个选项参数却很少有人关注,在某些特殊环境下,可能会非常有用,下面一一说明: 1.NOSORT,记录排序可选项. 默认情况下,在表中创建索引的时候,会对 ...
- Oracle使用并行建索引须要注意的问题
建索引时.我们为了建索引快.会加上并行,加上并行之后.此列索引就会是并行了. 訪问有并行度的索引时,CBO可能可能会考虑并行运行.这可能会引发一些问题,如在server资源紧张的时候用并行会引起更加严 ...
- INDEX--创建索引和删除索引时的SCH_M锁
最近有一个困惑,生产服务器上有一表索引建得乱七八糟,经过整理后需要新建几个索引,再删除几个索引,建立索引时使用联机(ONLINE=ON)创建,查看下服务器负载(磁盘和CPU压力均比较低的情况)后就选择 ...
- 索引时利用K-邻近算法过滤重复歌曲
最近一直在做公司搜索的优化与维护,做完索引和搜索的分离之后,又有一个新需求,因为做的是歌曲方面的搜索,所以在数据库中有多个同歌名,同演唱者的的数据,这样在用户搜索的时候,会出来一大堆不同版本的歌曲,影 ...
- Mongodb 3 查询优化(语句优化、建索引)
一.explain(),语句分析工具 MongoDB 3.0之后,explain的返回与使用方法与之前版本有了很大的变化,介于3.0之后的优秀特色和我们目前所使用给的是3.0.7版本,本文仅针对Mon ...
- Mysql索引分析:适合建索引?不适合建索引?【转】
数据库建立索引常用的规则如下: 1.表的主键.外键必须有索引: 2.数据量超过300的表应该有索引: 3.经常与其他表进行连接的表,在连接字段上应该建立索引: 4.经常出现在Where子句中的字段,特 ...
- MySQL 分区建索引
200 ? "200px" : this.width)!important;} --> 介绍 mysql分区后每个分区成了独立的文件,虽然从逻辑上还是一张表其实已经分成了多张 ...
随机推荐
- servlet的url-pattern匹配规则
首先需要明确几容易混淆的规则: servlet容器中的匹配规则既不是简单的通配,也不是正则表达式,而是特定的规则.所以不要用通配符或者正则表达式的匹配规则来看待servlet的url-pattern. ...
- js获取json的value
getJson('age'); function getJson(key){ var jsonObj={"name":"cxr","age" ...
- Java web项目综合练习(Estore)
Java web项目综合练习(Estore) 复习day18: ajax代码的书写步骤 2)json格式文本,转js对象的方法是那个 项目开发流程介绍 这里学习的JavaWEB项目实战,主要是把前面学 ...
- team viewer - rollback framework could not be initialized
rollback framework could not be initialized, 在安装team viewer 的时候出现的这个错误信息,求大师帮忙 https://zhidao.baidu. ...
- 《JS权威指南学习总结--6.1原型》
内容要点: 一.每一个JS对象(null除外)都和另一个对象相关联."另一个"对象就是我们熟知的原型,每一个对象都从原型继承属性. 二.所有通过对象直接量创建的对象都具有同一个原型 ...
- 一行一行分析JQ源码学习笔记-01
jQuery (function(window,undefined){ }) undefined 防止外部参数中 var undefined =10:以此来改变内部 undefined 不太建议用严 ...
- geom设置—折线图
折线图在R中也是很常见的一种图形,相对而言也比较简单. geom_line(mapping = NULL, data = NULL, stat = "identity", posi ...
- deepin2014.1快捷键
初试deepin2014.1,发现windows很多快捷键在deepin中也完美支持,举例如下: ctrl+shift+n : 新建文件夹 窗口键+E:打开文件系统 窗口键+TAB:3D切换桌面 al ...
- 8.多线程和Socket通信
一.多线程 1.进程的概念: 进程就是应用程序的执行实例,有独立的内存空间和系统资源.当一个应用程序没有执行的时候,它就不是一个进程. 2.进行的特征: (1)动态性:动态产生动态消亡. (2)并 ...
- 越狱开发-创建真正的后台程序(Daemon Process)
在网上搜索了一下如何在IOS上面实现Daemon Process,只有chrisalvares的博客中有过详细的描述,但是其博客中描述的较为复杂, 参考stackoverflow中的一个问答: htt ...