社区日报 第56期 (2017-09-23)
http://t.cn/RCTbs2d
2. es6.0节省了更多的存储空间,你知道原因吗?
http://t.cn/R0LvDlt
3. 一个用elasticsearch追踪网站点击的案例
http://t.cn/R9kMs8G
编辑:bsll
归档:https://www.elasticsearch.cn/article/292
订阅:https://tinyletter.com/elastic-daily
http://t.cn/RCTbs2d
2. es6.0节省了更多的存储空间,你知道原因吗?
http://t.cn/R0LvDlt
3. 一个用elasticsearch追踪网站点击的案例
http://t.cn/R9kMs8G
编辑:bsll
归档:https://www.elasticsearch.cn/article/292
订阅:https://tinyletter.com/elastic-daily 收起阅读 »
社区日报 第55期 (2017-09-22)
http://t.cn/R0297wW
2、这一招,解决了mysql与elasticsearch删除同步的难题!
http://t.cn/R029ld9
3、ElasticPress | 基于Elasticsearch构建你的wordpress博客检索助手!
http://t.cn/R07kUUQ
编辑:laoyang360
归档:https://www.elasticsearch.cn/article/290
订阅:https://tinyletter.com/elastic-daily
http://t.cn/R0297wW
2、这一招,解决了mysql与elasticsearch删除同步的难题!
http://t.cn/R029ld9
3、ElasticPress | 基于Elasticsearch构建你的wordpress博客检索助手!
http://t.cn/R07kUUQ
编辑:laoyang360
归档:https://www.elasticsearch.cn/article/290
订阅:https://tinyletter.com/elastic-daily
收起阅读 »
【摩拜招聘】ES高级工程师
工作职责:
开发、维护ES,支持各种场景需求
开发、维护fluentd/flume/kafka等大数据产品
业务推动,解决大数据、高并发下的产品需求
跟进研究业界前沿技术,推动产品技术升级
职位要求:
1. 编程能力扎实,熟悉Java/C++/go中的一种,具有良好的数据结构、算法、操作系统等计算机基本知识;
2. 熟悉ElasticSearch/Lucene开源系统,有实际开发经验者优先;
3. 具有敏捷开发、完整产品生命周期开发者优先;
4. 学习能力强,善于独立思考,思维活跃,对技术有强烈激情;
欢迎投递简历:zhengchangshuai@mobike.com
薪资20K~50K
公司属于高速成长的独角兽,非常国际化的一家公司,具体感兴趣的请发简历到邮箱
工作职责:
开发、维护ES,支持各种场景需求
开发、维护fluentd/flume/kafka等大数据产品
业务推动,解决大数据、高并发下的产品需求
跟进研究业界前沿技术,推动产品技术升级
职位要求:
1. 编程能力扎实,熟悉Java/C++/go中的一种,具有良好的数据结构、算法、操作系统等计算机基本知识;
2. 熟悉ElasticSearch/Lucene开源系统,有实际开发经验者优先;
3. 具有敏捷开发、完整产品生命周期开发者优先;
4. 学习能力强,善于独立思考,思维活跃,对技术有强烈激情;
欢迎投递简历:zhengchangshuai@mobike.com
薪资20K~50K
公司属于高速成长的独角兽,非常国际化的一家公司,具体感兴趣的请发简历到邮箱 收起阅读 »
社区日报 第54期 (2017-09-21)
2.还在为设置es的分片数量纠结?一篇文章教你全部 http://t.cn/R0vFh2G
3.基于elasticsearch nested object的关联分析 http://t.cn/R0vFMG9
编辑:金桥
归档:https://elasticsearch.cn/article/287
订阅:https://tinyletter.com/elastic-daily
2.还在为设置es的分片数量纠结?一篇文章教你全部 http://t.cn/R0vFh2G
3.基于elasticsearch nested object的关联分析 http://t.cn/R0vFMG9
编辑:金桥
归档:https://elasticsearch.cn/article/287
订阅:https://tinyletter.com/elastic-daily 收起阅读 »
nginx和kibana/es集成
1、记录kibana的每个请求日志
2、kibana通过nginx连到es,可以实现负载均衡的请求es。
集成方法比较简单,在任意一台机器上安装nginx,nginx里配置es相关信息,kibana配置文件中的elasticsearch.url改成nginx相应的ip和监听端口即可。
nginx配置文件的主要内容如下:
upstream elasticsearch {
server 10.10.10.1:9200;
server 10.10.10.2:9200;
server 10.10.10.3:9200;
keepalive 10;
}
server {
listen 8888;
server_name hostname;
location / {
proxy_pass http://elasticsearch;
access_log_bypass_if ($request = 'HEAD / HTTP/1.1');
access_log_bypass_if ($request = 'GET /_nodes?filter_path=nodes.*.version%2Cnodes.*.http.publish_address%2Cnodes.*.ip HTTP/1.1');
access_log_bypass_if ($request = 'GET /_nodes/_local?filter_path=nodes.*.settings.tribe HTTP/1.1');
access_log_bypass_if ($request_body = '{\"docs\":[{\"_index\":\".kibana\",\"_type\":\"config\",\"_id\":\"5.5.1\"}]}');
access_log_bypass_if ($request = 'GET /_cluster/health/.kibana?timeout=5s HTTP/1.1');
access_log_bypass_if ($request = 'POST /.kibana/config/_search HTTP/1.1');
access_log_bypass_if ($request = 'GET /_cluster/settings?include_defaults=true&filter_path=**.script.engine.*.inline HTTP/1.1');
access_log_bypass_if ($request = 'GET /_aliases HTTP/1.1');
access_log_bypass_if ($request = 'GET /_mapping HTTP/1.1');
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}
upstream定义了es有哪些节点。另外,nginx加了日志过滤模块ngx_log_if,用来过滤kibana和es之间的心跳请求日志,这个模块可以在github上下载
1、记录kibana的每个请求日志
2、kibana通过nginx连到es,可以实现负载均衡的请求es。
集成方法比较简单,在任意一台机器上安装nginx,nginx里配置es相关信息,kibana配置文件中的elasticsearch.url改成nginx相应的ip和监听端口即可。
nginx配置文件的主要内容如下:
upstream elasticsearch {
server 10.10.10.1:9200;
server 10.10.10.2:9200;
server 10.10.10.3:9200;
keepalive 10;
}
server {
listen 8888;
server_name hostname;
location / {
proxy_pass http://elasticsearch;
access_log_bypass_if ($request = 'HEAD / HTTP/1.1');
access_log_bypass_if ($request = 'GET /_nodes?filter_path=nodes.*.version%2Cnodes.*.http.publish_address%2Cnodes.*.ip HTTP/1.1');
access_log_bypass_if ($request = 'GET /_nodes/_local?filter_path=nodes.*.settings.tribe HTTP/1.1');
access_log_bypass_if ($request_body = '{\"docs\":[{\"_index\":\".kibana\",\"_type\":\"config\",\"_id\":\"5.5.1\"}]}');
access_log_bypass_if ($request = 'GET /_cluster/health/.kibana?timeout=5s HTTP/1.1');
access_log_bypass_if ($request = 'POST /.kibana/config/_search HTTP/1.1');
access_log_bypass_if ($request = 'GET /_cluster/settings?include_defaults=true&filter_path=**.script.engine.*.inline HTTP/1.1');
access_log_bypass_if ($request = 'GET /_aliases HTTP/1.1');
access_log_bypass_if ($request = 'GET /_mapping HTTP/1.1');
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}
upstream定义了es有哪些节点。另外,nginx加了日志过滤模块ngx_log_if,用来过滤kibana和es之间的心跳请求日志,这个模块可以在github上下载 收起阅读 »
elasticsearch index、create和update的源码分析
社区里面有人问了如下一个问题:
执行 bulk 索引文档的时候,用 index 或者 create 类型并且自定义 doc id 的情况下,是否会像 update 一样每次都要去 get 一遍原始文档? 比如下面的这条命令:
POST _bulk
{ "index" : { "_index" : "test", "_type" : "type1", "_id" : "1" } }
{ "field1" : "value1" }
{ "create" : { "_index" : "test", "_type" : "type1", "_id" : "3" } }
{ "field1" : "value3" }
问题出现的原因是他们在 bulk 测试的时候遇到了写性能的问题,而正巧社区里面前几天有这么一个类似的帖子,说的是 es 5.x 版本里面做 update 操作的性能问题。虽然和这个问题不完全一致,但都涉及到 es 索引数据的部分。
侯捷老师说:“源码面前,了无秘密”,那我们就来简单看下 es 这部分的相关代码,以便回答开篇提出的问题。
准备工作
我是用 IntelliJ IDEA 来阅读 elasticsearch 源码的,操作也简单。操作步骤如下:
1.下载 es 源码,由于 es 的commit信息比较多,可以增加 --depth=1 只下载最近的commit,减少下载时间。
git clone https://github.com/elastic/elasticsearch.git --depth=1
2.安装 gradle,确保版本在 3.3 及以上,然后在源码目录下执行以下命令准备导入 IntelliJ IDEA 需要的文件
gradle idea
3.下载安装 IntelliJ IDEA,确保版本为 2017.2 及以上版本。安装完成后,将 elasticsearch 以 gradle 形式导入即可。
大家可以参考 elasticsearch 文档说明 和 elasticsearch 文档说明 这两篇文章,细节我这里就不赘述了。
另外我是分析的 5.5.0 分支,大家记得 checkout,防止行数对应不起来。另外由于 es 代码结构有些复杂,先不在这篇文章里面梳理整个流程了,直接说核心代码。
Index/Create 源码分析
es index 和 create 最终都会调用 org/elasticsearch/index/engine/InternalEngine.java 中下面的方法:
457 public IndexResult index(Index index) throws IOException
注意这里的 index 中包含有要写入的 doc, 简单画下该方法的执行流程图,代码这里就不贴了,刚兴趣的自己去看。
请结合上面的流程图来看相应的代码,整个逻辑应该还是很清晰的,接下来我们看 planIndexingAsPrimary 的逻辑。
558 private IndexingStrategy planIndexingAsPrimary(Index index) throws IOException {
这个方法最终返回一个 IndexingStrategy,即一个索引的策略,总共有如下几个策略:
- optimizedAppendOnly
- skipDueToVersionConflict
- processNormally
- overrideExistingAsIfNotThere
- skipAsStale
不同的策略对应了不同的处理逻辑,前面3个是常用的,我们来看下流程图。
这里的第一步判断 是否是自定义 doc id?这一步就是 es 对于日志类非自定义 doc id的优化,感兴趣的可以自己去看下代码,简单讲就是在非自定义 id 的情况下,直接将文档 add ,否则需要 update,而 update 比 add 成本高很多。
而第二个判断 检查版本号是否冲突? 涉及到是如何根据文档版本号来确认文档可写入,代码都在index.versionType().isVersionConflictForWrites方法里,逻辑也比较简单,不展开讲了,感兴趣的自己去看吧。
上面的流程图也比较清晰地列出了策略选择的逻辑,除去 optimizedAppendOnly 策略,其他都需要根据待写入文档的版本号来做出决策。接下来我们就看下获取文档版本号的方法。
389 private VersionValue resolveDocVersion(final Operation op) throws IOException {
该方法逻辑比较简单,主要分为2步:
- 尝试从 versionMap 中读取待写入文档的 version,也即从内存中读取。versionMap 会暂存还没有 commit 到磁盘的文档版本信息。
- 如果第 1 步中没有读到,则从 index 中读取,也即从文件中读取。
看到这里,开篇问题便有了答案。es 在 index 或者 create 的时候并不会 get 整个文档,而是只会获取文档的版本号做对比,而这个开销不会很大。
Update 源码分析
es update 的核心代码在 org/elasticsearch/action/update/UpdateHelper.java 中,具体方法如下:
public Result prepare(UpdateRequest request, IndexShard indexShard, LongSupplier nowInMillis) {
final GetResult getResult = indexShard.getService().get(request.type(), request.id(),
new String[]{RoutingFieldMapper.NAME, ParentFieldMapper.NAME, TTLFieldMapper.NAME, TimestampFieldMapper.NAME},
true, request.version(), request.versionType(), FetchSourceContext.FETCH_SOURCE);
return prepare(indexShard.shardId(), request, getResult, nowInMillis);
}
代码逻辑很清晰,分两步走:
- 获取待更新文档的数据
- 执行更新文档的操作
第 1 步最终会调用 InternalEngine 中的 get 方法,如下:
350 public GetResult get(Get get, Function<String, Searcher> searcherFactory, LongConsumer onRefresh) throws EngineException {
这里就接上开篇提到的社区问题中的源码分析了。代码就不展开讲了,感兴趣的自己去看吧。
update 操作需要先获取原始文档的原因也很简单,因为这里是允许用户做部分更新的,而 es 底层每次更新时要求必须是完整的文档(因为 lucene 的更新实际是删除老文档,新增新文档),如果不拿到原始数据的话,就不能组装出更新后的完整文档了。
因此,比较看重效率的业务,最好还是不要用 update 这种操作,直接用上面的 index 会更好一些。
总结
本文通过源码分析的方式解决了开篇提到的问题,答案简单总结在下面。
es 在 index 和 create 操作的时候,如果没有自定义 doc id,那么会使用 append 优化模式,否则会获取待写入文档的版本号,进行版本检查后再决定是否写入lucene。所以这里不会去做一个 get 操作,即获取完整的文档信息。
最后,记住侯捷老师的话:
源码面前,了无秘密!
查看更好的排版
社区里面有人问了如下一个问题:
执行 bulk 索引文档的时候,用 index 或者 create 类型并且自定义 doc id 的情况下,是否会像 update 一样每次都要去 get 一遍原始文档? 比如下面的这条命令:
POST _bulk
{ "index" : { "_index" : "test", "_type" : "type1", "_id" : "1" } }
{ "field1" : "value1" }
{ "create" : { "_index" : "test", "_type" : "type1", "_id" : "3" } }
{ "field1" : "value3" }
问题出现的原因是他们在 bulk 测试的时候遇到了写性能的问题,而正巧社区里面前几天有这么一个类似的帖子,说的是 es 5.x 版本里面做 update 操作的性能问题。虽然和这个问题不完全一致,但都涉及到 es 索引数据的部分。
侯捷老师说:“源码面前,了无秘密”,那我们就来简单看下 es 这部分的相关代码,以便回答开篇提出的问题。
准备工作
我是用 IntelliJ IDEA 来阅读 elasticsearch 源码的,操作也简单。操作步骤如下:
1.下载 es 源码,由于 es 的commit信息比较多,可以增加 --depth=1 只下载最近的commit,减少下载时间。
git clone https://github.com/elastic/elasticsearch.git --depth=1
2.安装 gradle,确保版本在 3.3 及以上,然后在源码目录下执行以下命令准备导入 IntelliJ IDEA 需要的文件
gradle idea
3.下载安装 IntelliJ IDEA,确保版本为 2017.2 及以上版本。安装完成后,将 elasticsearch 以 gradle 形式导入即可。
大家可以参考 elasticsearch 文档说明 和 elasticsearch 文档说明 这两篇文章,细节我这里就不赘述了。
另外我是分析的 5.5.0 分支,大家记得 checkout,防止行数对应不起来。另外由于 es 代码结构有些复杂,先不在这篇文章里面梳理整个流程了,直接说核心代码。
Index/Create 源码分析
es index 和 create 最终都会调用 org/elasticsearch/index/engine/InternalEngine.java 中下面的方法:
457 public IndexResult index(Index index) throws IOException
注意这里的 index 中包含有要写入的 doc, 简单画下该方法的执行流程图,代码这里就不贴了,刚兴趣的自己去看。
请结合上面的流程图来看相应的代码,整个逻辑应该还是很清晰的,接下来我们看 planIndexingAsPrimary 的逻辑。
558 private IndexingStrategy planIndexingAsPrimary(Index index) throws IOException {
这个方法最终返回一个 IndexingStrategy,即一个索引的策略,总共有如下几个策略:
- optimizedAppendOnly
- skipDueToVersionConflict
- processNormally
- overrideExistingAsIfNotThere
- skipAsStale
不同的策略对应了不同的处理逻辑,前面3个是常用的,我们来看下流程图。
这里的第一步判断 是否是自定义 doc id?这一步就是 es 对于日志类非自定义 doc id的优化,感兴趣的可以自己去看下代码,简单讲就是在非自定义 id 的情况下,直接将文档 add ,否则需要 update,而 update 比 add 成本高很多。
而第二个判断 检查版本号是否冲突? 涉及到是如何根据文档版本号来确认文档可写入,代码都在index.versionType().isVersionConflictForWrites方法里,逻辑也比较简单,不展开讲了,感兴趣的自己去看吧。
上面的流程图也比较清晰地列出了策略选择的逻辑,除去 optimizedAppendOnly 策略,其他都需要根据待写入文档的版本号来做出决策。接下来我们就看下获取文档版本号的方法。
389 private VersionValue resolveDocVersion(final Operation op) throws IOException {
该方法逻辑比较简单,主要分为2步:
- 尝试从 versionMap 中读取待写入文档的 version,也即从内存中读取。versionMap 会暂存还没有 commit 到磁盘的文档版本信息。
- 如果第 1 步中没有读到,则从 index 中读取,也即从文件中读取。
看到这里,开篇问题便有了答案。es 在 index 或者 create 的时候并不会 get 整个文档,而是只会获取文档的版本号做对比,而这个开销不会很大。
Update 源码分析
es update 的核心代码在 org/elasticsearch/action/update/UpdateHelper.java 中,具体方法如下:
public Result prepare(UpdateRequest request, IndexShard indexShard, LongSupplier nowInMillis) {
final GetResult getResult = indexShard.getService().get(request.type(), request.id(),
new String[]{RoutingFieldMapper.NAME, ParentFieldMapper.NAME, TTLFieldMapper.NAME, TimestampFieldMapper.NAME},
true, request.version(), request.versionType(), FetchSourceContext.FETCH_SOURCE);
return prepare(indexShard.shardId(), request, getResult, nowInMillis);
}
代码逻辑很清晰,分两步走:
- 获取待更新文档的数据
- 执行更新文档的操作
第 1 步最终会调用 InternalEngine 中的 get 方法,如下:
350 public GetResult get(Get get, Function<String, Searcher> searcherFactory, LongConsumer onRefresh) throws EngineException {
这里就接上开篇提到的社区问题中的源码分析了。代码就不展开讲了,感兴趣的自己去看吧。
update 操作需要先获取原始文档的原因也很简单,因为这里是允许用户做部分更新的,而 es 底层每次更新时要求必须是完整的文档(因为 lucene 的更新实际是删除老文档,新增新文档),如果不拿到原始数据的话,就不能组装出更新后的完整文档了。
因此,比较看重效率的业务,最好还是不要用 update 这种操作,直接用上面的 index 会更好一些。
总结
本文通过源码分析的方式解决了开篇提到的问题,答案简单总结在下面。
es 在 index 和 create 操作的时候,如果没有自定义 doc id,那么会使用 append 优化模式,否则会获取待写入文档的版本号,进行版本检查后再决定是否写入lucene。所以这里不会去做一个 get 操作,即获取完整的文档信息。
最后,记住侯捷老师的话:
源码面前,了无秘密!
查看更好的排版
收起阅读 »
社区日报 第53期 (2017-09-20)
http://t.cn/R0vpOVu
2. 基于Kibana的时序实践
http://t.cn/RCVj5Wm
3. 基于Vue的Elasticsearch可视化工具 比head更好用(github)
http://t.cn/Ro5WST3
编辑:江水
归档:https://elasticsearch.cn/article/284
订阅:https://tinyletter.com/elastic-daily
http://t.cn/R0vpOVu
2. 基于Kibana的时序实践
http://t.cn/RCVj5Wm
3. 基于Vue的Elasticsearch可视化工具 比head更好用(github)
http://t.cn/Ro5WST3
编辑:江水
归档:https://elasticsearch.cn/article/284
订阅:https://tinyletter.com/elastic-daily 收起阅读 »
社区日报 第52期 (2017-09-19)
2.看Logz如何构建一个完美的Kibana可视化系统。http://t.cn/Rpr21iH
3.易宝支付日志中心平台从0到1的搭建,值得借鉴。http://t.cn/Rpgse8D
编辑:叮咚光军
归档:https://elasticsearch.cn/article/283
订阅:https://tinyletter.com/elastic-daily
2.看Logz如何构建一个完美的Kibana可视化系统。http://t.cn/Rpr21iH
3.易宝支付日志中心平台从0到1的搭建,值得借鉴。http://t.cn/Rpgse8D
编辑:叮咚光军
归档:https://elasticsearch.cn/article/283
订阅:https://tinyletter.com/elastic-daily
收起阅读 »
Elasticsearch大文件检索性能提升20倍实践(干货)
Elasticsearch大文件检索性能提升20倍实践(干货)
感谢群内各位大神的帮助!现将遇到问题、问题排查、问题定位、优化处理分享给大家。
欢迎拍砖!
Elasticsearch大文件检索性能提升20倍实践(干货)
感谢群内各位大神的帮助!现将遇到问题、问题排查、问题定位、优化处理分享给大家。
欢迎拍砖! 收起阅读 »
社区日报 第51期 (2017-09-18)
http://t.cn/RpBZ8d7
2. 来看看国外最流行的协作工具slack是如何运用elk来做安全分析的。
http://t.cn/RpB26BH
3. 在 Kibana 中使用脚本字段(需梯子)。
http://t.cn/RpBLhDb
编辑:cyberdak
归档:https://www.elasticsearch.cn/article/281
订阅:https://tinyletter.com/elastic-daily
http://t.cn/RpBZ8d7
2. 来看看国外最流行的协作工具slack是如何运用elk来做安全分析的。
http://t.cn/RpB26BH
3. 在 Kibana 中使用脚本字段(需梯子)。
http://t.cn/RpBLhDb
编辑:cyberdak
归档:https://www.elasticsearch.cn/article/281
订阅:https://tinyletter.com/elastic-daily
收起阅读 »
社区日报 第50期 (2017-09-17)
http://t.cn/RpmnT8C
2. 使用Elasticsearch和grafana分析github项目。
http://t.cn/R9xXkZE
3. 第二届GrafanaCon谈话视频整理。
http://t.cn/RpmmMk3
编辑:至尊宝
归档:https://www.elasticsearch.cn/article/280
订阅:https://tinyletter.com/elastic-daily
http://t.cn/RpmnT8C
2. 使用Elasticsearch和grafana分析github项目。
http://t.cn/R9xXkZE
3. 第二届GrafanaCon谈话视频整理。
http://t.cn/RpmmMk3
编辑:至尊宝
归档:https://www.elasticsearch.cn/article/280
订阅:https://tinyletter.com/elastic-daily
收起阅读 »
社区日报 第49期 (2017-09-16)
http://t.cn/RpYDk2c
2. 手把手教你在Azure搭建ELK
http://t.cn/RpYsAG8
3. 你知道es可以执行包含多个词的同义词的词组查询吗?
http://t.cn/RpTvc5Z
编辑:bsll
归档:https://www.elasticsearch.cn/article/279
订阅:https://tinyletter.com/elastic-daily
http://t.cn/RpYDk2c
2. 手把手教你在Azure搭建ELK
http://t.cn/RpYsAG8
3. 你知道es可以执行包含多个词的同义词的词组查询吗?
http://t.cn/RpTvc5Z
编辑:bsll
归档:https://www.elasticsearch.cn/article/279
订阅:https://tinyletter.com/elastic-daily
收起阅读 »
为何要避免往ES里写入稀疏数据
https://www.elastic.co/guide/e ... rsity
Avoid sparsityedit
The data-structures behind Lucene, which Elasticsearch relies on in order to index and store data, work best with dense data, ie. when all documents have the same fields. This is especially true for fields that have norms enabled (which is the case for text fields by default) or doc values enabled (which is the case for numerics, date, ip and keyword by default).
The reason is that Lucene internally identifies documents with so-called doc ids, which are integers between 0 and the total number of documents in the index. These doc ids are used for communication between the internal APIs of Lucene: for instance searching on a term with a matchquery produces an iterator of doc ids, and these doc ids are then used to retrieve the value of the norm in order to compute a score for these documents. The way this norm lookup is implemented currently is by reserving one byte for each document. The norm value for a given doc id can then be retrieved by reading the byte at index doc_id. While this is very efficient and helps Lucene quickly have access to the norm values of every document, this has the drawback that documents that do not have a value will also require one byte of storage.
In practice, this means that if an index has M documents, norms will require M bytes of storage per field, even for fields that only appear in a small fraction of the documents of the index. Although slightly more complex with doc values due to the fact that doc values have multiple ways that they can be encoded depending on the type of field and on the actual data that the field stores, the problem is very similar. In case you wonder: fielddata, which was used in Elasticsearch pre-2.0 before being replaced with doc values, also suffered from this issue, except that the impact was only on the memory footprint since fielddata was not explicitly materialized on disk.
Note that even though the most notable impact of sparsity is on storage requirements, it also has an impact on indexing speed and search speed since these bytes for documents that do not have a field still need to be written at index time and skipped over at search time.
It is totally fine to have a minority of sparse fields in an index. But beware that if sparsity becomes the rule rather than the exception, then the index will not be as efficient as it could be.
This section mostly focused on norms and doc values because those are the two features that are most affected by sparsity. Sparsity also affect the efficiency of the inverted index (used to index text/keyword fields) and dimensional points (used to index geo_point and numerics) but to a lesser extent.
Here are some recommendations that can help avoid sparsity:
https://www.elastic.co/blog/index-vs-type
Fields that exist in one type will also consume resources for documents of types where this field does not exist. This is a general issue with Lucene indices: they don’t like sparsity. Sparse postings lists can’t be compressed efficiently because of high deltas between consecutive matches. And the issue is even worse with doc values: for speed reasons, doc values often reserve a fixed amount of disk space for every document, so that values can be addressed efficiently. This means that if Lucene establishes that it needs one byte to store all value of a given numeric field, it will also consume one byte for documents that don’t have a value for this field. Future versions of Elasticsearch will have improvements in this area but I would still advise you to model your data in a way that will limit sparsity as much as possible.
https://www.elastic.co/blog/sp ... ucene
[url=https://issues.apache.org/jira/browse/LUCENE-6863]https://issues.apache.org/jira/browse/LUCENE-6863[/url]
https://www.elastic.co/blog/el ... eased
https://www.elastic.co/guide/e ... rsity
Avoid sparsityedit
The data-structures behind Lucene, which Elasticsearch relies on in order to index and store data, work best with dense data, ie. when all documents have the same fields. This is especially true for fields that have norms enabled (which is the case for text fields by default) or doc values enabled (which is the case for numerics, date, ip and keyword by default).
The reason is that Lucene internally identifies documents with so-called doc ids, which are integers between 0 and the total number of documents in the index. These doc ids are used for communication between the internal APIs of Lucene: for instance searching on a term with a matchquery produces an iterator of doc ids, and these doc ids are then used to retrieve the value of the norm in order to compute a score for these documents. The way this norm lookup is implemented currently is by reserving one byte for each document. The norm value for a given doc id can then be retrieved by reading the byte at index doc_id. While this is very efficient and helps Lucene quickly have access to the norm values of every document, this has the drawback that documents that do not have a value will also require one byte of storage.
In practice, this means that if an index has M documents, norms will require M bytes of storage per field, even for fields that only appear in a small fraction of the documents of the index. Although slightly more complex with doc values due to the fact that doc values have multiple ways that they can be encoded depending on the type of field and on the actual data that the field stores, the problem is very similar. In case you wonder: fielddata, which was used in Elasticsearch pre-2.0 before being replaced with doc values, also suffered from this issue, except that the impact was only on the memory footprint since fielddata was not explicitly materialized on disk.
Note that even though the most notable impact of sparsity is on storage requirements, it also has an impact on indexing speed and search speed since these bytes for documents that do not have a field still need to be written at index time and skipped over at search time.
It is totally fine to have a minority of sparse fields in an index. But beware that if sparsity becomes the rule rather than the exception, then the index will not be as efficient as it could be.
This section mostly focused on norms and doc values because those are the two features that are most affected by sparsity. Sparsity also affect the efficiency of the inverted index (used to index text/keyword fields) and dimensional points (used to index geo_point and numerics) but to a lesser extent.
Here are some recommendations that can help avoid sparsity:
https://www.elastic.co/blog/index-vs-type
Fields that exist in one type will also consume resources for documents of types where this field does not exist. This is a general issue with Lucene indices: they don’t like sparsity. Sparse postings lists can’t be compressed efficiently because of high deltas between consecutive matches. And the issue is even worse with doc values: for speed reasons, doc values often reserve a fixed amount of disk space for every document, so that values can be addressed efficiently. This means that if Lucene establishes that it needs one byte to store all value of a given numeric field, it will also consume one byte for documents that don’t have a value for this field. Future versions of Elasticsearch will have improvements in this area but I would still advise you to model your data in a way that will limit sparsity as much as possible.
https://www.elastic.co/blog/sp ... ucene
[url=https://issues.apache.org/jira/browse/LUCENE-6863]https://issues.apache.org/jira/browse/LUCENE-6863[/url]
https://www.elastic.co/blog/el ... eased
收起阅读 »
社区日报 第48期 (2017-09-15)
http://t.cn/RpOCVsz
2.twitter数据导入Elasticsearch的三种方式。
http://t.cn/RpOC6An
3.CSV数据导入Elasticsearch及可视化方案。
http://t.cn/RCGeeJK
编辑:laoyang360
归档:https://www.elasticsearch.cn/article/276
订阅:https://tinyletter.com/elastic-daily
http://t.cn/RpOCVsz
2.twitter数据导入Elasticsearch的三种方式。
http://t.cn/RpOC6An
3.CSV数据导入Elasticsearch及可视化方案。
http://t.cn/RCGeeJK
编辑:laoyang360
归档:https://www.elasticsearch.cn/article/276
订阅:https://tinyletter.com/elastic-daily
收起阅读 »