好的想法是十分钱一打,真正无价的是能够实现这些想法的人。

社区日报 第490期 (2018-12-26)

1. Elastic Stack实战学习教程 日志数据的收集、分析与可视化
http://t.cn/EbPvOva
2. 新浪是如何分析处理32亿条实时日志的
http://t.cn/RUuylp6
3. 苏宁大数据离线任务开发调度平台实践
http://t.cn/EbP7Kav

编辑:江水
归档:https://elasticsearch.cn/article/6224
订阅:https://tinyletter.com/elastic-daily
继续阅读 »
1. Elastic Stack实战学习教程 日志数据的收集、分析与可视化
http://t.cn/EbPvOva
2. 新浪是如何分析处理32亿条实时日志的
http://t.cn/RUuylp6
3. 苏宁大数据离线任务开发调度平台实践
http://t.cn/EbP7Kav

编辑:江水
归档:https://elasticsearch.cn/article/6224
订阅:https://tinyletter.com/elastic-daily 收起阅读 »

社区日报 第489期 (2018-12-25)

1、用ElasticSearch搭建自己的搜索和分析引擎
http://t.cn/E4n6of8
2、Elasticsearch 集群性能的最佳实践
http://t.cn/E4n6M3v
3、海量数据下Elasticsearch搜索引擎分析与搭建
http://t.cn/R3bde2J

编辑:叮咚光军
归档:https://elasticsearch.cn/article/6223
订阅:https://tinyletter.com/elastic-daily
继续阅读 »
1、用ElasticSearch搭建自己的搜索和分析引擎
http://t.cn/E4n6of8
2、Elasticsearch 集群性能的最佳实践
http://t.cn/E4n6M3v
3、海量数据下Elasticsearch搜索引擎分析与搭建
http://t.cn/R3bde2J

编辑:叮咚光军
归档:https://elasticsearch.cn/article/6223
订阅:https://tinyletter.com/elastic-daily 收起阅读 »

访谈:2亿+ vivo 手机背后搜索服务平台的故事

欢迎来到 Elastic 社区电台的第九期节目,我们本期节目的嘉宾是来自于 vivo 互联网负责搜索业务研发的杨振涛,vivo 从 Elasticsearch 2.1.1 版本开始,如今使用 100 多个 Elasticsearch 集群来支撑全球 2 亿多台手机每天的各种搜索请求,如 vivo 的应用商店、游戏、音乐、主题、壁纸、铃声等各种手机服务背后的搜索服务,也包括产品配件、售后、FAQ 等企业门户官网的搜索请求。今天让我们一起走进 vivo,看看 vivo 具体是如何使用 Elasticsearch 来解决这些搜索问题的。

可以点击下面的任意链接来收听(时长约 50 分钟):

嘉宾

podcast_vivo_banner720x420.jpg

杨振涛,vivo 互联网搜索引擎架构师,专注于数据的存储、检索与可视化,以及 DevOps 与软件过程改进。Elastic 中文社区深圳地区负责人,发起并组织 Elasticsearch、Redis、Jenkins 等主题的技术沙龙,并参与多个开源项目的文档翻译和中文化工作。 技术翻译爱好者,InfoQ 中文社区编辑,TED Translator。

主持人

Elastic 技术布道师,曾勇(Medcl)。

关于 vivo

vivo为一个专注于智能手机领域的手机品牌,vivo和追求乐趣、充满活力、年轻时尚的群体一起打造拥有卓越外观、专业级音质、极致影像、愉悦体验的智能产品,并将敢于追求极致、持续创造惊喜作为vivo的坚定追求。

关于 Elastic 社区电台

Elastic 开源社区举办的一款播客类节目, 邀请来自开源社区的用户,一起聊聊 Elastic 开源产品的使用案例、经验分享、架构变迁等等。

相关链接

继续阅读 »

欢迎来到 Elastic 社区电台的第九期节目,我们本期节目的嘉宾是来自于 vivo 互联网负责搜索业务研发的杨振涛,vivo 从 Elasticsearch 2.1.1 版本开始,如今使用 100 多个 Elasticsearch 集群来支撑全球 2 亿多台手机每天的各种搜索请求,如 vivo 的应用商店、游戏、音乐、主题、壁纸、铃声等各种手机服务背后的搜索服务,也包括产品配件、售后、FAQ 等企业门户官网的搜索请求。今天让我们一起走进 vivo,看看 vivo 具体是如何使用 Elasticsearch 来解决这些搜索问题的。

可以点击下面的任意链接来收听(时长约 50 分钟):

嘉宾

podcast_vivo_banner720x420.jpg

杨振涛,vivo 互联网搜索引擎架构师,专注于数据的存储、检索与可视化,以及 DevOps 与软件过程改进。Elastic 中文社区深圳地区负责人,发起并组织 Elasticsearch、Redis、Jenkins 等主题的技术沙龙,并参与多个开源项目的文档翻译和中文化工作。 技术翻译爱好者,InfoQ 中文社区编辑,TED Translator。

主持人

Elastic 技术布道师,曾勇(Medcl)。

关于 vivo

vivo为一个专注于智能手机领域的手机品牌,vivo和追求乐趣、充满活力、年轻时尚的群体一起打造拥有卓越外观、专业级音质、极致影像、愉悦体验的智能产品,并将敢于追求极致、持续创造惊喜作为vivo的坚定追求。

关于 Elastic 社区电台

Elastic 开源社区举办的一款播客类节目, 邀请来自开源社区的用户,一起聊聊 Elastic 开源产品的使用案例、经验分享、架构变迁等等。

相关链接

收起阅读 »

Day 25 - Elasticsearch Ingest节点数据管道处理器

​首先还是祝大家圣诞快乐,既然是节日,我们就讨论一个比较轻松的话题。如何使用6.5引入数据管道处理器来更好的治理预定义好的数据管道。

背景

2018这一年来拜访了很多用户,其中有相当一部分在数据摄取时遇到包括性能在内的各种各样的问题,那么大多数在我们做了ingest节点的调整后得到了很好的解决。Ingest节点不是万能的,但是使用起来简单,而且抛开后面数据节点来看性能提升趋于线性。所以我一直本着能用ingest节点解决的问题,绝不麻烦其他组件的大体原则 :-)

下面快速回顾一下ingest节点的角色定位。

ingest.png

使用场景

通过上面的图纸我们很容易看到ingest节点可以在数据被索引之前,通过预定义好的处理管道对其进行治理。但这里一直存在一个局限性,就是只能通过一条管道。那么一直以来应对这个不便的方案就是把所有的处理器和细节全部配置到当前管道下。那么带来的问题也是比较明显的:

  • 复制、粘贴很多相同的管道配置在不同数据管道里
  • 非常难管理、维护冗长的管道
  • 如果要更新一个处理细节的话要找到定位所有使用过这个逻辑的管道

其实这块对于开发的同学们很好理解,当你经常复制、粘贴代码的时候,就是时候好好思考一下了。我想说到这里大家其实已经明白了,这个管道处理器实际就是提供了一个允许你在一个管道内调用其他管道的方案。

他的使用非常简单,就像函数调用一样只有一个必要参数name

{
  "pipeline": {
    "name": "<其他管道的名称 - 英文字符>"
  }
}

当然,也像其他处理器一样提供了on_failure参数来处理错误,并且还有一个非常实用的if参数来判断是否执行这个管道,这里就不做详细介绍了。

举例

这里我们用一个非常简单的案例来看看如何使用管道处理器。

假设在Elastic公司,我们使用员工卡来作为进入公司和各个部门以及房间的钥匙,并且这些刷卡事件也会被记录下来。那么由于上班卡机和门禁供应商不同,数据格式也不一样。但是最后都有一个通用的逻辑,就是除了事件发生的时间,我们还会记录下数据录入到Elasticsearch的时间。

首先我们看一下原始数据:

# 公司正门卡机数据
2018-12-25T08:59:59.312Z,front_door,binw,entered

# 架构部门禁数据
@timestamp=2018-12-25T09:15:34.414Z device_id=recreation_hall user=binw event=entered

那如果在6.5之前,我们定义2条管道是这个样子

  1. 正门卡机管道

    • grok 解析数据
    • 打上数据录入的时间戳
    • 明确录入时间戳的处理器
  2. 门禁数据管道
    • KV 解析数据
    • 打上数据录入的时间戳
    • 明确录入时间戳的处理器

很明显又66.67%的配置都是重复的,所以这里我们可以更优雅的解决这个问题

  1. 统一的数据录入时间戳处理器
    • 打上数据录入的时间戳
    • 明确录入时间戳的处理器
PUT _ingest/pipeline/pl_cmn
{
  "description": "刷卡数据通用管道",
  "processors": [
    {
      "set": {
        "field": "ingest_timestamp",
        "value": "{{_ingest.timestamp}}"
      }
    },
    {
      "set": {
        "field": "cmn_processed",
        "value": "yes"
      }
    }
  ]
}
  1. 正门卡机管道
    • grok 解析数据
    • <调用管道 pl_cmn>
POST _ingest/pipeline/_simulate
{
  "pipeline": {
    "description": "正门打卡机数据处理管道",
    "processors": [
      {
        "grok": {
          "field": "message",
          "patterns": [
            "%{TIMESTAMP_ISO8601:@timestamp},%{WORD:device_id},%{USER:user},%{WORD:event}"
          ]
        }
      },
      {
        "pipeline": {
          "name": "pl_cmn"
        }
      }
    ]
  },
  "docs": [
    {
      "_source": {
        "message": "2018-12-25T08:59:59.312Z,front_door,binw,entered"
      }
    }
  ]
}
  1. 门禁数据管道
    • KV 解析数据
    • <调用管道 pl_cmn>
POST _ingest/pipeline/_simulate
{
  "pipeline": {
    "description": "架构部门禁数据处理管道",
    "processors": [
      {
        "kv": {
          "field": "message",
          "field_split": " ",
          "value_split": "="
        }
      },
      {
        "pipeline": {
          "name": "pl_cmn"
        }
      }
    ]
  },
  "docs": [
    {
      "_source": {
        "message": "@timestamp=2018-12-25T09:15:34.414Z device_id=recreation_hall user=binw event=entered"
      }
    }
  ]
}

好啦,这个例子非常简单。但当面对复杂业务场景的时候,会让你整个数据管道的管理比以前整齐很多。再结合合理的架构和数据治理,ingest节点也可以让你的整个数据处理能力有所提升。

写在最后

在文章的例子里,我们往索引里灌注的是一个个的事件数据。那要如何对数据中的实体进行有效的分析呢?那不得不说到面向实体的数据模型设计。Elasticsearch本身也提供了工具能让我们快速实现,让我们明年有机会的时候再与大家分享吧。最后还是祝愿大家度过一个愉快的圣诞节和元旦!

继续阅读 »

​首先还是祝大家圣诞快乐,既然是节日,我们就讨论一个比较轻松的话题。如何使用6.5引入数据管道处理器来更好的治理预定义好的数据管道。

背景

2018这一年来拜访了很多用户,其中有相当一部分在数据摄取时遇到包括性能在内的各种各样的问题,那么大多数在我们做了ingest节点的调整后得到了很好的解决。Ingest节点不是万能的,但是使用起来简单,而且抛开后面数据节点来看性能提升趋于线性。所以我一直本着能用ingest节点解决的问题,绝不麻烦其他组件的大体原则 :-)

下面快速回顾一下ingest节点的角色定位。

ingest.png

使用场景

通过上面的图纸我们很容易看到ingest节点可以在数据被索引之前,通过预定义好的处理管道对其进行治理。但这里一直存在一个局限性,就是只能通过一条管道。那么一直以来应对这个不便的方案就是把所有的处理器和细节全部配置到当前管道下。那么带来的问题也是比较明显的:

  • 复制、粘贴很多相同的管道配置在不同数据管道里
  • 非常难管理、维护冗长的管道
  • 如果要更新一个处理细节的话要找到定位所有使用过这个逻辑的管道

其实这块对于开发的同学们很好理解,当你经常复制、粘贴代码的时候,就是时候好好思考一下了。我想说到这里大家其实已经明白了,这个管道处理器实际就是提供了一个允许你在一个管道内调用其他管道的方案。

他的使用非常简单,就像函数调用一样只有一个必要参数name

{
  "pipeline": {
    "name": "<其他管道的名称 - 英文字符>"
  }
}

当然,也像其他处理器一样提供了on_failure参数来处理错误,并且还有一个非常实用的if参数来判断是否执行这个管道,这里就不做详细介绍了。

举例

这里我们用一个非常简单的案例来看看如何使用管道处理器。

假设在Elastic公司,我们使用员工卡来作为进入公司和各个部门以及房间的钥匙,并且这些刷卡事件也会被记录下来。那么由于上班卡机和门禁供应商不同,数据格式也不一样。但是最后都有一个通用的逻辑,就是除了事件发生的时间,我们还会记录下数据录入到Elasticsearch的时间。

首先我们看一下原始数据:

# 公司正门卡机数据
2018-12-25T08:59:59.312Z,front_door,binw,entered

# 架构部门禁数据
@timestamp=2018-12-25T09:15:34.414Z device_id=recreation_hall user=binw event=entered

