elasticSearch常见问题答疑

本文档详细解答了关于Elasticsearch(ES)在数据写入、查询、跨机房部署、性能优化等方面的问题。ES不是数据库,数据写入后可能无法立即查询到,可通过refresh API解决。跨机房部署可能导致性能下降,ES不推荐。数据写入后需关注bulkresponse状态以确保数据完整性。ES是一个最终一致性系统,相同query在不同时间可能得到不同结果。此外,文档讨论了索引、模板、mapping、thread pool、错误处理等多个主题,并提供了最佳实践和常见错误案例。
摘要由CSDN通过智能技术生成

1.ES不是什么
ES不是可靠的存储系统,不是数据库,它有丢数据的风险。具体请参考ES内部分享中的ES简介这个文档

2.为什么一条数据写入后马上查询查不到?
ES不是实时系统,数据写入成功只是trans log成功(类似于mysql的bin log),写入成功后立刻查询查不到是正常的。因为数据此刻可能还在内存里而不是进入存储引擎里。
同理,删除一条数据后也不是马上消失
写入何时可查询?ES内部有一个后台线程,定时将内存中的一批数据写入到存储引擎,此后数据可见
默认后台线程一秒运行一次。该线程运行的越频繁,写入性能越低。运行的频率越低,写入的性能越高(不会无限高)

1.2.跨机房问题
a. ES官方不推荐跨机房部署。https://www.elastic.co/blog/clustering_across_multiple_data_centers

b. 除了上述问题外,同时我们在公司内部署双机房测试,读写性能均下降15%

c. 而且双机房部署后,由于master节点的奇数特征,势必会出现某一个机房并不能独立工作的情况

1.3.如何解决数据写入后想马上查询到
写入数据后手工调用refresh这个API即可
没有免费的午餐,这个API调用的频繁会影响写入性能

  1. 为什么同样的query多次查询的数据不一致?
    a. 由于shard的主分片和副本是由独立的节点去刷新的,刷新的频率并不同步,这样同样的query发送到不同的分片(主片和从片)上看到的数据是不同的,导致的结果是查询到的数据也不完全同步。简单说,ES是一个最终一致性系统

3. bulk写入后数据条目不一致
a. 对数据可靠性要求高的话,用bulk批量写入后需要展开bulkrespose的每一个条目,判断每一条数据的写入成功情况

              ActionRequestBuilder#execute(ActionListener<Response>),注册一个listener,在onResponse中遍历bulk中每个请求的执行情况,对于失败的请求,可以重试或者log...

3.1. ES的能力边界是什么
目前已知的单ES集群可以存储PB级别的数据,不过这个就非常费劲了。TB级别数据没压力

4.es中不分词,哪些查询语句是模糊查询的?我指的模糊查询是查询 “裤子” ***裤子都会查找出来*
有这样需求的赶紧走数据库

5.一个ES的index能存多少数据
ES的index分成若干shard,每个shard最大能存20亿条数据,这是个硬限制

6.IllegalArgumentException: number of documents in the index cannot exceed 2147483519
超过上头的限制报的异常.一个分片最多能存 2147483519 个文档,这是ES的门槛,只能删掉部分数据,或者重新建索引。
6.1.使用ES的条件
如果使用ES官方提供的jar包访问,需要JDK1.7及以上
升级JDK到1.7有问题的话,请自行用HTTP包装API

7.给个ES使用文档参考
https://www.elastic.co/guide/index.html

8.给个ES使用例子参考
Demo说明

9.ES2.1需要的jar的版本要求:
JDK1.7及以上

10.ES client版本问题
使用对应的版本访问ES server。如果ES server端的版本是1.7,那么请使用ES 1.7的client。如果ES server是2.1,请使用2.1的client
用低版本访问过程中出现问题我们不负责处理。
11.Date数据为什么差8小时
时区问题:http://josh-persistence.iteye.com/blog/2230074 //北京时间可以表示为GMT+8:00
如何正确的写入date类型的数据到ES:.field(“date”, new Date(), ISODateTimeFormat.dateTime().withZone(DateTimeZone.forID(“Asia/Shanghai”)))
12.ES内部分享的资料
ES内部分享

13.ES的版本是什么?索引存在了什么地方?几副本?存储容量是多少?
目前提供的版本是2.1
索引存在linux服务器的文件系统之上(背后是文件系统,不是类似于HDFS的分布式文件系统)
副本数目由业务方根据需求自己确定
可以认为存储空间没有限制(存储空间不够的话ES服务方会动态加节点、加硬盘)
14.如何优化写性能
https://www.elastic.co/blog/performance-considerations-elasticsearch-indexing
15.如果优化读性能
https://www.elastic.co/blog/found-optimizing-elasticsearch-searches
15.1.容量规划(科学的确定shard的数量)
https://www.elastic.co/guide/en/elasticsearch/guide/master/capacity-planning.html

