利用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分区后每个分区成了独立的文件,虽然从逻辑上还是一张表其实已经分成了多张 ...
随机推荐
- hibernate异常:org.hibernate.NonUniqueObjectException
异常:org.hibernate.NonUniqueObjectException 提示:a different object with the same identifier value was a ...
- Android:Asmack能登录但是获取不到联系人的问题
先说一下:换了N个jar包,换了N个OpenFire,就是获取不到联系人.但是能登录.特别纳闷,百度不到,google一下,有人隐约说了下权限的问题. 终于搞出来了,总结一下,浪费了一整天的时间.(码 ...
- CodeForces 699A Launch of Collider
枚举相邻两个$a[i]$与$a[i+1]$,如果$s[i]=R$并且$s[i+1]=L$,那么$i$和$i+1$会碰撞,更新答案. #pragma comment(linker, "/STA ...
- Bullcow 牡牛和牝牛(bzoj 3398)
Description 约翰要带N(1≤N≤100000)只牛去参加集会里的展示活动,这些牛可以是牡牛,也可以是牝牛.牛们要站成一排.但是牡牛是好斗的,为了避免牡牛闹出乱子,约翰决定任意两只牡 ...
- 拉钩网爬取所有python职位信息
最近在找工作,所以爬取了拉钩网的全部python职位,以便给自己提供一个方向.拉钩网的数据还是比较容易爬取的,得到json数据直接解析就行,废话不多说, 直接贴代码: import json impo ...
- html历史
方法一: location.hash = 'abc' window.onhashchange = function(){} location.hash 返回结果 #abc => locati ...
- PAT 乙级 1004. 成绩排名
读入n名学生的姓名.学号.成绩,分别输出成绩最高和成绩最低学生的姓名和学号. 输入格式:每个测试输入包含1个测试用例,格式为 第1行:正整数n 第2行:第1个学生的姓名 学号 成绩 第3行:第2个学生 ...
- 关于 plsql连接oracle数据库的问题
因电脑没有 安装oracle服务器端,所以安装plsql后还是不能连接oracle数据库,网上下载一个oracle客户端工具,是绿色免安装的,解压就好.我放我云盘了. instantclient_11 ...
- ckeditor上传图片的注意点
1.要在 ckeditor的 config.js 文件中加上 CKEDITOR.editorConfig = function( config ) { config.filebrowserImage ...
- Java 集合 JDK1.7的LinkedList
Java 集合 JDK1.7的LinkedList @author ixenos LinkedList LinkedList是List接口的双向链表实现,JDK1.7以前是双向循环链表,以后是双向非循 ...