那如果在6.5之前,我们定义2条管道是这个样子

  1. 正门卡机管道

    • grok 解析数据
    • 打上数据录入的时间戳
    • 明确录入时间戳的处理器
  2. 门禁数据管道
    • KV 解析数据
    • 打上数据录入的时间戳
    • 明确录入时间戳的处理器

很明显又66.67%的配置都是重复的,所以这里我们可以更优雅的解决这个问题

  1. 统一的数据录入时间戳处理器
    • 打上数据录入的时间戳
    • 明确录入时间戳的处理器
PUT _ingest/pipeline/pl_cmn
{
  "description": "刷卡数据通用管道",
  "processors": [
    {
      "set": {
        "field": "ingest_timestamp",
        "value": "{{_ingest.timestamp}}"
      }
    },
    {
      "set": {
        "field": "cmn_processed",
        "value": "yes"
      }
    }
  ]
}
  1. 正门卡机管道
    • grok 解析数据
    • <调用管道 pl_cmn>
POST _ingest/pipeline/_simulate
{
  "pipeline": {
    "description": "正门打卡机数据处理管道",
    "processors": [
      {
        "grok": {
          "field": "message",
          "patterns": [
            "%{TIMESTAMP_ISO8601:@timestamp},%{WORD:device_id},%{USER:user},%{WORD:event}"
          ]
        }
      },
      {
        "pipeline": {
          "name": "pl_cmn"
        }
      }
    ]
  },
  "docs": [
    {
      "_source": {
        "message": "2018-12-25T08:59:59.312Z,front_door,binw,entered"
      }
    }
  ]
}
  1. 门禁数据管道
    • KV 解析数据
    • <调用管道 pl_cmn>
POST _ingest/pipeline/_simulate
{
  "pipeline": {
    "description": "架构部门禁数据处理管道",
    "processors": [
      {
        "kv": {
          "field": "message",
          "field_split": " ",
          "value_split": "="
        }
      },
      {
        "pipeline": {
          "name": "pl_cmn"
        }
      }
    ]
  },
  "docs": [
    {
      "_source": {
        "message": "@timestamp=2018-12-25T09:15:34.414Z device_id=recreation_hall user=binw event=entered"
      }
    }
  ]
}

好啦,这个例子非常简单。但当面对复杂业务场景的时候,会让你整个数据管道的管理比以前整齐很多。再结合合理的架构和数据治理,ingest节点也可以让你的整个数据处理能力有所提升。

写在最后

在文章的例子里,我们往索引里灌注的是一个个的事件数据。那要如何对数据中的实体进行有效的分析呢?那不得不说到面向实体的数据模型设计。Elasticsearch本身也提供了工具能让我们快速实现,让我们明年有机会的时候再与大家分享吧。最后还是祝愿大家度过一个愉快的圣诞节和元旦!

收起阅读 »

社区日报 第488期 (2018-12-24)

1.聊聊 ElasticSearch 使用场景
http://t.cn/E4QEI6q
2.让 Elasticsearch 飞起来:性能优化实践干货
http://t.cn/E4Q3cbj
3.Filebeat issue 排查  : i/o timeout
http://t.cn/E4Q3Bhz

编辑:cyberdak
归档:https://elasticsearch.cn/article/6220
订阅:https://tinyletter.com/elastic-daily
继续阅读 »
1.聊聊 ElasticSearch 使用场景
http://t.cn/E4QEI6q
2.让 Elasticsearch 飞起来:性能优化实践干货
http://t.cn/E4Q3cbj
3.Filebeat issue 排查  : i/o timeout
http://t.cn/E4Q3Bhz

编辑:cyberdak
归档:https://elasticsearch.cn/article/6220
订阅:https://tinyletter.com/elastic-daily 收起阅读 »

Day 23 - 基于 HanLP 的 ES 中文分词插件

一、分词插件

1、分词器概念

在 ES 中,分词器的作用是从文本中提取出若干词元(token)来支持索引的存储和搜索,分词器(Analyzer)由一个分解器(Tokenizer)、零个或多个词元过滤器(TokenFilter)组成。

分解器用于将字符串分解成一系列词元,词元过滤器的作用是对分词器提取出来的词元做进一步处理,比如转成小写,增加同义词等。处理后的结果称为索引词(Term),引擎会建立 Term 和原文档的倒排索引(Inverted Index),这样就能根据 Term 很快到找到源文档了。

文本分词并索引的过程

2、选择分词器

目前 ES 分词插件的选择性还是很多的,分词插件的核心就是提供各种分词器(Analyzer)、分解器(Tokenizer)、词元过滤器(TokenFilter);根据依赖的核心分词包(分词算法)的不同显现出不同的差异性,除了分词算法之外,是否支持用户自定义词典,是否支持词典热更新等其他附加功能也是选择分词插件时需要参考的。

下面列出选择分词插件需要考虑的因素(仅供参考):

  • 分词准确性:大家都希望分词结果能够尽可能准确,与分词准确性直接相关的就是用户词典了,此外才是分词算法;
  • 分词算法:个人认为无需纠结于分词算法,大多数分词包提供的分词算法都比较类似,选择时不需要过于纠结;
  • 分词速度:这个与分词算法直接相关,基于词典的分词算法一般比基于模型的分词算法要快;基于词典如果考虑词频、命名实体识别、词性标注则会慢一些;
  • 启动速度:当词典较大时,初始化词典会比较慢,某些分词器会对词典进行缓存,第二次启动会非常速度;
  • 内存占用:与分词算法、词典大小、模型大小均有关系,设计精巧的算法对内存占用较小;
  • 易用性:分词器是否开箱即用,是否可以直接使用在线链接或者压缩包进行安装,是否需要复杂的配置;
  • 扩展性:是否支持用户自定义词典、是否支持自定义分词算法、是否支持热更新等;
  • 是否开源:开源的分词器在遇到问题的时候可以自己进行深度调试,甚至可以进行二次开发;
  • 社区活跃度:这个看一下 github 的 star 数或者依赖的分词包的 star 数和 issue 数目即可判定;
  • 更新频率:是否能够与最新版的 ES 同步更新。

二、HanLP 简介

HanLP 是一系列模型与算法组成的 NLP 工具包,具备功能完善、性能高效、架构清晰、语料时新、可自定义的特点,详情可参考 github 介绍:https://github.com/hankcs/HanLP

选择 HanLP 作为核心的分词包开发 ES 分词插件,主要考虑以下因素:

  • HanLP 是 Java 分词包中最为流行的;
  • HanLP 提供了多种分词器,既可以基于词典也可以基于模型(在一亿字的大型综合语料库上训练的分词模型);
  • HanLP 坚持使用明文词典,这样可以借助社区的力量对词典不断进行完善;
  • 完善的开发文档和代码样例,较为活跃的用户群体;
  • 个人参与了部分功能的开发,对代码结构较为熟悉。

三、开发分词插件

1、代码结构

  • conf:插件的配置文件、HanLP 的配置文件、Java 安全策略文件;
  • scr.main.java.assemby:插件打包(maven-assembly-plugin)配置文件;
  • org.elasticsearch.plugin.hanlp.analysis:分词插件核心构建器;
  • org.elasticsearch.plugin.hanlp.conf:管理插件配置、分词器配置以及 HanLP 配置;
  • org.elasticsearch.plugin.hanlp.lucene:HanLP 中文分词 Lucene 插件,对 Lucune 分词进行实现;
  • scr.main.resources:插件属性文件所在目录

插件代码结构

2、TokenStream

Analyzer 类是一个抽象类,是所有分词器的基类,它通过 TokenStream 类将文本转换为词汇单元流;TokenStream 有两种实现 Tokenizer(输入为 Reader) 和 TokenFilter(输入为另一个 TokenStream)。

文本分词流程

TokenStream 基本使用流程:

  1. 实例化 TokenStream,向 AttributeSource 添加/获取属性(词汇单元文本、位置增量、偏移量、词汇类型等);
  2. 调用 reset() 方法,将流(stream)重置到原始(clean)状态;
  3. 循环调用 incrementToken() 方法,并处理 Attribute 属性信息,直到它返回 false 表示流处理结束;
  4. 调用 end() 方法,确保流结束(end-of-stream)的操作可以被执行;
  5. 调用 close() 方法释放资源。
// 实例化 TokenStream
TokenStream tokenStream = new IKAnalyzer().tokenStream("keywords",new StringReader("思想者"));
// 向 AttributeSource 添加/获取属性
CharTermAttribute attribute = tokenStream.addAttribute(CharTermAttribute.class);
// 将流(stream)重置到原始(clean)状态
tokenStream.reset();
// 判断是否还有下一个 Token
while(tokenStream.incrementToken()) {
  System.out.println(attribute);
}
tokenStream.end();
tokenStream.close();

综上,开发 Tokenizer 或者 TokenFilter 时,需要重点关注 reset、incrementToken、end、close 四个方法的实现。

3、开发中的小技巧

获取插件目录或文件目录

//获取插件根目录
private static Path getPluginPath() {
    return env.pluginsFile().resolve("analysis-hanlp");
}
//获取插件目录下的文件
private static Path getDefDicConfigPath() {
    return env.pluginsFile().resolve("analysis-hanlp/hanlp.properties").toAbsolutePath();
}

插件属性文件

如果希望插件属性文件(plugin-descriptor.properties)能够自动根据 pom.xml 中的属性进行赋值,则需要将文件防止到 resources 文件夹下。

插件版本兼容性

从实际测试来看:

  • ES5.X 及其以上的代码是完全复用的,也就是说代码逻辑不需要调整;
  • ES5.X 到 ES6.2.X 的插件是可以通用的,其特征是打包的时候需要将插件的文件全部打包到 elasticsearch 文件夹下;
  • ES6.3.X 以上的插件是可以通用的,打包的时候插件的文件全部打包到根目录即可。

也就是说,如果你升级了新版本 ES,对于插件升级,大多数情况只需要修改下 plugin-descriptor.properties 文件中 ES 的版本号即可。

4、安全策略文件

在插件开发中经常会使用到文件读取、属性读取、网络链接等功能,如果不提前注册安全策略,在调用这些功能的时候会报以下错误java.security.AccessControlException: access denied

官方给出的解决方案就是新建一个 plugin-security.policy 文件,然后在文件中声明需要的权限信息,最后在打包的时候将文件放置到插件的根目录,这样在使用 zip 包进行安装的时候,ES 会提示用户插件所需的权限信息,需要用户确认后插件才能正常安装。

@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@     WARNING: plugin requires additional permissions     @
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
* java.io.FilePermission <<ALL FILES>> read,write,delete
* java.lang.RuntimePermission createClassLoader
* java.lang.RuntimePermission getClassLoader
* java.lang.RuntimePermission setContextClassLoader
* java.net.SocketPermission * connect,resolve
* java.util.PropertyPermission * read,write
See http://docs.oracle.com/javase/8/docs/technotes/guides/security/permissions.html
for descriptions of what these permissions allow and the associated risks.

Continue with installation? [y/N]y
-> Installed analysis-hanlp

5、安全策略的坑

最开始认为只需要添加了 policy 文件,且打包到正确的位置即可解决插件的权限问题,因为在插件安装的时候 ES 已经提示了所需权限,但是代码在实际执行的时候依旧报 AccessControlException 的错误。

参考了多个 HanLP 的 ES 分词插件,都没有获得较好的方法,后来考虑到 IK 分词器远程加载词典时,需要网络连接权限,就去看了下其远程词典加载的代码,最终找到了正确的使用方法。

// 需要特殊权限的代码
AccessController.doPrivileged((PrivilegedAction<Segment>) () -> {
    Segment segment;
    if (config.getAlgorithm().equals("extend")) {
        segment = new ViterbiSegment();
    } else {
        segment = HanLP.newSegment(config.getAlgorithm());
    }
    // 在此处显示调用一下分词,使得加载词典、缓存词典的操作可以正确执行
    System.out.println( segment.seg("HanLP中文分词工具包!"));
    return segment;
});

四、插件特色

简单介绍一下插件的特点:

  • 内置多种分词模式,适合不同场景;
  • 内置词典,无需额外配置即可使用;
  • 支持外置词典,用户可自定义分词算法,基于词典或是模型;
  • 支持分词器级别的自定义词典,便于用于多租户场景;
  • 支持远程词典热更新(待开发);
  • 拼音过滤器、繁简体过滤器(待开发);
  • 基于词语或单字的 ngram 切分分词(待开发)。

Github 地址:https://github.com/AnyListen/elasticsearch-analysis-hanlp

继续阅读 »

一、分词插件

1、分词器概念

在 ES 中,分词器的作用是从文本中提取出若干词元(token)来支持索引的存储和搜索,分词器(Analyzer)由一个分解器(Tokenizer)、零个或多个词元过滤器(TokenFilter)组成。

分解器用于将字符串分解成一系列词元,词元过滤器的作用是对分词器提取出来的词元做进一步处理,比如转成小写,增加同义词等。处理后的结果称为索引词(Term),引擎会建立 Term 和原文档的倒排索引(Inverted Index),这样就能根据 Term 很快到找到源文档了。

文本分词并索引的过程

2、选择分词器

