题记
马云演讲中曾经提到:很多时候少听成功专家的话。所有的创业者多花点时间学习别人是怎么失败的,因为成功的原因有千千万万,失败的原因就一两个点。
创业需要关注别人的失败,而开发实战,别人的错误经验、别人的问题也非常有价值。
开发最懊悔的事莫过于:自己费尽脑汁、花费了很长时间解决了问题,原来别人在社区或者别的地方早已经给出了更优化的方案。
开发最最懊悔的事莫过于:别人已经给出了方案,但是我们仍然在黑暗中苦逼的摸索。
因此,我从2018年4月——至今,每月都会梳理出了Elasticsearch中文社区的精华干货——简称:Elastic错题本,
问题大多来自Medcl、wood大叔等大牛的精彩回复,结合实战严选的核心问题。
放在了GitHub上。
GitHub地址:https://github.com/laoyang360/deep_elasticsearch/tree/master/es_accumulate
目的:提前加深认知,少重复走别人的弯路!
1、Elasticsearch
1.1 如何清理Elasticsearch特定时间段数据?
Elasticsearch 6.6+新推出了一个 ILM 的功能,Index Lifecycle Management 的功能,在Kibana 界面里面就可以直接配置索引的保留时间和过期策略。
上一次错题本也提及:https://elasticsearch.cn/article/6358
es5.0提供了 Rollover 特性
https://elasticsearch.cn/question/1094
1.2 能否在一个查询中 查询两个条件 在对两个结果进行除法计算?
请教各位一个问题,我们有一个场景,想通过1个查询语句,计算两个查询结果的除法,
比如,我有一个查询条件,用 idc: “BJ” 能统计出有100条数据符合要求 ,
第二个条件 idc: “SH”,能统计出有200个数据,我现在想要取到 100 / 200 这个值 50% 这个数据,
请问能有办法实现吗?
参考 es6.6版本
PUT test01_index/_doc/5
{
"x_value":15,
"y_value":3
}
POST test01_index/_doc/_search
{
"script_fields": {
"my_divide_field": {
"script": {
"lang": "expression",
"source": "doc['y_value'].value != 0 ? doc['x_value'].value / doc['y_value'].value : 0"
}
}
}
}
1.3 ngram分词器会占很多内存吗?
ngram分词分的很细,会不会导致较多的内存占用?当数据量较大时,是否有瓶颈??
【回复】ngram分词分的很细会产生较多的 term ,因此会比普通使用词典分词的占用更多的存储和内容;
数据量大的时候,可通过分索引和多分片来分散压力。
1.4 自定义id带来的问题
问题描述:我们目前业务使用了自定义id,md5(uid+someid), 目的是为了再次更新方便。但是这样有两个问题,1: 这种随机的自定义id,压缩比很低,空间占用高。2: 指定id bulk index 的时候,es 会先判断 id 是否存在,然后再插入。这样随着数据量的增加,性能持续下降。 不知道大家有什么好办法,对应这种需要持续更新的数据。 数据量还挺大的。
官网建议:如果使用了自动生成id,每次导入数据的时候都要进行id的检查。这里是有性能消耗的。但是使用随机生成id,就不需要这一步。
官网地址:http://t.cn/Ei47gY0
讨论建议:
id的生成策略尽量是对压缩友好的,避免过于随机,比如按序生成
想到一点减小id是否存在的判断成本,是否考虑使用路由,相当于指定了插入doc所在的shard,减少判断是否存在的数据量。
1.5 关于 ik 新词更新
想做新词发现,更新词库,但是搞不清es对于这种更新词库后,老数据怎么处理为好
建议:不影响搜索的话,重建索引,reindex ,然后别名切换过去。
原因:ES数据写入的过程即是索引化的过程,这个阶段会按照设定的分词进行数据索引化。所以,必须reindex重建索引或者重新导入数据才能生效。
1 .6 es有没可能同时写多个索引?
有旧有数据的同步问题的困扰,需要类似数据双写的操作,貌似直接设置同一个别名然后insert会报错
alias 只能声明一个索引为写活跃状态,无法多个同时写入,否则会报错。
或者用reindex 开始的时候你写两份就行啊,修改一份。
1.7 bulk写入数据时,READ非常高
无论是index或者是update,只要指定了doc id,lucene都需要进行get操作,当你索引数据量很大时,会有频繁且大量segment中的数据加载到内存,这是read io高的一个大原因,
另外通常merge 只要线程数限小,不会有非常高的read io,我之前也碰到过这个问题,自己探索了下
经核实:确实是因为指定id引起的。
https://elasticsearch.cn/question/6526
1.8 增加索引个数能有效的提高写入效率吗?
如题,
现在ES集群是一个索引在写,后台15台物理机,48c,188G,是多线程同步写一个索引,看监控能到40W,再加并发也提高不了,但是机器的负载和线程池资源都还OK,我看线程池是index级别的设定,能通过增加写入索引个数来增加写入性能吧,还是说要扩容呢?
写入及索引性能核心参考:https://www.elastic.co/guide/en/elasticsearch/reference/master/tune-for-indexing-speed.html
网上所有的书籍、文档基本都离不开链接给出的东西
1.9 Elasticsearch6.5.3全聚合出现与MySQL聚合结果不一致的问题
MySQL中的聚合语句:
select sum(adv_price) from report_2019_01 where report_time>=1546272000 and report_time<1546358400;
MySQL聚合结果是:11612.840
将上面时间的数据全部导入es中,并聚合:
"aggregations": {
"revenue": {
"sum": {
"field": "adv_price"
}
}
}
}
Elasticsearch聚合结果是:9064
原因:浮点精度问题,类似相关问题都是浮点精度问题思路排查的。
1.10 如何对同一个字段进行不同的分词
multi-fields 可以实现,也就是说一个字段可以设置多个子字段.
推荐视频:https://elasticsearch.cn/article/13274
1.11 es禁止*删除索引
1、永久修改——通过setting修改
PUT /_cluster/settings
{
"persistent": {
"action.destructive_requires_name": "true"
}
}
2、通过配置文件修改
建议通过1修改
1.12 怎样限定es查询返回数据最低分,低于XX分数的不要
min_score参数
SearchResponse response = client.prepareSearch(INDEX_NAME)
.setTypes(TYPE_NAME)
.setQuery(queryBuilder)
.setMinScore(minScore)
.execute()
.actionGet();
.setMinScore(minScore)
1.13 想问下多个terms查询为何不起作用,有没有什么解决办法
https://elasticsearch.cn/question/7342
问题原因:大小写问题
默认的standard analyzer包含lowcase token filter, 会把大写转换为小写,,如果一定要使用大写查询的话,可以自定义
1.14 关于translog和线程池拒绝
比如提交bulk,请求写入了translog,但是由于服务器压力大,线程池拒绝了这个请求,那translog还有用吗?
回复:写translog是在写内存之后才会发生,如果出现拒绝是连内存还没写入就拒绝了,远没有到写translog,
可以看看这篇文章:https://zhuanlan.zhihu.com/p/34669354
1.15 es search为啥不用bloom filter?
首先你需要了解布隆过滤器的用途,一般是用于字符串或者数字等,检测是否存在的场景,例如:爬虫的 URL 去重;
ES 的查询,大部分场景是看某个文本是否存在与某篇文档中;或者日期、数字等是否在某个范围;
所以应用的方向不同,因此 ES 使用了倒排索引、KD数等其他数据结构实现了搜索
1.16 将文档存储在es外面,同时使es搜索结果只返回文档基本信息,这样做能否提高性能?
问题描述:
就是说,如果文档比较大,es把它作为搜索结果整个返回的时候,可能对es性能造成压力。
所以一个自然的想法就是,index时把文档整个存进es,同时把文档另存一份在其他专用的静态存储空间中,query时使es只返回文档基本信息,如id、timestamp等,再通过id来找到静态存储空间中的相应文档。
这样子能否对es性能有较大提升,实际应用中这样的使用模式多不多呢?
wood大叔回复:如果文档都非常大,静态存储方案廉价,能按照id,timestamp快速fetch回数据,那么这种方案未尝不可。 但是复杂性方面比全部放ES要高一些,应用层面多了一个依赖,也享受不到某些原生的ES特性,比如reindex。再就是静态存储通常也要是分布式的,维护也有成本。所以你还是要评估一下用静态存储的话能省多少硬件,如果省得不多,还不如将文档全部放ES里简单直接。
bsll:理论上是可以的,用过es+hbase, es+couchbase的案例,不过楼上说的很对,得根据你的实际情况来。
1.17 sql中的 is null 和 is not null 在Elasticsearch的应用
建议源头出发,定义NULL.
PUT my_index
{
"mappings": {
"_doc": {
"properties": {
"status_code": {
"type": "keyword",
"null_value": "NULL"
}
}
}
}
}
1.18 elasticsearch 删除不用的索引 怎么真正释放磁盘空间?
比如 我创建了 course1 course2 course3 这些都是测试创建的索引 但是我用curl -XDELETE http://192.168.1.113:9200/course1 这样的命令将course1 2 3 分别删除 但是在 elasticsearch data 目录下文件并未释放磁盘空间 怎么操作才能删除之前不用的索引并释放磁盘空间呢 谢谢!!
解决方案:https://elastic.blog.csdn.net/article/details/80038930
2、 Logstash
2.1 logstash 批量接收数据
在logstash 中有没有办法使用 avro 接收数据,或者有没有其他方案能够接收flume 的avro sink 发来的数据
实现:
input {
kafka {
codec => avro {
schema_uri => "/tmp/schema.avsc"
}
}
}
filter {
...
}
output {
...
}
https://www.elastic.co/guide/en/logstash/current/plugins-codecs-avro.html
2.2 logstash中添加fielter grok之后怎么过滤多余的字段
保留message字段
参考如下:
filter {
grok {
remove_field => [ "foo_%{somefield}", "my_extraneous_field" ]
}
}
2.3 logstash和es的template
问题描述:
logstash和es都指定了索引的模板, 那logstash采集数据到es时,以哪个模板为准呢
回复:两个模板会merge, 如果两个模板有相同的配置项,以模板order大的为准,不同的配置项则都会生效;建议设置一个单独的模板就行了,多个模板可能有问题。
建议:实际场景验证一下。
2.4 logstash数据监听
问题描述:
redis中的数据通过logstash直接入库到elasticsearch,项目使用的语言是java,目前的情况是,需要在elasticsearch中一有新数据,就要做一些其他的操作,不知道有没有什么方案,类似监听elasticsearch数据是否更新、增加的机制来实现
解决方案:elasticsearch alert有类似功能,可以看一下。
3、Kibana
3.1 Kibana中有几个Dashboard,可否对每个Dashboard分配权限,使其能够开放给指定人群浏览?
space的出现的目的就是相同公司不同部门实现不同权限的。可以参考。
3.2 kibana dev tools中文输入有问题
这是kibana低版本的bug,高版本已经修复。kibana6.6已经不存在。
铭毅天下——Elasticsearch基础、进阶、实战第一公众号