即使是不成熟的尝试,也胜于胎死腹中的策略。

elasticsearch 怎么实现按位与操作吗,或者取十进制对应的二进制某一位的值?

kennywu76 回复了问题 • 3 人关注 • 1 个回复 • 4954 次浏览 • 2017-06-15 17:22 • 来自相关话题

搜索打分问题

回复

匿名用户 发起了问题 • 1 人关注 • 0 个回复 • 1676 次浏览 • 2017-06-15 14:14 • 来自相关话题

dsl能否实现sql的join功能?

novia 回复了问题 • 4 人关注 • 5 个回复 • 2812 次浏览 • 2017-06-15 11:44 • 来自相关话题

模糊查询导致Elasticsearch服务宕机

kennywu76 发表了文章 • 1 个评论 • 5757 次浏览 • 2017-06-15 10:32 • 来自相关话题

之前我在社区里写过 《ElasticSearch集群故障案例分析: 警惕通配符查询》一文,讲的是关于通配符查询可能引起ES集群负载过高的问题。 当时提到wildcard query构造的non-deterministic automaton要经历一个determinize的过程,其间如果生成的状态数量过高,可能引起集群负载彪高,影响对外服务。 但因为determinize的过程中,Lucene对生成的状态数量做了限制,因此在问题查询过去以后,集群还是可以恢复常态。
 
然而近期我们线上的另外一起故障,使我意识到,Prefix/Regex/Fuzzy一类的模糊查询可能直接让整个集群直接挂掉。
 
问题出现时,ES服务端日志有如下报错:


[2017-06-14T21:06:39,330][ERROR][o.e.b.ElasticsearchUncaughtExceptionHandler] [xx.xx.xx.xx] fatal error in thread [elasticsearch[xx.xx.xx.xx][search][T#29]], exiting
java.lang.StackOverflowError
        at org.apache.lucene.util.automaton.Operations.isFinite(Operations.java:1053) ~[lucene-core-6.2.1.jar:6.2.1 43ab70147eb494324a1410f7a9f16a896a59bc6f - shalin - 2016-09-15 05:15:20]
        at org.apache.lucene.util.automaton.Operations.isFinite(Operations.java:1053) ~[lucene-core-6.2.1.jar:6.2.1 43ab70147eb494324a1410f7a9f16a896a59bc6f - shalin - 2016-09-15 05:15:20]
        at org.apache.lucene.util.automaton.Operations.isFinite(Operations.java:1053) ~[lucene-core-6.2.1.jar:6.2.1 43ab70147eb494324a1410f7a9f16a896a59bc6f - shalin - 2016-09-15 05:15:20]
        at org.apache.lucene.util.automaton.Operations.isFinite(Operations.java:1053) ~[lucene-core-6.2.1.jar:6.2.1 43ab70147eb494324a1410f7a9f16a896a59bc6f - shalin - 2016-09-15 05:15:20]


调查后发现,Prefix/Regex/Fuzzy一类的Query,是直接构造的deterministic automaton,如果查询字符串过长,或者pattern本身过于复杂,构造出来的状态过多,之后一个isFinite的Lucene方法调用可能产生堆栈溢出。
 
一个可以复现问题的regex query如下:
POST /test/_search
{
"query": {
"regexp": {
"test": "t{1,9500}"
}
}
}
Github上的issue链接: issues/24553。 

对于我们这次特定的问题,是因为prefix Query里没有限制用户输入的长度。 看ES的源码,PrefixQuery继承自Lucene的AutomatonQuery,在实例化的时候,maxDeterminizedStates传的是Integer.MAX_VALUE, 并且生成automaton之前,prefix的长度也没有做限制。 个人认为这里可能应该限制一下大小,避免产生过多的状态:
public class PrefixQuery extends AutomatonQuery {

/** Constructs a query for terms starting with <code>prefix</code>. */
public PrefixQuery(Term prefix) {
// It's OK to pass unlimited maxDeterminizedStates: the automaton is born small and determinized:
super(prefix, toAutomaton(prefix.bytes()), Integer.MAX_VALUE, true);
if (prefix == null) {
throw new NullPointerException("prefix must not be null");
}




 最终抛出异常的代码是
org.apache.lucene.util.automaton.Operations.isFinite,  
可以看到这段代码里用了递归,递归的深度取决于状态转移的数量。根据注释的说明,这是一段待完善的代码,因为使用了递归,可能导致堆栈溢出:
  // TODO: not great that this is recursive... in theory a
// large automata could exceed java's stack
private static boolean isFinite(Transition scratch, Automaton a, int state, BitSet path, BitSet visited) {
path.set(state);
int numTransitions = a.initTransition(state, scratch);
for(int t=0;t<numTransitions;t++) {
a.getTransition(state, t, scratch);
if (path.get(scratch.dest) || (!visited.get(scratch.dest) && !isFinite(scratch, a, scratch.dest, path, visited))) {
return false;
}
}
path.clear(state);
visited.set(state);
return true;
}

由此可见,在项目里使用了模糊查询的同学,一定一定要注意限制用户输入长度,否则可能导致集群负载过高或者整个挂掉。 
 
虽然Lucene/Elasticsearch应该在代码层面做一些限制,确保有问题的query不会导致stack overflow,但是当用到这类查询的时候,程序员的思维方式还局限在RDBMS开发的时代。 我们应该多在数据索引阶段下功夫,确保尽量用最高效的term query来完成绝大多数的查询。 

支持坐标系的问题

回复

zp_wan 发起了问题 • 1 人关注 • 0 个回复 • 2489 次浏览 • 2017-06-15 10:23 • 来自相关话题

请教关于搜索的问题

wilbur 回复了问题 • 2 人关注 • 1 个回复 • 2468 次浏览 • 2017-06-14 22:43 • 来自相关话题

shingle 和N-gram 两种token filter有什么区别?

imp 回复了问题 • 2 人关注 • 1 个回复 • 3580 次浏览 • 2017-06-14 18:14 • 来自相关话题

新手求教,关于索引删除的问题

little_heart 回复了问题 • 2 人关注 • 2 个回复 • 2607 次浏览 • 2017-06-13 19:36 • 来自相关话题

es重启一个节点就重新分片

kennywu76 回复了问题 • 4 人关注 • 2 个回复 • 4746 次浏览 • 2017-06-13 18:02 • 来自相关话题

cardinality聚合能根据多个字段进行去重计数麽

childe 回复了问题 • 3 人关注 • 1 个回复 • 3547 次浏览 • 2017-06-13 17:55 • 来自相关话题

es0.9升级es5.1.2数据迁移的方法,求大神,在线等

yiyezhiqiu425 回复了问题 • 3 人关注 • 2 个回复 • 2904 次浏览 • 2017-06-13 17:54 • 来自相关话题

es node 脱离又加入集群的问题(补充了es日志)

kennywu76 回复了问题 • 4 人关注 • 3 个回复 • 4714 次浏览 • 2017-06-13 13:54 • 来自相关话题

两个结果相同的(terms aggs)聚合查询,聚合查询时间差几百倍。

fhyes123 回复了问题 • 6 人关注 • 5 个回复 • 3379 次浏览 • 2017-06-13 10:24 • 来自相关话题

请问es有办法高亮聚合的结果吗?

回复

anonymous 发起了问题 • 1 人关注 • 0 个回复 • 3044 次浏览 • 2017-06-12 17:02 • 来自相关话题