目前 ES 分词插件的选择性还是很多的,分词插件的核心就是提供各种分词器(Analyzer)、分解器(Tokenizer)、词元过滤器(TokenFilter);根据依赖的核心分词包(分词算法)的不同显现出不同的差异性,除了分词算法之外,是否支持用户自定义词典,是否支持词典热更新等其他附加功能也是选择分词插件时需要参考的。

下面列出选择分词插件需要考虑的因素(仅供参考):

  • 分词准确性:大家都希望分词结果能够尽可能准确,与分词准确性直接相关的就是用户词典了,此外才是分词算法;
  • 分词算法:个人认为无需纠结于分词算法,大多数分词包提供的分词算法都比较类似,选择时不需要过于纠结;
  • 分词速度:这个与分词算法直接相关,基于词典的分词算法一般比基于模型的分词算法要快;基于词典如果考虑词频、命名实体识别、词性标注则会慢一些;
  • 启动速度:当词典较大时,初始化词典会比较慢,某些分词器会对词典进行缓存,第二次启动会非常速度;
  • 内存占用:与分词算法、词典大小、模型大小均有关系,设计精巧的算法对内存占用较小;
  • 易用性:分词器是否开箱即用,是否可以直接使用在线链接或者压缩包进行安装,是否需要复杂的配置;
  • 扩展性:是否支持用户自定义词典、是否支持自定义分词算法、是否支持热更新等;
  • 是否开源:开源的分词器在遇到问题的时候可以自己进行深度调试,甚至可以进行二次开发;
  • 社区活跃度:这个看一下 github 的 star 数或者依赖的分词包的 star 数和 issue 数目即可判定;
  • 更新频率:是否能够与最新版的 ES 同步更新。

二、HanLP 简介

HanLP 是一系列模型与算法组成的 NLP 工具包,具备功能完善、性能高效、架构清晰、语料时新、可自定义的特点,详情可参考 github 介绍:https://github.com/hankcs/HanLP

选择 HanLP 作为核心的分词包开发 ES 分词插件,主要考虑以下因素:

  • HanLP 是 Java 分词包中最为流行的;
  • HanLP 提供了多种分词器,既可以基于词典也可以基于模型(在一亿字的大型综合语料库上训练的分词模型);
  • HanLP 坚持使用明文词典,这样可以借助社区的力量对词典不断进行完善;
  • 完善的开发文档和代码样例,较为活跃的用户群体;
  • 个人参与了部分功能的开发,对代码结构较为熟悉。

三、开发分词插件

1、代码结构

  • conf:插件的配置文件、HanLP 的配置文件、Java 安全策略文件;
  • scr.main.java.assemby:插件打包(maven-assembly-plugin)配置文件;
  • org.elasticsearch.plugin.hanlp.analysis:分词插件核心构建器;
  • org.elasticsearch.plugin.hanlp.conf:管理插件配置、分词器配置以及 HanLP 配置;
  • org.elasticsearch.plugin.hanlp.lucene:HanLP 中文分词 Lucene 插件,对 Lucune 分词进行实现;
  • scr.main.resources:插件属性文件所在目录

插件代码结构

2、TokenStream

Analyzer 类是一个抽象类,是所有分词器的基类,它通过 TokenStream 类将文本转换为词汇单元流;TokenStream 有两种实现 Tokenizer(输入为 Reader) 和 TokenFilter(输入为另一个 TokenStream)。

文本分词流程

TokenStream 基本使用流程:

  1. 实例化 TokenStream,向 AttributeSource 添加/获取属性(词汇单元文本、位置增量、偏移量、词汇类型等);
  2. 调用 reset() 方法,将流(stream)重置到原始(clean)状态;
  3. 循环调用 incrementToken() 方法,并处理 Attribute 属性信息,直到它返回 false 表示流处理结束;
  4. 调用 end() 方法,确保流结束(end-of-stream)的操作可以被执行;
  5. 调用 close() 方法释放资源。
// 实例化 TokenStream
TokenStream tokenStream = new IKAnalyzer().tokenStream("keywords",new StringReader("思想者"));
// 向 AttributeSource 添加/获取属性
CharTermAttribute attribute = tokenStream.addAttribute(CharTermAttribute.class);
// 将流(stream)重置到原始(clean)状态
tokenStream.reset();
// 判断是否还有下一个 Token
while(tokenStream.incrementToken()) {
  System.out.println(attribute);
}
tokenStream.end();
tokenStream.close();

综上,开发 Tokenizer 或者 TokenFilter 时,需要重点关注 reset、incrementToken、end、close 四个方法的实现。

3、开发中的小技巧

获取插件目录或文件目录

//获取插件根目录
private static Path getPluginPath() {
    return env.pluginsFile().resolve("analysis-hanlp");
}
//获取插件目录下的文件
private static Path getDefDicConfigPath() {
    return env.pluginsFile().resolve("analysis-hanlp/hanlp.properties").toAbsolutePath();
}

插件属性文件

如果希望插件属性文件(plugin-descriptor.properties)能够自动根据 pom.xml 中的属性进行赋值,则需要将文件防止到 resources 文件夹下。

插件版本兼容性

从实际测试来看:

  • ES5.X 及其以上的代码是完全复用的,也就是说代码逻辑不需要调整;
  • ES5.X 到 ES6.2.X 的插件是可以通用的,其特征是打包的时候需要将插件的文件全部打包到 elasticsearch 文件夹下;
  • ES6.3.X 以上的插件是可以通用的,打包的时候插件的文件全部打包到根目录即可。

也就是说,如果你升级了新版本 ES,对于插件升级,大多数情况只需要修改下 plugin-descriptor.properties 文件中 ES 的版本号即可。

4、安全策略文件

在插件开发中经常会使用到文件读取、属性读取、网络链接等功能,如果不提前注册安全策略,在调用这些功能的时候会报以下错误java.security.AccessControlException: access denied

官方给出的解决方案就是新建一个 plugin-security.policy 文件,然后在文件中声明需要的权限信息,最后在打包的时候将文件放置到插件的根目录,这样在使用 zip 包进行安装的时候,ES 会提示用户插件所需的权限信息,需要用户确认后插件才能正常安装。

@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@     WARNING: plugin requires additional permissions     @
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
* java.io.FilePermission <<ALL FILES>> read,write,delete
* java.lang.RuntimePermission createClassLoader
* java.lang.RuntimePermission getClassLoader
* java.lang.RuntimePermission setContextClassLoader
* java.net.SocketPermission * connect,resolve
* java.util.PropertyPermission * read,write
See http://docs.oracle.com/javase/8/docs/technotes/guides/security/permissions.html
for descriptions of what these permissions allow and the associated risks.

Continue with installation? [y/N]y
-> Installed analysis-hanlp

5、安全策略的坑

最开始认为只需要添加了 policy 文件,且打包到正确的位置即可解决插件的权限问题,因为在插件安装的时候 ES 已经提示了所需权限,但是代码在实际执行的时候依旧报 AccessControlException 的错误。

参考了多个 HanLP 的 ES 分词插件,都没有获得较好的方法,后来考虑到 IK 分词器远程加载词典时,需要网络连接权限,就去看了下其远程词典加载的代码,最终找到了正确的使用方法。

// 需要特殊权限的代码
AccessController.doPrivileged((PrivilegedAction<Segment>) () -> {
    Segment segment;
    if (config.getAlgorithm().equals("extend")) {
        segment = new ViterbiSegment();
    } else {
        segment = HanLP.newSegment(config.getAlgorithm());
    }
    // 在此处显示调用一下分词,使得加载词典、缓存词典的操作可以正确执行
    System.out.println( segment.seg("HanLP中文分词工具包!"));
    return segment;
});

四、插件特色

简单介绍一下插件的特点:

  • 内置多种分词模式,适合不同场景;
  • 内置词典,无需额外配置即可使用;
  • 支持外置词典,用户可自定义分词算法,基于词典或是模型;
  • 支持分词器级别的自定义词典,便于用于多租户场景;
  • 支持远程词典热更新(待开发);
  • 拼音过滤器、繁简体过滤器(待开发);
  • 基于词语或单字的 ngram 切分分词(待开发)。

Github 地址:https://github.com/AnyListen/elasticsearch-analysis-hanlp

收起阅读 »

社区日报 第487期 (2018-12-23)

1.使用Elasticsearch进行简单标记。
http://t.cn/E4pK0fk
2.Java中的Elasticsearch指南。
http://t.cn/E4pXPl4
3.(自备梯子)智能家居技术仍然不够智能。
http://t.cn/E4CNtpJ

编辑:至尊宝
归档:https://elasticsearch.cn/article/6218
订阅:https://tinyletter.com/elastic-daily
继续阅读 »
1.使用Elasticsearch进行简单标记。
http://t.cn/E4pK0fk
2.Java中的Elasticsearch指南。
http://t.cn/E4pXPl4
3.(自备梯子)智能家居技术仍然不够智能。
http://t.cn/E4CNtpJ

编辑:至尊宝
归档:https://elasticsearch.cn/article/6218
订阅:https://tinyletter.com/elastic-daily 收起阅读 »

社区日报 第486期 (2018-12-22)

  1. 京东到家订单中心 Elasticsearch 演进历程。 http://t.cn/E4MXmyD

  2. 机器学习在solr,es,vespa上的应用(需翻墙)。 http://t.cn/E46pLF4

  3. 将Firestore数据导入到es教程。 http://t.cn/E46OPrz
继续阅读 »
  1. 京东到家订单中心 Elasticsearch 演进历程。 http://t.cn/E4MXmyD

  2. 机器学习在solr,es,vespa上的应用(需翻墙)。 http://t.cn/E46pLF4

  3. 将Firestore数据导入到es教程。 http://t.cn/E46OPrz
收起阅读 »

Day22 - 熟练使用ES离做好搜索还差多远?


作者:杨振涛 搜索引擎架构师@vivo 
首次发布:Elasticsearch中文社区
发布日期:2018-12-22


搜索引擎作为互联网发展历史中一个非常典型的产品/业务形态,时至今日并没有太大的突破性变化;主流形态可以划分为大搜、垂搜、企业级搜索和站内/app内搜索等。除了Google, Yahoo, Bing, Ask 等以及国内百度、搜狗、360、神马等是人们熟识的大搜之外,非业内人士还真不知道其他还有哪些公司以及有哪些搜索产品或业务场景。 实际上,在信息爆炸的时代,几乎每家有点儿规模的公司都或多或少要涉及到搜索引擎,最起码你需要接触SEO/SEM。本文将从非大搜企业的搜索需求出发,并基于开源技术栈来介绍和探讨搜索引擎在实践中的几个核心任务及其主要解决思路。同时为了避免重复,本文以外链形式引用了大量网络已有的国内外公开资料,方便大家参考,需要注意的是部分内容可能会随着时间推移而过期或链接失效。

提到开源搜索引擎,在Java技术栈里以Lucene, Solr/SolrCloud及Elasticsearch为代表的几个项目可能最为流行。本文的写作初衷是解答”熟练使用ES等开源搜索引擎解决方案以后,要如何才能做好搜索产品/业务?“ 希望对你有所帮助,如果你有关于此话题的更多实践经验或不同见解,欢迎留言评论交流。 
 
1. 做好搜索引擎意味着什么?
 
有一位同行的文章总结了好的搜索引擎的衡量维度:
  • 相关性
  • 体验
  • 性能


其中相关性是非常重要的一个维度,这里我将通过引用一篇文章来介绍什么是”相关性工程“以及”相关性工程师“ http://www.flax.co.uk/blog/201 ... ound/ 。

相关性工程中的“相关性”,主要是指代用户的Query与索引库中的Doc之间的相关性,所以可以分别从索引数据和Query两个方面来考虑。

相关性工程考虑的第一个特征就是基于已有索引数据的文本相关度计算,通常有TF-IDF、BM25、BM25F等。Elasticsearch早期的版本默认都是TF-IDF,目前已更改为BM25。对于中文数据,分词方法和策略也会直接影响到文本相关度的计算;其次匹配方式也非常重要;最后就是基于此的相关性算分了。

相关性工程还可以考虑更多的特征,尤其是从索引数据之外来挖掘出的特征,比如索引文档的权威性、时效性、专业性、质量与口碑评分、热度与流行度等。结合NLP技术,相关性工程还可以考虑语义距离等特征,丰富召回结果。当然这些特征的处理与机器学习中的特征工程基本一致,比如涉及归一化问题、权重问题、稀疏性问题、非典型分布等等。

相关性工程考虑的另一个重要特征是用户点击反馈数据,即对于用户所看到的搜索结果列表,点击行为被看作是对当前搜索结果的一种认可,用户点了哪个位置的doc对于继续优化相关性至关重要。这两天有个著名案例就是Google的劈柴在听证会上解释为什么在Google搜索Idiot出现的都是特朗普的照片。


体验涉及的方面较多,最重要的就是产品功能和交互方面的体验了,比如一个典型的搜索产品,C端可能具备以下功能:
  • 搜索前:搜索框,搜索入口,热搜榜/飙升榜/大家都在搜,搜索发现,默认搜索词,历史搜索记录,猜你想搜,分类搜索,语音输入搜索/图片搜索; 广告位
  • 搜索中:搜索联想直达,搜索联想词,输入纠错,关键词匹配高亮
  • 搜索后:搜索结果列表,列表页推荐/广告,特形展示,列表穿插,搜了还搜,搜索详情页,详情页搜索推荐,无结果及少结果填充 ,筛选条件/筛选器,自主排序,列表样式切换(宫格 | 列表)