16.怎么申请服务
我们提供一个测试环境供大家测试功能:杰思

测试环境说明:ES测试环境部署
线上服务申请流程请参考:
TODO: 王松林补充文档

17.我的业务很重要,我需要独立的物理机部署
抱歉,申请物理机不在我们这,我们这只提供ES服务。只有服务,没有硬件,没有物理机,没有CPU。这些申请统统不在我们这。
但是我也理解,每个人的业务都很重要,怎么办?提供你们的QoS需求,比如需要写入的TPS是多少,查询的TP99需要保证多少等等,然后咱们一起在有限的资源上保障业务方的QoS
18.除了集群外,其他的东西为什么要申请,比如mapping的创建,修改,index的创建,删除等等。
首先,目前我们做不到强制让你申请,因为所有的API都是不鉴权的,我们只能建议申请,做不到强制申请。但是,建议大家该申请的申请
但是,在2016年三季度(最晚四季度)我们会开发出ES的权限模块,此时,我们就能做到强制申请
为什么要申请?
前期一是帮助大家review明显的错误;二是为啥数据安全
后期我们维护的就不是ES了,而是ES协议兼容的存储系统,有些ES支持的我们就不支持了;有些ES不支持的我们会支持。
19.用http的方式如何访问es集群
ES暂时未与VIP打通,业务可自行申请VIP
20.我的mapping合不合理
对不起,不知道
要想跟我们讨论你的mapping合不合理,必须把你们的全部query都拿出来,这才有讨论的可能。
什么叫全部的query?
select * from type1 where fieldA = XXX
select * from type1 where fieldA = XXX and fieldB = XXX
select * from type1 where fieldA = XXX and fieldB = XXX sort on fieldC
select count( * ) from type1 where fieldA = XXX

21.mapping能否更新
Other than where documented, existing type and field mappings cannot be updated. Changing the mapping would mean invalidating already indexed documents. Instead, you should create a new index with the correct mappings and reindex your data into that index.
存在的字段不能被更新和删除
不存在的字段可以添加
21.2mapping冲突
https://www.elastic.co/blog/great-mapping-refactoring#conflicting-mappings

22.定期创建索引
有些业务需要定期创建索引,比如日志,订单,运单等。这种需求是通过申请一个template,然后ES服务提供方负责定期创建索引完成的
23.什么是template(模板)
模板是描述表结构(mapping)和表设置(setting)的数据结构
模板特殊在它可以描述一组mapping和setting的组合。描述一组的功能是通过名字的正则表达式实现的
tempate的一个例子:TimLine图片20160715110214.png
原理:
1 在ES中创建一个索引模板,其本质就是包含mapping及分片信息,模板中有个属性 template 表示该模板用来匹配什么样的索引。比如 "template:abc*“,创建的所有以abc开头的索引,将会应用这个模板,一般用来匹配按 周期 创建的索引,例如 abc-2017-02-03;

2 通过定时任务创建索引,菜单在 “”集群管理–定时任务配置” 创建一个定时任务,按照特定间隔创建索引。比如按1天。

24.ES2.1版本元字段属性
ES2.1元字段的属性
25.routing是什么?为什么要用routing?能带来什么好处?有什么坏处
rouing就是hash key, 这个key决定写入/查询的分片id
如果你在写数据和查询的时候从来没有涉及到routing,那么ES在写入的时候用document的id做routing决定这条数据写到哪个分片上。查询的时候则把query下发到所有分片
为了避免把query下发到所有的分片进而提升检索性能,会有这种技巧:根据查询的特征,比如我的查询都是用用户id去查,那么在写入数据的时候可以根据用户id去决定分片;在查询的时候也用用户ID做shard key将query只下发到相关的分片上。这是routing能带来的最大和唯一的好处
但是,这是有条件的,就是你的query确实是有特征的
坏处是根据某一特定值做routing之后,可能带来数据倾斜,使得某些分片承载的数据很多而另外一些分片承担的数据很少。
26.能否对一条document指定多个rouing key,让它分配到不同的shard上去,这样我的Aquery就可以只查Ashard上,B query只查B shard
rouing是hash key, 你以为你用多个routing key就一定能分配到不同的shard上(没有hash冲突?!!),我只能说太navie了。
所以写数据的时候指定多个routing key这事就别想了

