最近因为一个项目涉及到了搜索相关的需求,elasticsearch可以说是目前最流行,最受欢迎的企业搜索引擎,所以在技术选型上自然的选择ES作为搜索引擎的实现,由于自己也是第一次接触elasticsearch,故写下这篇文章总结下自己在使用学习ES过程中的一些经验教训。
一、Elasticsearch简介
1.产品简介
Elasticsearch是一个开源的分布式、RESTful 风格的搜索和数据分析引擎,它的底层是开源库Apache Lucene,Lucene 可以说是当下最先进、高性能、全功能的搜索引擎库——无论是开源还是私有,但它也仅仅只是一个库。为了充分发挥其功能,你需要使用 Java 并将 Lucene 直接集成到应用程序中,且lucene的使用十分负责,你需要了解很多搜索领域的专业知识才可能明白它的原理,为了解决lucene的易用性问题,Elasticsearch应运而生。
Elasticsearch不仅仅是对Lucene做了简单的封装,它本身是一个可以独立部署的高可用的分布式系统,可弹性伸缩支持多至上百个节点,且有配套的可视化管理平台(kibana),极大的降低elasticsearch的运维成本,它封装了一套统一而又简洁的REST接口,对外提供搜索能力,所以依赖的系统可以是任何语言实现的,只需要通过HTTP请求与elasticsearch交互即可,除此之外,依托于分布式的优势,Elasticsearch的性能十分优秀,可轻松支持数亿量级的文档搜索。由于Elasticsearch的功能强大和使用简单,维基百科、卫报、Stack Overflow、GitHub等都纷纷采用它来做搜索。现在,Elasticsearch已成为全文搜索领域的主流软件之一。
2.应用场景
elasticsearch的应用场景非常广泛,由于它是一个搜索引擎,所有依赖于搜索能力的场景都可以用到elasticsearch,包括但不限以下所列举的场景:
1.日志检索,最常用的场景,事实上,elasticsearch+logstash+kibnana已经快成为日志检索的标准技术栈了。
2.指标的度量和观测,elasticsearch拥有强大的数据聚合能力,可以针对给定的数据做各种维度的聚合操作(求平均/求和/求最大值等),且响应速度很快,适合做一些系统指标的监控和度量(如CPU的负载变化趋势,最大值/最小值/平均值等)。
3.地理位置搜索,elasticsearch支持地址位置搜索,基于这个强大的能力我们可以实现一些有趣的能力:如搜索附近的人/店铺/停车场等信息。
4.任何需要用到全文搜索的场景,如媒体网站(文章搜索),社区问答(搜索答案或者问题)等等。
二、ES入门学习
1.一些基础概念
这里主要介绍下一些比较基础且重要的概念,elasticsearch本质上也是一种NoSql数据库,很多概念其实可以和关系型数据库匹配上。
●index:索引,类似于mysql中的database,一个索引就是一个库,一般具有相同特性的document会存放在一个index里,index需要定义对应的setiings,如配置索引的刷新时间/分片数量,分析器等配置信息。
●type:type是定义在index下的,类似于数据库中的表,一个索引下可以有多个type,type必须定一个mapping信息,即定一个这个type有哪些字段,分别是什么类型,索引时如何处理这个字段。(注:type在6.0版本后已经逐渐被废弃了,也就是说一个index就对应一张表了。)
●document:文档,是es中可被索引的最小单位,类似于数据库中的一行记录,以json格式序列化保存,每个document都会有一个ID主键和一个版本号,document是不可更改的,每次更新都是将之前的记录删除,再保存新的记录,并将版本号+1。
●shard:分片,elasticsearch是分布式的,分片就是用来定义索引的数据是如何分布的,每个index索引都需要定义主分片/和副本分片的数量,ES会根据分片的数量来将索引的数据均匀的分发到集群的节点中,充分利用集群的优势,不过这里需要注意主分片的数量是不可改变的,所以我们在使用ES的时候需要做好容量规划,如果后续需要增加分片时,则需要重新索引数据。
2.倒排索引
如果我们要搜索某段文本中是否包含某个关键字,如果是关系型数据库,如mysql,则需要用到like模糊匹配查询,如select * from table where conent like'%keyword%',我们都知道这样的模糊匹配是无法走索引的,这个sql会导致全表扫描,当数据量很大时,速度就很慢了,而elasticsearch却能很快的搜索出对应的文档,这是因为elasticsearch采用了一种叫“倒排索引”的数据结构来实现的,其实个人认为“倒排索引”这个翻译并不是很准确,叫“反向索引”可能更合适,如上诉所说,mysql的模糊匹配查询很慢是因为搜索的关键字没有的对应的索引,那如果在存储的时候,将文本内容中的关键字提取出来作为索引,不就可以通过关键字快速定位到某段文本内容了么,事实上elasticsearch就是这么做的,如果你将某个字段类型设置为text,elasticsearch在索引文档时,会对这个字段的值进行分析处理,将这个字段的值拆分成一个一个词条(Term),每个词条都会反向指向到