除了产品功能,还需要考虑搜索引擎的可运营性,比如搜索运营管理系统,至少要具备基本功能的各种黑白灰名单,包括人工干预,优化分词的自定义词典、同义词典、停用词典,以及对查询词的强制改写或者升降权;对索引内容的管控,比如对检索字段的;对召回和排序的相关参数的优化和调整等等;此外,还有配套的SEO或ASO系统,以及各种数据指标相关的看板系统。

而搜索结果中的特形展示,也是目前比较主流的产品形式,不管是自然结果还是搜索广告,都可以提供更快捷的体验,甚至一度成为知识图谱在搜索产品中应用的代表性功能。另外搜索联想中的直达服务,也是目前比较流行的,可以进一步缩短用户的操作路径,直达目标内容或服务。

更多关于产品体验和设计类问题可以参考  http://www.woshipm.com/tag/搜索功能 

性能方面,搜索引擎的每一次查询理论上都是实时运算,大部分搜索引擎系统都是实时或准实时的,这就要求在用户感知上要有基本的响应时间(RT)保障,比如在国内公网环境下,200ms是比较优秀的体验,300ms-500ms是正常的体验,500ms+就需要尽快去优化。除去其中的网络I/O等开销,对于后端搜索服务的RT,一般是T99在100ms以内,T90在50ms以内,具体标准取决与当事业务和产品。除了RT,可用性也是非常重要的,一般要求99.9%以上;另外,索引数据的生效时间也很重要,比如新加入的索引,或者已有索引的更新和删除,秒级生效是比较好的体验。需要明确的一点是,这里的性能指标我们针对的是To C用户,如果是企业级搜索甚至是基于ES的一个即时查询分析系统,可能复杂查询的秒级响应也是很正常的。

延伸阅读:

阿里云-开放搜索-最佳实践-功能篇-相关性实践 https://help.aliyun.com/document_detail/29186.html 
Defining relevance engineering 什么是相关性工程 http://www.flax.co.uk/blog/201 ... ound/ 
 
2. 搜索引擎是典型的机器学习问题
 
云计算、大数据、AI 先后成为IT与互联网行业的热点,三者经常被称为CBA或ABC技术,而这些都与一家公司密切相关,那就是 Google !   众所周知 Google 是一家著名的全球搜索引擎公司,但其产品远不止搜索引擎。从Google的三驾马车 GFS, MapReduce, BigTable开始,后来有了 Yahoo牵头的开源实现Hadoop(Hadoop最早来自于Nutch,是的,没错,就是那个开发了 Lucene 的 Doug Cutting所开源的Nutch,他被称作Hadoop之父),到后来的云计算与大数据技术蓬勃,到今天的AI热潮,各种深度学习各种NN, Google Brain,开源的Tensorflow,对Google来说这一切都是搜索引擎业务驱动的水到渠成的发展轨迹。 可以说搜索引擎是天生的机器学习问题,有着诸多的机器学习/深度学习应用场景。这里顺便DISS下一些眼高手低的迷糊党,互联网圈儿曾有人遇到求职者表示想做AI,却不做搜索不做推荐不做广告!(本人内心:你咋不上天呢!请记住AI is a buzzword. )当今的互联网或移动互联网,搜索、推荐与广告是三大典型的所谓AI应用落地方向,其他的也有但并未发展成熟,至少还没有成熟的变现模式;而这三者或多或少有些交集,搜索几乎是最基础的一个,比如推荐也需要建立索引,需要检索TOP N,搜索广告也需要做召回和排序。

如果我们把搜索引擎的核心模型简化下,其实主要是在解决三大类问题: 

- 数据: 内容侧的爬虫,预处理,内容分析和理解,索引建立和存储 ;用户侧的Query理解,改写,意图识别等
- 算法/模型 :把相关性和排序等业务问题抽象为回归或分类/聚类问题,特征工程,离线训练模型,在线预测
- 策略:为满足业务需求而制定并持续优化的一系列规则、模型或模型组合、参数优化等活动,并通过工程化实现体现到线上系统,以及配套的试验和评估系统 
 
2.1 Ranking  排序

常见的排序策略有:
  • 单维度排序:顾名思义按照单个维度来排序,没有任何复杂性可言,在召回结果集不太大的情况下实时排序即可。
  • 优先级排序:相对单维度排序而已一般是先按维度A排,当A的排序依据一样或相等时再按维度B排序,以此类推。
  • 加权排序   :针对多个维度或特征,赋予不同权重,并按求和之后的得分来排序;实践中通常会采用分层加权排序(第一层加权排序之后,得到不少于2个得分,继续加权后排序),或者分组加权排序(第一层分组来加权排序后,对所得到的得分可能按业务需求进行非求和类的运算比如乘法,再按最终得分排序)的策略。 加权排序的难点在于,如何设置并持续优化这些权重,通常会建模为典型的机器学习问题来拟合。
  • 机器学习排序 :即所谓LTR,根据用户点击或人工标注数据集建立学习目标,然后通过特征工程来挖掘与目标有关系的一系列特征,并建立学习模型,通过训练集获得模型参数,以该组参数为基准做预测,上线后再基于用户点击数据持续优化该模型的参数。LTR是一个通用方法的称谓,不是某一个具体算法的名称,具体算法名称参见下文。


排序问题可以简单抽象成为预测用户点击列表中对象的概率问题。
 
2.2 ES生态内的 LTR 

关于LTR的理论和方法学,已经有很多论文和资料了 ( 参考 wikipedia LTR简介-微软亚研院, LTR Pairwise to Listwise ,  大规模LTR-GoogleLTR书籍 ),感兴趣的可以阅读,这里主要提供几个JAVA和ES生态的工程实现参考。

es-ltr插件  http://es-learn-to-rank.labs.o19s.com/ 

Set of command line tools for Learning To Rank https://github.com/SeaseLtd/ltr-tools

es的ranking evaluation api https://www.elastic.co/guide/e ... .html 

Java LTR类库: RankLib  https://sourceforge.net/p/lemur/wiki/RankLib/

支持算法如下:
  • MART (Multiple Additive Regression Trees, a.k.a. Gradient boosted regression tree) 
  • RankNet 
  • RankBoost 
  • AdaRank 
  • Coordinate Ascent 
  • LambdaMART 
  • ListNet 
  • Random Forests  


延伸阅读:

 
2.3 典型垂搜

电商与O2O搜索

案例: 天猫,淘宝,京东,美丽说蘑菇街,有赞 ,美团点评,饿了么 

阿里研究员徐盈辉:在线AI技术在搜索与推荐场景的应用 https://yq.aliyun.com/articles/107941  
阿里巴巴资深算法专家三桐:人工智能在搜索中的应用 https://yq.aliyun.com/articles/288065  
阿里巴巴年度技术总结 - 人工智能在搜索的应用和实践 http://www.sohu.com/a/214123235_680198
 电子商务搜索系统架构参考 (京东) https://blog.csdn.net/hongseji ... 08067  
电商搜索之动态属性值(特征值)聚合 (举例 京东和solr实现)  https://blog.csdn.net/hu948162 ... 80071  
劈开迷雾,蘑菇街电商搜索架构及搜索排序实现 https://blog.csdn.net/huangshu ... 46694
有赞搜索引擎实践(工程篇)  https://www.cnblogs.com/hsydj/p/5303050.html
有赞搜索引擎实践(算法篇)  https://www.cnblogs.com/hsydj/p/5402945.html 
有赞搜索系统的架构演进   https://tech.youzan.com/search-tech-1/   
有赞搜索系统的技术内幕  https://tech.youzan.com/search-tech-2/  

电商系统如何做搜索引擎? https://blog.csdn.net/zysgdhf4 ... 53999  

电商检索系统总结——功能篇 https://www.cnblogs.com/wanghuaijun/p/7112952.html 

App搜索 

案例:Google Play, 应用宝,各种手机助手,Apple App Store及各大其他手机厂商的应用商店/应用市场以及互联网电视/机顶盒等的应用商店/应用市场  
 
3. 搜索引擎的效果评价

我们在团队内有句戏言:看一个搜索团队是否专业,就看他们是否做效果评价。 在与国内外的搜索工程师交流和学习过程中,还有一个说法是:搜素引擎的优化就像一个打地鼠游戏,你解决一类bad case的同时很难确认其是否会带来新的bad case以及会带来多少。

需要区别的是,搜索引擎中使用到的机器学习/深度学习算法本身的效果评估(如分类算法的Accuracy、Precision、Recall、F1、ROC、AUC 等)并不能直接代替搜索引擎的效果评价。通常我们分为人工主观评测和业务指标评测。

参考:

 
4. NLP 自然语言处理

我们知道搜索引擎的上游学科是信息检索(IR),这也是搜索引擎的理论基础。而自然语言处理(NLP)在信息检索领域尤其是搜索引擎中有着至关重要的地位和作用。一方面我们对于被搜索的内容数据的理解,需要借助NLP来提升语义性和智能程度,另一方面我们对于用户Query和意图的理解,也需要借助NLP相关方法和技术来完成。

实际上ES的很多特性已经非常强大, 可以作为基本的文本分析和挖掘工具使用,这也是解释了ES官方博客以及其他博客有分享一些文章,主题是关于使用ES来进行文本分类或者实现推荐系统。


总结一下,想要做好一个典型的搜索引擎产品,除了熟练使用ES,还需要考虑搜索产品的功能完备性、体验优劣、性能以及相关性,而相关性涉及对内容数据的理解和挖掘、对用户Query的理解和意图识别,以及检索过程中的特征选取和权重优化、算分、排序,最后是比较重要的效果评价。这个过程中NLP的应用也非常多,除了基本的分词,还可能涉及非必留、词性识别、纠错、繁简体、多语言、文本向量化及语义距离计算等。


最后推荐一本搜索必读书籍—— 吴军的《数学之美》第二版 https://book.douban.com/subject/26163454/   

第1 章 文字和语言 vs 数字和信息
第2 章 自然语言处理 — 从规则到统计
第3 章 统计语言模型
第4 章 谈谈分词
第5 章 隐含马尔可夫模型
第6 章 信息的度量和作用
第7 章 贾里尼克和现代语言处理
第8 章 简单之美 — 布尔代数和搜索引擎
第9 章 图论和网络爬虫
第10章 PageRank — Google的民主表决式网页排名技术
第11章 如何确定网页和查询的相关性
第12章 有限状态机和动态规划 — 地图与本地
第13章 Google AK-47 的设计者 — 阿米特· 辛格博士
第14章 余弦定理和新闻的分类
第15章 矩阵运算和文本处理中的两个分类问题
第16章 信息指纹及其应用
第17章 由电视剧《暗算》所想到的 — 谈谈密码学的数学原理
第18章 闪光的不一定是金子 — 谈谈搜索引擎
第19章 谈谈数学模型的重要性
第20章 不要把鸡蛋放到一个篮子里 — 谈谈最
第21章 拼音输入法的数学原理
第22章 自然语言处理的教父马库斯和他的优秀弟子们
第23章 布隆过滤器
第24章 马尔可夫链的扩展 — 贝叶斯网络
第25章 条件随机场、文法分析及其他
第26章 维特比和他的维特比算法
第27章 上帝的算法 — 期望最大化算法
第28章 逻辑回归和搜索广告
第29章 各个击破算法和Google 云计算的基础
第30章 Google 大脑和人工神经网络
第31章 大数据的威力——谈谈数据的重要性
 
 
 
 
 
继续阅读 »


作者:杨振涛 搜索引擎架构师@vivo 
首次发布:Elasticsearch中文社区
发布日期:2018-12-22


搜索引擎作为互联网发展历史中一个非常典型的产品/业务形态,时至今日并没有太大的突破性变化;主流形态可以划分为大搜、垂搜、企业级搜索和站内/app内搜索等。除了Google, Yahoo, Bing, Ask 等以及国内百度、搜狗、360、神马等是人们熟识的大搜之外,非业内人士还真不知道其他还有哪些公司以及有哪些搜索产品或业务场景。 实际上,在信息爆炸的时代,几乎每家有点儿规模的公司都或多或少要涉及到搜索引擎,最起码你需要接触SEO/SEM。本文将从非大搜企业的搜索需求出发,并基于开源技术栈来介绍和探讨搜索引擎在实践中的几个核心任务及其主要解决思路。同时为了避免重复,本文以外链形式引用了大量网络已有的国内外公开资料,方便大家参考,需要注意的是部分内容可能会随着时间推移而过期或链接失效。

提到开源搜索引擎,在Java技术栈里以Lucene, Solr/SolrCloud及Elasticsearch为代表的几个项目可能最为流行。本文的写作初衷是解答”熟练使用ES等开源搜索引擎解决方案以后,要如何才能做好搜索产品/业务?“ 希望对你有所帮助,如果你有关于此话题的更多实践经验或不同见解,欢迎留言评论交流。 
 
1. 做好搜索引擎意味着什么?
 
有一位同行的文章总结了好的搜索引擎的衡量维度:
  • 相关性
  • 体验
  • 性能


其中相关性是非常重要的一个维度,这里我将通过引用一篇文章来介绍什么是”相关性工程“以及”相关性工程师“ http://www.flax.co.uk/blog/201 ... ound/ 。