27.为什么申请别名?为什么要为读写申请不同的别名?
请参考官方文档:https://www.elastic.co/guide/en/elasticsearch/guide/current/index-aliases.html
28.能否按天创建索引?是否提供定时删除过期索引?
能按天创建索引
提供定时删除过期索引
29.一个典型的错误查询用例
search_type[DFS_QUERY_THEN_FETCH], total_shards[32], source[{“from”:0,“size”:1,“query”:{“term”:{“waybillCode”:“19966779685”}},“explain”:true,“fields”:[“updateTime”,“updateTimeM”,“updateTimeE”,“tsC”,“tsE”,“tsM”]}], extra_source[]

错误点:
search type不要用DFS_QUERY_THEN_FETCH,用query_then_fetch足够(除非能提供充足的理由)

尽可能的用filter,它快

不要用explain:true,这个是打印debug相关的信息的
不要用fields, 在client端去解码
30.ES java client
ES java client是线程安全的,全局构建一个即可满足读写需求,不要每次都创建ES client。否则会出现下面这个问题
31.java.lang.OutOfMemoryError: Direct buffer memory
完整异常:
org.elasticsearch.netty.channel.socket.nio.AbstractNioSelector - Unexpected exception in the selector loop.
每次访问ES都构建新的es client即会抛出次异常。解决方案:全局构建一个client
32.java.lang.OutOfMemoryError: unable to create new native thread
ES进程启动时从操作系统中拿到的Max processes过小而ES开启的线程数超过该值,从而导致ES进程不能开启其他工作线程
33.ClassNotFoundException
检查ES client用到的依赖包的版本是否大于等于demo里的包的版本(最好是等于)
34.NoSuchMethodError
很多用户跑demo时会报出这个异常,原因是ES需要的很多jar包的版本比你们项目中使用的相同的jar包要高,此时需要升级相关jar包
35.NoNodeAvailableException
查看链接的ip地址和端口是否正确。经常有人把TCP的端口错配为HTTP的端口
查看cluset name是否正确(cluster name错了也抛这个异常)
使用和ES server版本匹配的ES Client 版本

如果是在连上ES并且运行一段时间后出现,很有可能是某个链接的节点出问题了。此时请大家不要紧张,ES会自动切换到其他节点访问

如果使用安全插件(鉴权),可能验证不通过导致异常。
36.TransportSerializationException
Caused by: org.elasticsearch.transport.TransportSerializationException: Failed to deserialize exception response from stream
检查ES client的版本与server的版本是否一致
37.如何检查ES server的版本

38.IllegalStateException
java.lang.IllegalStateException: Message not fully read (request) for requestId
检查是否有低版本的ES client访问高版本的ES server
39.InvalidIndexNameException
索引的名字有如下规范,如果违反如下规范,则抛出上述异常
索引名字不能包含非法的文件名称字符(\,/,*,?,",<,>,|,空格,逗号 )
索引名字不能包含#
索引名字不能以下划线_开头

索引名称如果包含因为字母,则必须为小写
40.TypeMissingException
ES的index是逻辑数据库,type是逻辑表
这个异常的意思是逻辑表不存在
逻辑表如果是通过ES系统申请创建的,那么查查申请的mapping
逻辑表如果是通过程序创建的,你们自己查自己的程序
41.什么是mapping?写数据必须要创建mapping吗?
Mapping相当于数据库的表结构

在写数据前ES不强制要求创建mapping,因为ES有动态识别和创建的机制

非常不建议使用ES的动态识别和创建的机制,因为很多情况下这并非你所需要。推荐的做法是在写数据之前仔细的创建mapping

42.如何创建mapping
http://jpcloud.jd.com/pages/viewpage.action?pageId=16624064

测试环境创建mapping请自行创建

线上环境请在系统提交申请。

43.是否应该完整的提交mapping申请
是的。虽然ES有dynamic mapping(dynamic schema)的功能,单这通常会造成很大的问题,所以我们都ES集群都是关闭该功能的,需要预先提交完整的mapping
44.TooManyClauses / maxClauseCount
使用terms query, prefix query, fuzzy query, wildcard query或者range query等都会出现这个异常

上述query都是语法糖,在搜索引擎内部是转换为boolean query查询的

以terms query为了,其实是构建了多个term query为子语句的全or关系的一个boolean query

为了避免内存消耗过多和时间消耗过长,搜索引擎内部对boolean query的子语句个数是有限制的,超过这个限制就会抛出TooManyClauses

最好的解决办法是调整自己的查询语句,不要出现TooManyClauses

index.query.bool.max_clause_count:1024 在V5中indices.query.bool.m

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值