相关性工程中的“相关性”,主要是指代用户的Query与索引库中的Doc之间的相关性,所以可以分别从索引数据和Query两个方面来考虑。

相关性工程考虑的第一个特征就是基于已有索引数据的文本相关度计算,通常有TF-IDF、BM25、BM25F等。Elasticsearch早期的版本默认都是TF-IDF,目前已更改为BM25。对于中文数据,分词方法和策略也会直接影响到文本相关度的计算;其次匹配方式也非常重要;最后就是基于此的相关性算分了。

相关性工程还可以考虑更多的特征,尤其是从索引数据之外来挖掘出的特征,比如索引文档的权威性、时效性、专业性、质量与口碑评分、热度与流行度等。结合NLP技术,相关性工程还可以考虑语义距离等特征,丰富召回结果。当然这些特征的处理与机器学习中的特征工程基本一致,比如涉及归一化问题、权重问题、稀疏性问题、非典型分布等等。

相关性工程考虑的另一个重要特征是用户点击反馈数据,即对于用户所看到的搜索结果列表,点击行为被看作是对当前搜索结果的一种认可,用户点了哪个位置的doc对于继续优化相关性至关重要。这两天有个著名案例就是Google的劈柴在听证会上解释为什么在Google搜索Idiot出现的都是特朗普的照片。


体验涉及的方面较多,最重要的就是产品功能和交互方面的体验了,比如一个典型的搜索产品,C端可能具备以下功能:
  • 搜索前:搜索框,搜索入口,热搜榜/飙升榜/大家都在搜,搜索发现,默认搜索词,历史搜索记录,猜你想搜,分类搜索,语音输入搜索/图片搜索; 广告位
  • 搜索中:搜索联想直达,搜索联想词,输入纠错,关键词匹配高亮
  • 搜索后:搜索结果列表,列表页推荐/广告,特形展示,列表穿插,搜了还搜,搜索详情页,详情页搜索推荐,无结果及少结果填充 ,筛选条件/筛选器,自主排序,列表样式切换(宫格 | 列表)


除了产品功能,还需要考虑搜索引擎的可运营性,比如搜索运营管理系统,至少要具备基本功能的各种黑白灰名单,包括人工干预,优化分词的自定义词典、同义词典、停用词典,以及对查询词的强制改写或者升降权;对索引内容的管控,比如对检索字段的;对召回和排序的相关参数的优化和调整等等;此外,还有配套的SEO或ASO系统,以及各种数据指标相关的看板系统。

而搜索结果中的特形展示,也是目前比较主流的产品形式,不管是自然结果还是搜索广告,都可以提供更快捷的体验,甚至一度成为知识图谱在搜索产品中应用的代表性功能。另外搜索联想中的直达服务,也是目前比较流行的,可以进一步缩短用户的操作路径,直达目标内容或服务。

更多关于产品体验和设计类问题可以参考  http://www.woshipm.com/tag/搜索功能 

性能方面,搜索引擎的每一次查询理论上都是实时运算,大部分搜索引擎系统都是实时或准实时的,这就要求在用户感知上要有基本的响应时间(RT)保障,比如在国内公网环境下,200ms是比较优秀的体验,300ms-500ms是正常的体验,500ms+就需要尽快去优化。除去其中的网络I/O等开销,对于后端搜索服务的RT,一般是T99在100ms以内,T90在50ms以内,具体标准取决与当事业务和产品。除了RT,可用性也是非常重要的,一般要求99.9%以上;另外,索引数据的生效时间也很重要,比如新加入的索引,或者已有索引的更新和删除,秒级生效是比较好的体验。需要明确的一点是,这里的性能指标我们针对的是To C用户,如果是企业级搜索甚至是基于ES的一个即时查询分析系统,可能复杂查询的秒级响应也是很正常的。

延伸阅读:

阿里云-开放搜索-最佳实践-功能篇-相关性实践 https://help.aliyun.com/document_detail/29186.html 
Defining relevance engineering 什么是相关性工程 http://www.flax.co.uk/blog/201 ... ound/ 
 
2. 搜索引擎是典型的机器学习问题
 
云计算、大数据、AI 先后成为IT与互联网行业的热点,三者经常被称为CBA或ABC技术,而这些都与一家公司密切相关,那就是 Google !   众所周知 Google 是一家著名的全球搜索引擎公司,但其产品远不止搜索引擎。从Google的三驾马车 GFS, MapReduce, BigTable开始,后来有了 Yahoo牵头的开源实现Hadoop(Hadoop最早来自于Nutch,是的,没错,就是那个开发了 Lucene 的 Doug Cutting所开源的Nutch,他被称作Hadoop之父),到后来的云计算与大数据技术蓬勃,到今天的AI热潮,各种深度学习各种NN, Google Brain,开源的Tensorflow,对Google来说这一切都是搜索引擎业务驱动的水到渠成的发展轨迹。 可以说搜索引擎是天生的机器学习问题,有着诸多的机器学习/深度学习应用场景。这里顺便DISS下一些眼高手低的迷糊党,互联网圈儿曾有人遇到求职者表示想做AI,却不做搜索不做推荐不做广告!(本人内心:你咋不上天呢!请记住AI is a buzzword. )当今的互联网或移动互联网,搜索、推荐与广告是三大典型的所谓AI应用落地方向,其他的也有但并未发展成熟,至少还没有成熟的变现模式;而这三者或多或少有些交集,搜索几乎是最基础的一个,比如推荐也需要建立索引,需要检索TOP N,搜索广告也需要做召回和排序。

如果我们把搜索引擎的核心模型简化下,其实主要是在解决三大类问题: 

- 数据: 内容侧的爬虫,预处理,内容分析和理解,索引建立和存储 ;用户侧的Query理解,改写,意图识别等
- 算法/模型 :把相关性和排序等业务问题抽象为回归或分类/聚类问题,特征工程,离线训练模型,在线预测
- 策略:为满足业务需求而制定并持续优化的一系列规则、模型或模型组合、参数优化等活动,并通过工程化实现体现到线上系统,以及配套的试验和评估系统 
 
2.1 Ranking  排序

常见的排序策略有:
  • 单维度排序:顾名思义按照单个维度来排序,没有任何复杂性可言,在召回结果集不太大的情况下实时排序即可。
  • 优先级排序:相对单维度排序而已一般是先按维度A排,当A的排序依据一样或相等时再按维度B排序,以此类推。
  • 加权排序   :针对多个维度或特征,赋予不同权重,并按求和之后的得分来排序;实践中通常会采用分层加权排序(第一层加权排序之后,得到不少于2个得分,继续加权后排序),或者分组加权排序(第一层分组来加权排序后,对所得到的得分可能按业务需求进行非求和类的运算比如乘法,再按最终得分排序)的策略。 加权排序的难点在于,如何设置并持续优化这些权重,通常会建模为典型的机器学习问题来拟合。
  • 机器学习排序 :即所谓LTR,根据用户点击或人工标注数据集建立学习目标,然后通过特征工程来挖掘与目标有关系的一系列特征,并建立学习模型,通过训练集获得模型参数,以该组参数为基准做预测,上线后再基于用户点击数据持续优化该模型的参数。LTR是一个通用方法的称谓,不是某一个具体算法的名称,具体算法名称参见下文。


排序问题可以简单抽象成为预测用户点击列表中对象的概率问题。
 
2.2 ES生态内的 LTR 

关于LTR的理论和方法学,已经有很多论文和资料了 ( 参考 wikipedia LTR简介-微软亚研院, LTR Pairwise to Listwise ,  大规模LTR-GoogleLTR书籍 ),感兴趣的可以阅读,这里主要提供几个JAVA和ES生态的工程实现参考。

es-ltr插件  http://es-learn-to-rank.labs.o19s.com/ 

Set of command line tools for Learning To Rank https://github.com/SeaseLtd/ltr-tools

es的ranking evaluation api https://www.elastic.co/guide/e ... .html 

Java LTR类库: RankLib  https://sourceforge.net/p/lemur/wiki/RankLib/

支持算法如下:
  • MART (Multiple Additive Regression Trees, a.k.a. Gradient boosted regression tree) 
  • RankNet 
  • RankBoost 
  • AdaRank 
  • Coordinate Ascent 
  • LambdaMART 
  • ListNet 
  • Random Forests  


延伸阅读:

 
2.3 典型垂搜

电商与O2O搜索

案例: 天猫,淘宝,京东,美丽说蘑菇街,有赞 ,美团点评,饿了么 

阿里研究员徐盈辉:在线AI技术在搜索与推荐场景的应用 https://yq.aliyun.com/articles/107941  
阿里巴巴资深算法专家三桐:人工智能在搜索中的应用 https://yq.aliyun.com/articles/288065  
阿里巴巴年度技术总结 - 人工智能在搜索的应用和实践 http://www.sohu.com/a/214123235_680198
 电子商务搜索系统架构参考 (京东) https://blog.csdn.net/hongseji ... 08067  
电商搜索之动态属性值(特征值)聚合 (举例 京东和solr实现)  https://blog.csdn.net/hu948162 ... 80071  
劈开迷雾,蘑菇街电商搜索架构及搜索排序实现 https://blog.csdn.net/huangshu ... 46694
有赞搜索引擎实践(工程篇)  https://www.cnblogs.com/hsydj/p/5303050.html
有赞搜索引擎实践(算法篇)  https://www.cnblogs.com/hsydj/p/5402945.html 
有赞搜索系统的架构演进   https://tech.youzan.com/search-tech-1/   
有赞搜索系统的技术内幕  https://tech.youzan.com/search-tech-2/  

电商系统如何做搜索引擎? https://blog.csdn.net/zysgdhf4 ... 53999  

电商检索系统总结——功能篇 https://www.cnblogs.com/wanghuaijun/p/7112952.html 

App搜索 

案例:Google Play, 应用宝,各种手机助手,Apple App Store及各大其他手机厂商的应用商店/应用市场以及互联网电视/机顶盒等的应用商店/应用市场  
 
3. 搜索引擎的效果评价

我们在团队内有句戏言:看一个搜索团队是否专业,就看他们是否做效果评价。 在与国内外的搜索工程师交流和学习过程中,还有一个说法是:搜素引擎的优化就像一个打地鼠游戏,你解决一类bad case的同时很难确认其是否会带来新的bad case以及会带来多少。

需要区别的是,搜索引擎中使用到的机器学习/深度学习算法本身的效果评估(如分类算法的Accuracy、Precision、Recall、F1、ROC、AUC 等)并不能直接代替搜索引擎的效果评价。通常我们分为人工主观评测和业务指标评测。

参考:

 
4. NLP 自然语言处理

我们知道搜索引擎的上游学科是信息检索(IR),这也是搜索引擎的理论基础。而自然语言处理(NLP)在信息检索领域尤其是搜索引擎中有着至关重要的地位和作用。一方面我们对于被搜索的内容数据的理解,需要借助NLP来提升语义性和智能程度,另一方面我们对于用户Query和意图的理解,也需要借助NLP相关方法和技术来完成。

实际上ES的很多特性已经非常强大, 可以作为基本的文本分析和挖掘工具使用,这也是解释了ES官方博客以及其他博客有分享一些文章,主题是关于使用ES来进行文本分类或者实现推荐系统。


总结一下,想要做好一个典型的搜索引擎产品,除了熟练使用ES,还需要考虑搜索产品的功能完备性、体验优劣、性能以及相关性,而相关性涉及对内容数据的理解和挖掘、对用户Query的理解和意图识别,以及检索过程中的特征选取和权重优化、算分、排序,最后是比较重要的效果评价。这个过程中NLP的应用也非常多,除了基本的分词,还可能涉及非必留、词性识别、纠错、繁简体、多语言、文本向量化及语义距离计算等。


最后推荐一本搜索必读书籍—— 吴军的《数学之美》第二版 https://book.douban.com/subject/26163454/   

第1 章 文字和语言 vs 数字和信息
第2 章 自然语言处理 — 从规则到统计
第3 章 统计语言模型
第4 章 谈谈分词
第5 章 隐含马尔可夫模型
第6 章 信息的度量和作用
第7 章 贾里尼克和现代语言处理
第8 章 简单之美 — 布尔代数和搜索引擎
第9 章 图论和网络爬虫
第10章 PageRank — Google的民主表决式网页排名技术
第11章 如何确定网页和查询的相关性
第12章 有限状态机和动态规划 — 地图与本地
第13章 Google AK-47 的设计者 — 阿米特· 辛格博士
第14章 余弦定理和新闻的分类
第15章 矩阵运算和文本处理中的两个分类问题
第16章 信息指纹及其应用
第17章 由电视剧《暗算》所想到的 — 谈谈密码学的数学原理
第18章 闪光的不一定是金子 — 谈谈搜索引擎
第19章 谈谈数学模型的重要性
第20章 不要把鸡蛋放到一个篮子里 — 谈谈最
第21章 拼音输入法的数学原理
第22章 自然语言处理的教父马库斯和他的优秀弟子们
第23章 布隆过滤器
第24章 马尔可夫链的扩展 — 贝叶斯网络
第25章 条件随机场、文法分析及其他
第26章 维特比和他的维特比算法
第27章 上帝的算法 — 期望最大化算法
第28章 逻辑回归和搜索广告
第29章 各个击破算法和Google 云计算的基础
第30章 Google 大脑和人工神经网络
第31章 大数据的威力——谈谈数据的重要性
 
 
 
 
  收起阅读 »

Day24 - Predator捕捉病毒样本

predator.jpeg

对,你一定看过一个电影,情节是这样的,他们拿着长矛去狩猎异形怪物,它们比人类强健,它们的脸部的器官布置得出奇丑陋。它们的身上总是带了一堆很先进的狩猎武器,它们喜欢在杀死猎物后将尸体剥皮,还会将猎物头骨加工成工艺品,当成战利品收藏。对,这部电影系列就叫Predator。好了,言归正传,我们今天讲的故事其实非常简单,讲述的是elasticsearch引擎在安全领域的简单应用,如何通过elasticsearch来搜索一个病毒,我们开发了一个小小的工具来帮我做跨集群查询,以及SQL-DSL转换接口,我们把这个小工具叫做predator。

背景

我司主要是做病毒相关工作的,近年来,数据爆炸,病毒软件也成几何级数倍数增长,大数据病毒出现自然需要对应的大数据工具来处理它们,简单来讲,就是我们可以把病毒样本的一些属性剥离到elasticsearch中,就和日志来描述一个用户的行为一样,本质来说,它们都是数据,然后,我们研究病毒的一些特征属性,通过简单的搜索,就可以快速分析出一堆可能的病毒样本,再然后,通过一系列的测试,过滤,我们就可以真正的找到我们想要的病毒样本,并且通过这些规则持续的追踪它们,是不是很简单?

问题

事情是那么简单,但是在使用elasticsearch作为特征库的过程中,我们也有这样的问题:
1,多种维度特征
由于存在多种维度特征的病毒,不通模块剥离出不通病毒属性,所以存在多张表来存属性,那么在query的时候就需要跨表,甚至跨集群查询。
2,DSL的复杂度
由于内部研究员们对elasticStack并不熟悉,加上DSL语言相对复杂,我们需要使用更加接近hunman特性的SQL来转换DSL语言。

数据处理架构

我们有一个类似的数据处理架构

数据架构.png

Predator和它的Spear

因此,我们开发了一个小工具,其实,这个小工具非常简单,只是简单的解决了上述2个问题:
使用Elasticsearch-SQL插件来包装一个restful的DSL转换SQL接口,当然,目前ES6已经完全支持SQL接口了,哈哈,早点出来我们就不用做那么工作了:) :):)。
简单的写个跨集群的查下聚合器就可以实现跨表查下,其实,这个功能只是简单的查下封装,只是针对特殊的业务场景,没啥参考价值。
至于Spear,它其实就是个predator service的客户端,哈哈,像不像铁血战士拿着长矛开着非常去狩猎的样子:) 。

predator架构.png

这是一个规则:

规则.png

这是规则的查询结果:

rule_hit.png

长矛的sample code:

# cross cluster search by dsls
import json
from spear import Spear
sp = Spear()      
dsl_1 = {}
dsl_2 = {}
query_dict = {    
    json.dumps(dsl_1): {
        "cluster": "es_cluster_1",
        "type":"xxx"
    },
    json.dumps(dsl_2): {
        "cluster": "es_cluster_2",
        "type": "yyy"
    }
}
sp.cross_count_by_dsl(query_dict, is_show_help=False)

当然长矛也支持SQL接口

总结

其实,这个只是一个user case的工程实践,可以看到的是,伟大的ElasticStack在各行各业,各种大数据领域,如果抛开领域的概念,一切都是数据,那么理论上来说我们可以使用elasticsearch处理任何类型的数据,当然目前业界典型的应用场景还是搜索,日志,甚至于APM,总之,紧跟社区可以学到很多东西啦。

继续阅读 »

predator.jpeg

对,你一定看过一个电影,情节是这样的,他们拿着长矛去狩猎异形怪物,它们比人类强健,它们的脸部的器官布置得出奇丑陋。它们的身上总是带了一堆很先进的狩猎武器,它们喜欢在杀死猎物后将尸体剥皮,还会将猎物头骨加工成工艺品,当成战利品收藏。对,这部电影系列就叫Predator。好了,言归正传,我们今天讲的故事其实非常简单,讲述的是elasticsearch引擎在安全领域的简单应用,如何通过elasticsearch来搜索一个病毒,我们开发了一个小小的工具来帮我做跨集群查询,以及SQL-DSL转换接口,我们把这个小工具叫做predator。

背景

我司主要是做病毒相关工作的,近年来,数据爆炸,病毒软件也成几何级数倍数增长,大数据病毒出现自然需要对应的大数据工具来处理它们,简单来讲,就是我们可以把病毒样本的一些属性剥离到elasticsearch中,就和日志来描述一个用户的行为一样,本质来说,它们都是数据,然后,我们研究病毒的一些特征属性,通过简单的搜索,就可以快速分析出一堆可能的病毒样本,再然后,通过一系列的测试,过滤,我们就可以真正的找到我们想要的病毒样本,并且通过这些规则持续的追踪它们,是不是很简单?

问题

事情是那么简单,但是在使用elasticsearch作为特征库的过程中,我们也有这样的问题:
1,多种维度特征
由于存在多种维度特征的病毒,不通模块剥离出不通病毒属性,所以存在多张表来存属性,那么在query的时候就需要跨表,甚至跨集群查询。
2,DSL的复杂度
由于内部研究员们对elasticStack并不熟悉,加上DSL语言相对复杂,我们需要使用更加接近hunman特性的SQL来转换DSL语言。

数据处理架构

我们有一个类似的数据处理架构

数据架构.png

Predator和它的Spear

因此,我们开发了一个小工具,其实,这个小工具非常简单,只是简单的解决了上述2个问题:
使用Elasticsearch-SQL插件来包装一个restful的DSL转换SQL接口,当然,目前ES6已经完全支持SQL接口了,哈哈,早点出来我们就不用做那么工作了:) :):)。
简单的写个跨集群的查下聚合器就可以实现跨表查下,其实,这个功能只是简单的查下封装,只是针对特殊的业务场景,没啥参考价值。
至于Spear,它其实就是个predator service的客户端,哈哈,像不像铁血战士拿着长矛开着非常去狩猎的样子:) 。

predator架构.png

这是一个规则:

规则.png

这是规则的查询结果:

rule_hit.png

长矛的sample code:

# cross cluster search by dsls
import json
from spear import Spear
sp = Spear()      
dsl_1 = {}
dsl_2 = {}
query_dict = {    
    json.dumps(dsl_1): {
        "cluster": "es_cluster_1",
        "type":"xxx"
    },
    json.dumps(dsl_2): {
        "cluster": "es_cluster_2",
        "type": "yyy"
    }
}
sp.cross_count_by_dsl(query_dict, is_show_help=False)

当然长矛也支持SQL接口

总结

其实,这个只是一个user case的工程实践,可以看到的是,伟大的ElasticStack在各行各业,各种大数据领域,如果抛开领域的概念,一切都是数据,那么理论上来说我们可以使用elasticsearch处理任何类型的数据,当然目前业界典型的应用场景还是搜索,日志,甚至于APM,总之,紧跟社区可以学到很多东西啦。

收起阅读 »

社区日报 第485期(2018-12-21)

1、Mongodb同步Elasticsearch演示
http://t.cn/EUu5RI3
2、Elasticsearch7.0计算向量距离新特性抢先看
http://t.cn/EUB4vbo
3、Kubernetes上部署高可用和可扩展的Elasticsearch
http://t.cn/ELhogLr

编辑:铭毅天下
归档:https://elasticsearch.cn/article/6214
订阅:https://tinyletter.com/elastic-daily
继续阅读 »
1、Mongodb同步Elasticsearch演示
http://t.cn/EUu5RI3
2、Elasticsearch7.0计算向量距离新特性抢先看
http://t.cn/EUB4vbo
3、Kubernetes上部署高可用和可扩展的Elasticsearch
http://t.cn/ELhogLr

编辑:铭毅天下
归档:https://elasticsearch.cn/article/6214
订阅:https://tinyletter.com/elastic-daily 收起阅读 »

Day 21 - ECE 版本升级扫雷实战

Elastic Cloud Enterprise 出来也有一年多的时间了。对于这类的开源软件企业版本,基本都是在可管理性和稳定性上面下功夫。但是新产品免不了需要经历一下bug的打磨才会变得成熟。

下面分享的这个案例是当我们在把集群从5.4.1 升级到5.6.12 的过程中,遇到节点关闭受阻,升级不完整等情景。以及对应的处理方法。
首先在ECE中,版本是通过stack的方式管理
 
QQ20181221-104539@2x.png

Ref : https://www.elastic.co/guide/e ... .html

这些版本都是以docker images的形式存储

QQ20181221-104619@2x.png

因此,ECE根据不同的版本,然后选择对应的docker image就可以创建一个节点了. 那么升级的过程就可以简单分成几个步骤

1.exclude准备升级的节点。

2.停止节点ES进程,更换container 版本。

3.重新启动节点,加入集群。

4.在其他节点上重复以上流程。

在这个过程中, 实际使用的时候发现有一些需要注意的雷区.
扫雷一:使用UI触发升级,必须保证集群没有自定义插件和bundles

ECE 里面的集群操作是通过plan来控制的

QQ20181221-104650@2x.png

任何的集群操作最终都会生成一个plan的diff。如上图,把集群从5.4.1 升级到 5.6.12 会产生以上diff.

正常情况下是没有问题的.

如果集群配置了自定义bundles, 比如LDAP bundles, ref:https://www.elastic.co/guide/e ... .html

那么在集群的plan里面就会存在这么一段配置

QQ20181221-104718@2x.png

那么当我们在按下升级按钮的时候

QQ20181221-104744@2x.png

ECE 只在plan中修改了集群大版本的配置, 但是并没有修改自定义bundles中的版本号(仍然是5.4.1).

在这种情况下去执行升级,会直接产生报错.

QQ20181221-104810@2x.png

界面上没有显示原因, 但是这是因为plan里面大版本和bundle中的版本不一致,然后会导致新增的节点无法启动. 于是ECE 就认为集群升级失败了.
解决方法是手动编辑plan,把自定义bundles中的版本号改成和集群版本一致

QQ20181221-104848@2x.png

然后使用ECE 提供的一种手动使用plan进行集群升级的方式进行升级.

扫雷二:节点无法关闭

ECE 控制container 是通过一个叫做 constructor的服务。constructor 通过接收集群的更改需求,制定具体的更改计划与步骤,指导allocator对container进行操作。同时也负责保证集群高可靠性,通过Availability Zone的数量在不同的AZ上面部署节点。

当Allocator接受到关闭container命令的时候,会尝试去关闭container,如果container处于一个阻塞状态无法响应, 那么关闭命令无法执行成功。这个时候constructor会等待节点关闭,但是allocator又认为节点已经接受到关闭命令了。又或者constructor发送给allocator的过程中网络丢包, 这个时候allocator 没有正确接受关闭container的命令. 整个升级进程就卡住了。 这种情况十分罕见,通常发现一个container如果处于”正在关闭”时间太久了, 那么通常就是中间的通信出现问题了.

QQ20181221-104926@2x.png

解决办法是可以通过手动停止container, 在对应的allocator上面找到container,使用

docker stop <container_name>

停止container,这样可以出发allocator更新container的健康状态,上报这个container已经关闭了, 从而打通流程并执行下一步。
扫雷三: 多版本并存

如果使用上面的方式强行关闭docker container, 虽然可以让升级进程继续进行下去. 但是被手动关闭的节点会保留原来的版本。于是在升级后查看各个节点的版本,会发现部分节点是5.4.1, 部分是5.6.12.

因为节点是强制关闭的, ECE直接认为节点已经完成升级,并重新启动这个container. 而在这个处理中,跳过了升级docker image的一步.

为什么不是生成一个新的container呢? 因为从plan里面可以看到

QQ20181221-104951@2x.png

在默认情况下, ECE 处理版本升级是使用rolling 策略 Ref: https://www.elastic.co/guide/e ... .html

在这个策略下,ECE会停止当前container并直接修改重启。

如果ECE集群容量允许, 可以改成grow_and_shrink 策略, 这样ECE 会创建新的container并且销毁旧的container, 避免集群出现多版本.
如果出现了多版本的集群,可以通过更改集群任意一个配置来触发 grow_and_shrink 同样可以使到版本回归一致.
总结来说ECE 在版本升级方面还是有很多需要改进的地方. 对于ECE用户再说在使用ECE的版本升级功能的时候主要有以下建议

1. 自己学会手动修改plan. 这也是每一个ECE support engineer 都会干的事情.

2.如果集群容量允许,尽量使用 grow_and_shrink的策略来进行集群操作.
 
继续阅读 »
Elastic Cloud Enterprise 出来也有一年多的时间了。对于这类的开源软件企业版本,基本都是在可管理性和稳定性上面下功夫。但是新产品免不了需要经历一下bug的打磨才会变得成熟。

下面分享的这个案例是当我们在把集群从5.4.1 升级到5.6.12 的过程中,遇到节点关闭受阻,升级不完整等情景。以及对应的处理方法。
首先在ECE中,版本是通过stack的方式管理
 
QQ20181221-104539@2x.png

Ref : https://www.elastic.co/guide/e ... .html

这些版本都是以docker images的形式存储

QQ20181221-104619@2x.png

因此,ECE根据不同的版本,然后选择对应的docker image就可以创建一个节点了. 那么升级的过程就可以简单分成几个步骤

1.exclude准备升级的节点。

2.停止节点ES进程,更换container 版本。

3.重新启动节点,加入集群。

4.在其他节点上重复以上流程。

在这个过程中, 实际使用的时候发现有一些需要注意的雷区.
扫雷一:使用UI触发升级,必须保证集群没有自定义插件和bundles

ECE 里面的集群操作是通过plan来控制的

QQ20181221-104650@2x.png

任何的集群操作最终都会生成一个plan的diff。如上图,把集群从5.4.1 升级到 5.6.12 会产生以上diff.

正常情况下是没有问题的.

如果集群配置了自定义bundles, 比如LDAP bundles, ref:https://www.elastic.co/guide/e ... .html

那么在集群的plan里面就会存在这么一段配置

QQ20181221-104718@2x.png

那么当我们在按下升级按钮的时候

QQ20181221-104744@2x.png

ECE 只在plan中修改了集群大版本的配置, 但是并没有修改自定义bundles中的版本号(仍然是5.4.1).

在这种情况下去执行升级,会直接产生报错.

QQ20181221-104810@2x.png

界面上没有显示原因, 但是这是因为plan里面大版本和bundle中的版本不一致,然后会导致新增的节点无法启动. 于是ECE 就认为集群升级失败了.
解决方法是手动编辑plan,把自定义bundles中的版本号改成和集群版本一致

QQ20181221-104848@2x.png

然后使用ECE 提供的一种手动使用plan进行集群升级的方式进行升级.

扫雷二:节点无法关闭

ECE 控制container 是通过一个叫做 constructor的服务。constructor 通过接收集群的更改需求,制定具体的更改计划与步骤,指导allocator对container进行操作。同时也负责保证集群高可靠性,通过Availability Zone的数量在不同的AZ上面部署节点。

当Allocator接受到关闭container命令的时候,会尝试去关闭container,如果container处于一个阻塞状态无法响应, 那么关闭命令无法执行成功。这个时候constructor会等待节点关闭,但是allocator又认为节点已经接受到关闭命令了。又或者constructor发送给allocator的过程中网络丢包, 这个时候allocator 没有正确接受关闭container的命令. 整个升级进程就卡住了。 这种情况十分罕见,通常发现一个container如果处于”正在关闭”时间太久了, 那么通常就是中间的通信出现问题了.

QQ20181221-104926@2x.png

解决办法是可以通过手动停止container, 在对应的allocator上面找到container,使用

docker stop <container_name>

停止container,这样可以出发allocator更新container的健康状态,上报这个container已经关闭了, 从而打通流程并执行下一步。
扫雷三: 多版本并存

如果使用上面的方式强行关闭docker container, 虽然可以让升级进程继续进行下去. 但是被手动关闭的节点会保留原来的版本。于是在升级后查看各个节点的版本,会发现部分节点是5.4.1, 部分是5.6.12.

因为节点是强制关闭的, ECE直接认为节点已经完成升级,并重新启动这个container. 而在这个处理中,跳过了升级docker image的一步.

为什么不是生成一个新的container呢? 因为从plan里面可以看到

QQ20181221-104951@2x.png

在默认情况下, ECE 处理版本升级是使用rolling 策略 Ref: https://www.elastic.co/guide/e ... .html

在这个策略下,ECE会停止当前container并直接修改重启。

如果ECE集群容量允许, 可以改成grow_and_shrink 策略, 这样ECE 会创建新的container并且销毁旧的container, 避免集群出现多版本.
如果出现了多版本的集群,可以通过更改集群任意一个配置来触发 grow_and_shrink 同样可以使到版本回归一致.
总结来说ECE 在版本升级方面还是有很多需要改进的地方. 对于ECE用户再说在使用ECE的版本升级功能的时候主要有以下建议

1. 自己学会手动修改plan. 这也是每一个ECE support engineer 都会干的事情.

2.如果集群容量允许,尽量使用 grow_and_shrink的策略来进行集群操作.
  收起阅读 »

社区日报 第484期 (2018-12-20)

1.kibana本地文件安全漏洞CVE-2018-17246说明
http://t.cn/E45chlT
2.有赞全链路压测实战
http://t.cn/E45cViJ
3.Elasticsearch bool query小结
http://t.cn/E45cKEi

编辑:金桥
归档:https://elasticsearch.cn/article/6212
订阅:https://tinyletter.com/elastic-daily
继续阅读 »
1.kibana本地文件安全漏洞CVE-2018-17246说明
http://t.cn/E45chlT
2.有赞全链路压测实战
http://t.cn/E45cViJ
3.Elasticsearch bool query小结
http://t.cn/E45cKEi

编辑:金桥
归档:https://elasticsearch.cn/article/6212
订阅:https://tinyletter.com/elastic-daily 收起阅读 »

Day 20 - Elastic性能实战指南

让Elasticsearch飞起来!——性能优化实践干货

0、题记

Elasticsearch性能优化的最终目的:用户体验。 关于爽的定义——著名产品人梁宁曾经说过“人在满足时候的状态叫做愉悦,人不被满足就会难受,就会开始寻求。如果这个人在寻求中,能立刻得到即时满足,这种感觉就是爽!”。 Elasticsearch的爽点就是:快、准、全! 关于Elasticsearch性能优化,阿里、腾讯、京东、携程、滴滴、58等都有过很多深入的实践总结,都是非常好的参考。本文换一个思路,基于Elasticsearch的爽点,进行性能优化相关探讨。

1、集群规划优化实践

1.1 基于目标数据量规划集群

在业务初期,经常被问到的问题,要几个节点的集群,内存、CPU要多大,要不要SSD? 最主要的考虑点是:你的目标存储数据量是多大?可以针对目标数据量反推节点多少。

1.2 要留出容量Buffer

注意:Elasticsearch有三个警戒水位线,磁盘使用率达到85%、90%、95%。 不同警戒水位线会有不同的应急处理策略。 这点,磁盘容量选型中要规划在内。控制在85%之下是合理的。 当然,也可以通过配置做调整。

1.3 ES集群各节点尽量不要和其他业务功能复用一台机器。

除非内存非常大。 举例:普通服务器,安装了ES+Mysql+redis,业务数据量大了之后,势必会出现内存不足等问题。

1.4 磁盘尽量选择SSD

Elasticsearch官方文档肯定推荐SSD,考虑到成本的原因。需要结合业务场景, 如果业务对写入、检索速率有较高的速率要求,建议使用SSD磁盘。 阿里的业务场景,SSD磁盘比机械硬盘的速率提升了5倍。 但要因业务场景而异。

1.5 内存配置要合理

官方建议:堆内存的大小是官方建议是:Min(32GB,机器内存大小/2)。 Medcl和wood大叔都有明确说过,不必要设置32/31GB那么大,建议:热数据设置:26GB,冷数据:31GB。 总体内存大小没有具体要求,但肯定是内容越大,检索性能越好。 经验值供参考:每天200GB+增量数据的业务场景,服务器至少要64GB内存。 除了JVM之外的预留内存要充足,否则也会经常OOM。

1.6 CPU核数不要太小

CPU核数是和ESThread pool关联的。和写入、检索性能都有关联。 建议:16核+

1.7 超大量级的业务场景,可以考虑跨集群检索

除非业务量级非常大,例如:滴滴、携程的PB+的业务场景,否则基本不太需要跨集群检索。

1.8 集群节点个数无需奇数

ES内部维护集群通信,不是基于zookeeper的分发部署机制,所以,无需奇数。 但是discovery.zen.minimum_master_nodes的值要设置为:候选主节点的个数/2+1,才能有效避免脑裂。

1.9 节点类型优化分配

集群节点数:<=3,建议:所有节点的master:true, data:true。既是主节点也是路由节点。 集群节点数:>3, 根据业务场景需要,建议:逐步独立出Master节点和协调/路由节点。

1.10 建议冷热数据分离

热数据存储SSD和普通历史数据存储机械磁盘,物理上提高检索效率。

2、索引优化实践

Mysql等关系型数据库要分库、分表。Elasticserach的话也要做好充分的考虑。

2.1 设置多少个索引?

建议根据业务场景进行存储。 不同通道类型的数据要分索引存储。举例:知乎采集信息存储到知乎索引;APP采集信息存储到APP索引。

2.2 设置多少分片?

建议根据数据量衡量。 经验值:建议每个分片大小不要超过30GB

2.3 分片数设置?

建议根据集群节点的个数规模,分片个数建议>=集群节点的个数。 5节点的集群,5个分片就比较合理。 注意:除非reindex操作,分片数是不可以修改的。

2.4副本数设置?

除非你对系统的健壮性有异常高的要求,比如:银行系统。可以考虑2个副本以上。 否则,1个副本足够。 注意:副本数是可以通过配置随时修改的。

2.5不要再在一个索引下创建多个type

即便你是5.X版本,考虑到未来版本升级等后续的可扩展性。 建议:一个索引对应一个type。6.x默认对应_doc,5.x你就直接对应type统一为doc。

2.6 按照日期规划索引

随着业务量的增加,单一索引和数据量激增给的矛盾凸显。 按照日期规划索引是必然选择。 好处1:可以实现历史数据秒删。很对历史索引delete即可。注意:一个索引的话需要借助delete_by_query+force_merge操作,慢且删除不彻底。 好处2:便于冷热数据分开管理,检索最近几天的数据,直接物理上指定对应日期的索引,速度快的一逼! 操作参考:模板使用+rollover API使用

2.7 务必使用别名

ES不像mysql方面的更改索引名称。使用别名就是一个相对灵活的选择。

3、数据模型优化实践

3.1 不要使用默认的Mapping

默认Mapping的字段类型是系统自动识别的。其中:string类型默认分成:text和keyword两种类型。如果你的业务中不需要分词、检索,仅需要精确匹配,仅设置为keyword即可。 根据业务需要选择合适的类型,有利于节省空间和提升精度,如:浮点型的选择。

3.2 Mapping各字段的选型流程

11.png

3.3 选择合理的分词器

常见的开源中文分词器包括:ik分词器、ansj分词器、hanlp分词器、结巴分词器、海量分词器、“ElasticSearch最全分词器比较及使用方法” 搜索可查看对比效果。 如果选择ik,建议使用ik_max_word。因为:粗粒度的分词结果基本包含细粒度ik_smart的结果。

3.4 date、long、还是keyword

根据业务需要,如果需要基于时间轴做分析,必须date类型; 如果仅需要秒级返回,建议使用keyword

4、数据写入优化实践

4.1 要不要秒级响应?

Elasticsearch近实时的本质是:最快1s写入的数据可以被查询到。 如果refresh_interval设置为1s,势必会产生大量的segment,检索性能会受到影响。 所以,非实时的场景可以调大,设置为30s,甚至-1。

4.2 减少副本,提升写入性能。

写入前,副本数设置为0, 写入后,副本数设置为原来值。

4.3 能批量就不单条写入

批量接口为bulk,批量的大小要结合队列的大小,而队列大小和线程池大小、机器的cpu核数。

4.4 禁用swap

在Linux系统上,通过运行以下命令临时禁用交换:

sudo swapoff -a

5、检索聚合优化实战

5.1 禁用 wildcard模糊匹配

数据量级达到TB+甚至更高之后,wildcard在多字段组合的情况下很容易出现卡死,甚至导致集群节点崩溃宕机的情况。 后果不堪设想。 替代方案: 方案一:针对精确度要求高的方案:两套分词器结合,standard和ik结合,使用match_phrase检索。 方案二:针对精确度要求不高的替代方案:建议ik分词,通过match_phrase和slop结合查询。

5.2极小的概率使用match匹配

中文match匹配显然结果是不准确的。很大的业务场景会使用短语匹配“match_phrase"。 match_phrase结合合理的分词词典、词库,会使得搜索结果精确度更高,避免噪音数据。

5.3 结合业务场景,大量使用filter过滤器

对于不需要使用计算相关度评分的场景,无疑filter缓存机制会使得检索更快。 举例:过滤某邮编号码。

5.3控制返回字段和结果

和mysql查询一样,业务开发中,select * 操作几乎是不必须的。 同理,ES中,_source 返回全部字段也是非必须的。 要通过_source 控制字段的返回,只返回业务相关的字段。 网页正文content,网页快照html_content类似字段的批量返回,可能就是业务上的设计缺陷。 显然,摘要字段应该提前写入,而不是查询content后再截取处理。

5.4 分页深度查询和遍历

分页查询使用:from+size; 遍历使用:scroll; 并行遍历使用:scroll+slice。 斟酌集合业务选型使用。

5.5 聚合Size的合理设置

聚合结果是不精确的。除非你设置size为2的32次幂-1,否则聚合的结果是取每个分片的Top size元素后综合排序后的值。 实际业务场景要求精确反馈结果的要注意。 尽量不要获取全量聚合结果——从业务层面取TopN聚合结果值是非常合理的。因为的确排序靠后的结果值意义不大。

5.6 聚合分页合理实现

聚合结果展示的时,势必面临聚合后分页的问题,而ES官方基于性能原因不支持聚合后分页。 如果需要聚合后分页,需要自开发实现。包含但不限于: 方案一:每次取聚合结果,拿到内存中分页返回。 方案二:scroll结合scroll after集合redis实现。

6、业务优化

让Elasticsearch做它擅长的事情,很显然,它更擅长基于倒排索引进行搜索。 业务层面,用户想最快速度看到自己想要的结果,中间的“字段处理、格式化、标准化”等一堆操作,用户是不关注的。 为了让Elasticsearch更高效的检索,建议: 1)要做足“前戏” 字段抽取、倾向性分析、分类/聚类、相关性判定放在写入ES之前的ETL阶段进行; 2)“睡服”产品经理 产品经理基于各种奇葩业务场景可能会提各种无理需求。 作为技术人员,要“通知以情晓之以理”,给产品经理讲解明白搜索引擎的原理、Elasticsearch的原理,哪些能做,哪些真的“臣妾做不到”。

7、小结

实际业务开发中,公司一般要求又想马儿不吃草,又想马儿飞快跑。 对于Elasticsearch开发也是,硬件资源不足(cpu、内存、磁盘都爆满)几乎没有办法提升性能的。 除了检索聚合,让Elasticsearch做N多相关、不相干的工作,然后得出结论“Elastic也就那样慢,没有想像的快”。 你脑海中是否也有类似的场景浮现呢? 提供相对NB的硬件资源、做好前期的各种准备工作、让Elasticsearch轻装上阵,相信你的Elasticsearch也会飞起来!

来日我们再相会......

推荐阅读: 1、阿里:https://elasticsearch.cn/article/6171 2、滴滴:http://t.cn/EUNLkNU 3、腾讯:http://t.cn/E4y9ylL 4、携程:https://elasticsearch.cn/article/6205 5、社区:https://elasticsearch.cn/article/6202 6、社区:https://elasticsearch.cn/article/708 7、社区:https://elasticsearch.cn/article/6202

33.jpg

Elasticsearch基础、进阶、实战第一公众号

继续阅读 »

让Elasticsearch飞起来!——性能优化实践干货

0、题记

Elasticsearch性能优化的最终目的:用户体验。 关于爽的定义——著名产品人梁宁曾经说过“人在满足时候的状态叫做愉悦,人不被满足就会难受,就会开始寻求。如果这个人在寻求中,能立刻得到即时满足,这种感觉就是爽!”。 Elasticsearch的爽点就是:快、准、全! 关于Elasticsearch性能优化,阿里、腾讯、京东、携程、滴滴、58等都有过很多深入的实践总结,都是非常好的参考。本文换一个思路,基于Elasticsearch的爽点,进行性能优化相关探讨。

1、集群规划优化实践

1.1 基于目标数据量规划集群

在业务初期,经常被问到的问题,要几个节点的集群,内存、CPU要多大,要不要SSD? 最主要的考虑点是:你的目标存储数据量是多大?可以针对目标数据量反推节点多少。

1.2 要留出容量Buffer

注意:Elasticsearch有三个警戒水位线,磁盘使用率达到85%、90%、95%。 不同警戒水位线会有不同的应急处理策略。 这点,磁盘容量选型中要规划在内。控制在85%之下是合理的。 当然,也可以通过配置做调整。

1.3 ES集群各节点尽量不要和其他业务功能复用一台机器。

除非内存非常大。 举例:普通服务器,安装了ES+Mysql+redis,业务数据量大了之后,势必会出现内存不足等问题。

1.4 磁盘尽量选择SSD

Elasticsearch官方文档肯定推荐SSD,考虑到成本的原因。需要结合业务场景, 如果业务对写入、检索速率有较高的速率要求,建议使用SSD磁盘。 阿里的业务场景,SSD磁盘比机械硬盘的速率提升了5倍。 但要因业务场景而异。

1.5 内存配置要合理

官方建议:堆内存的大小是官方建议是:Min(32GB,机器内存大小/2)。 Medcl和wood大叔都有明确说过,不必要设置32/31GB那么大,建议:热数据设置:26GB,冷数据:31GB。 总体内存大小没有具体要求,但肯定是内容越大,检索性能越好。 经验值供参考:每天200GB+增量数据的业务场景,服务器至少要64GB内存。 除了JVM之外的预留内存要充足,否则也会经常OOM。

1.6 CPU核数不要太小

CPU核数是和ESThread pool关联的。和写入、检索性能都有关联。 建议:16核+

1.7 超大量级的业务场景,可以考虑跨集群检索

除非业务量级非常大,例如:滴滴、携程的PB+的业务场景,否则基本不太需要跨集群检索。

1.8 集群节点个数无需奇数

ES内部维护集群通信,不是基于zookeeper的分发部署机制,所以,无需奇数。 但是discovery.zen.minimum_master_nodes的值要设置为:候选主节点的个数/2+1,才能有效避免脑裂。

1.9 节点类型优化分配

集群节点数:<=3,建议:所有节点的master:true, data:true。既是主节点也是路由节点。 集群节点数:>3, 根据业务场景需要,建议:逐步独立出Master节点和协调/路由节点。

1.10 建议冷热数据分离

热数据存储SSD和普通历史数据存储机械磁盘,物理上提高检索效率。

2、索引优化实践

Mysql等关系型数据库要分库、分表。Elasticserach的话也要做好充分的考虑。

2.1 设置多少个索引?

建议根据业务场景进行存储。 不同通道类型的数据要分索引存储。举例:知乎采集信息存储到知乎索引;APP采集信息存储到APP索引。

2.2 设置多少分片?

建议根据数据量衡量。 经验值:建议每个分片大小不要超过30GB

2.3 分片数设置?

建议根据集群节点的个数规模,分片个数建议>=集群节点的个数。 5节点的集群,5个分片就比较合理。 注意:除非reindex操作,分片数是不可以修改的。

2.4副本数设置?

除非你对系统的健壮性有异常高的要求,比如:银行系统。可以考虑2个副本以上。 否则,1个副本足够。 注意:副本数是可以通过配置随时修改的。

2.5不要再在一个索引下创建多个type

即便你是5.X版本,考虑到未来版本升级等后续的可扩展性。 建议:一个索引对应一个type。6.x默认对应_doc,5.x你就直接对应type统一为doc。

2.6 按照日期规划索引

随着业务量的增加,单一索引和数据量激增给的矛盾凸显。 按照日期规划索引是必然选择。 好处1:可以实现历史数据秒删。很对历史索引delete即可。注意:一个索引的话需要借助delete_by_query+force_merge操作,慢且删除不彻底。 好处2:便于冷热数据分开管理,检索最近几天的数据,直接物理上指定对应日期的索引,速度快的一逼! 操作参考:模板使用+rollover API使用

2.7 务必使用别名

ES不像mysql方面的更改索引名称。使用别名就是一个相对灵活的选择。

3、数据模型优化实践

3.1 不要使用默认的Mapping

默认Mapping的字段类型是系统自动识别的。其中:string类型默认分成:text和keyword两种类型。如果你的业务中不需要分词、检索,仅需要精确匹配,仅设置为keyword即可。 根据业务需要选择合适的类型,有利于节省空间和提升精度,如:浮点型的选择。

3.2 Mapping各字段的选型流程

11.png

3.3 选择合理的分词器

常见的开源中文分词器包括:ik分词器、ansj分词器、hanlp分词器、结巴分词器、海量分词器、“ElasticSearch最全分词器比较及使用方法” 搜索可查看对比效果。 如果选择ik,建议使用ik_max_word。因为:粗粒度的分词结果基本包含细粒度ik_smart的结果。

3.4 date、long、还是keyword

根据业务需要,如果需要基于时间轴做分析,必须date类型; 如果仅需要秒级返回,建议使用keyword

4、数据写入优化实践

4.1 要不要秒级响应?

Elasticsearch近实时的本质是:最快1s写入的数据可以被查询到。 如果refresh_interval设置为1s,势必会产生大量的segment,检索性能会受到影响。 所以,非实时的场景可以调大,设置为30s,甚至-1。

4.2 减少副本,提升写入性能。

写入前,副本数设置为0, 写入后,副本数设置为原来值。

4.3 能批量就不单条写入

批量接口为bulk,批量的大小要结合队列的大小,而队列大小和线程池大小、机器的cpu核数。

4.4 禁用swap

在Linux系统上,通过运行以下命令临时禁用交换:

sudo swapoff -a

5、检索聚合优化实战

5.1 禁用 wildcard模糊匹配

数据量级达到TB+甚至更高之后,wildcard在多字段组合的情况下很容易出现卡死,甚至导致集群节点崩溃宕机的情况。 后果不堪设想。 替代方案: 方案一:针对精确度要求高的方案:两套分词器结合,standard和ik结合,使用match_phrase检索。 方案二:针对精确度要求不高的替代方案:建议ik分词,通过match_phrase和slop结合查询。

5.2极小的概率使用match匹配

中文match匹配显然结果是不准确的。很大的业务场景会使用短语匹配“match_phrase"。 match_phrase结合合理的分词词典、词库,会使得搜索结果精确度更高,避免噪音数据。

5.3 结合业务场景,大量使用filter过滤器

对于不需要使用计算相关度评分的场景,无疑filter缓存机制会使得检索更快。 举例:过滤某邮编号码。

5.3控制返回字段和结果

和mysql查询一样,业务开发中,select * 操作几乎是不必须的。 同理,ES中,_source 返回全部字段也是非必须的。 要通过_source 控制字段的返回,只返回业务相关的字段。 网页正文content,网页快照html_content类似字段的批量返回,可能就是业务上的设计缺陷。 显然,摘要字段应该提前写入,而不是查询content后再截取处理。

5.4 分页深度查询和遍历

分页查询使用:from+size; 遍历使用:scroll; 并行遍历使用:scroll+slice。 斟酌集合业务选型使用。

5.5 聚合Size的合理设置

聚合结果是不精确的。除非你设置size为2的32次幂-1,否则聚合的结果是取每个分片的Top size元素后综合排序后的值。 实际业务场景要求精确反馈结果的要注意。 尽量不要获取全量聚合结果——从业务层面取TopN聚合结果值是非常合理的。因为的确排序靠后的结果值意义不大。

5.6 聚合分页合理实现

聚合结果展示的时,势必面临聚合后分页的问题,而ES官方基于性能原因不支持聚合后分页。 如果需要聚合后分页,需要自开发实现。包含但不限于: 方案一:每次取聚合结果,拿到内存中分页返回。 方案二:scroll结合scroll after集合redis实现。

6、业务优化

让Elasticsearch做它擅长的事情,很显然,它更擅长基于倒排索引进行搜索。 业务层面,用户想最快速度看到自己想要的结果,中间的“字段处理、格式化、标准化”等一堆操作,用户是不关注的。 为了让Elasticsearch更高效的检索,建议: 1)要做足“前戏” 字段抽取、倾向性分析、分类/聚类、相关性判定放在写入ES之前的ETL阶段进行; 2)“睡服”产品经理 产品经理基于各种奇葩业务场景可能会提各种无理需求。 作为技术人员,要“通知以情晓之以理”,给产品经理讲解明白搜索引擎的原理、Elasticsearch的原理,哪些能做,哪些真的“臣妾做不到”。

7、小结

实际业务开发中,公司一般要求又想马儿不吃草,又想马儿飞快跑。 对于Elasticsearch开发也是,硬件资源不足(cpu、内存、磁盘都爆满)几乎没有办法提升性能的。 除了检索聚合,让Elasticsearch做N多相关、不相干的工作,然后得出结论“Elastic也就那样慢,没有想像的快”。 你脑海中是否也有类似的场景浮现呢? 提供相对NB的硬件资源、做好前期的各种准备工作、让Elasticsearch轻装上阵,相信你的Elasticsearch也会飞起来!

来日我们再相会......

推荐阅读: 1、阿里:https://elasticsearch.cn/article/6171 2、滴滴:http://t.cn/EUNLkNU 3、腾讯:http://t.cn/E4y9ylL 4、携程:https://elasticsearch.cn/article/6205 5、社区:https://elasticsearch.cn/article/6202 6、社区:https://elasticsearch.cn/article/708 7、社区:https://elasticsearch.cn/article/6202

33.jpg

Elasticsearch基础、进阶、实战第一公众号

收起阅读 »

社区日报 第483期 (2018-12-19)

1、ECE 2.0:为你的使用场景助力加油。
http://t.cn/E421UUE
​2、(自备梯子)如何使用es和react构建电子商务搜索。
http://t.cn/E42BSad
​3、Elastic:Beyond Search!
http://t.cn/E42dIzz

编辑:wt
归档:https://elasticsearch.cn/article/6210
订阅:https://tinyletter.com/elastic-daily
继续阅读 »
1、ECE 2.0:为你的使用场景助力加油。
http://t.cn/E421UUE
​2、(自备梯子)如何使用es和react构建电子商务搜索。
http://t.cn/E42BSad
​3、Elastic:Beyond Search!
http://t.cn/E42dIzz

编辑:wt
归档:https://elasticsearch.cn/article/6210
订阅:https://tinyletter.com/elastic-daily 收起阅读 »