Elasticsearch (ES) 是一个基于 Lucene 构建的开源、分布式、RESTful 接口全文搜索引擎。仍是一个分布式文档数据库,其中每一个字段均是被索引的数据且可被搜索,它可以扩展至数以百计的服务器存储以及处理PB级的数据。它能够在很短的时间内在储、搜索和分析大量的数据。它一般做为具备复杂搜索场景状况下的核心发动机。css
官网:https://www.elastic.co/downloads/elasticsearch
中文社区:https://es.xiaoleilu.com/
什么是PB级别:https://baike.baidu.com/item/PetaByte/5910820html
若是使用数据库进行模糊查询,好比 like 语句,他会遍历整张表,同时进行字符串匹配,若是数据库数据量很是庞大的话,会很是消耗资源和时间。java
在换用 Elasticsearch 后,TB级别数据也能在毫秒级就能返回检索结果。node
缘由:Elasticsearch是基于倒排索引的web
在使用数据库的前提下,组合词检索是很是困难的,好比,当用户在搜索框输入"四川火锅”时,数据库一般只能把这四个字去进行所有匹配。但是在文本中,可能会出现“推荐四川好吃的火锅”,这时候就没有结果了。数据库
缘由:数据库并不支持分词。若是人工去开发分词功能,费时费精力。json
若是换用 Elasticsearch,使用云搜索服务后,就不用太过于关注分词了,由于 Elasticsearch 支持中文分词插件,很好地解决了问题。当用户使用Elasticsearch时进行搜索时,Elasticsearch 就自动帮他分好词了。服务器
例如当输入“四川火锅”时,Elasticsearch会自动作下面两件事 :微信
在用数据库作搜索时,结果常常会出现一系列文档。可是数据库并不支持相关性搜索。 数据结构
例如,当用户搜索“咖啡厅”的时候,他极可能更想知道附近哪里能够喝咖啡,而不是怎么开咖啡厅。
当使用了云搜索服务后,发现 Elasticsearch 能很好地支持相关性评分。经过合理的优化,云搜索服务可以返回精准的结果,知足用户的需求。
缘由: Elasticsearch 支持全文搜索和相关度评分。这样在返回结果就会根据分数由高到低排列。分数越高,意味着和查询语句越相关。
因此,当用户搜索“星巴克咖啡”,带有“星巴克咖啡”的信息就要比只包含“咖啡”的信息靠前。
Elasticsearch 是为高可用和可扩展而生的。能够经过购置性能更强的服务器来完成。
横向可扩展性:只须要增长台服务器,作一点儿配置,启动一下 Elasticsearch 就能够并入集群。
分片机制提供更好的分布性:同一个索引分红多个分片(sharding), 这点相似于HDFS的块机制;分而治之的方式可提高处理效率。
高可用:提供复制( replica) 机制,一个分片能够设置多个复制,使得某台服务器在宕机的状况下,集群仍旧能够照常运行,并会把服务器宕机丢失的数据信息复制恢复到其余可用节点上。
在使用数据库进行查询数据时,不少时候都是经过工程代码或者命令端完成。其实在分析结果时并不太方便,缺乏一个可视化界面来提升效率。
缘由: 数据库自身一般不带可视化界面。而在完成搜索相关的任务时,经常须要根据搜索结果来进行分析。
而 Kibana 可视化工具则完美支持 Elasticsearch。研发人员可以在上面快速地进行概念验证,分析结果,提升开发效率。
Elasticsearch是面向文档型数据库的,一条数据即一个文档,用 JSON 做为文档序列化的格式,好比下面这条用户数据:
{
"name" : "John",
"sex" : "Male",
"age" : 25,
"birthDate": "1990/05/01",
"about" : "I love to go rock climbing",
"interests": [ "sports", "music" ]
}
关于Elasticsearch以及Kibana的安装请参考以前的一篇文章:<了解一下Elasticsearch的基本概念>
首先 Elasticsearch 使用的是倒排索引,何为倒排索引?
如上图,当用户搜索“手机”时,Elasticsearch 就会当即返回文档 F,G,H。这样就不用花多余的时间在其余文档上了,所以检索速度获得了数量级的提高。
也许你还不太了解倒排索引,甚至是正向索引也不了解?
正向索引是文档与关键词一一对应的数据结构。
其以文档的ID为关键字,表中记录文档中每一个字的位置信息,查找时扫描表中每一个文档中字的信息直到找出全部包含查询关键字的文档。
这种组织方法在创建索引的时候结构比较简单,创建比较方便且易于维护;由于索引是基于文档创建的,如果有新的文档加入,直接为该文档创建一个新的索引块,挂接在原来索引文件的后面。如果有文档删除,则直接找到该文档号文档对应的索引信息,将其直接删除。可是在查询的时候需对全部的文档进行扫描以确保没有遗漏,这样就使得检索时间大大延长,检索效率低下。
尽管正向索引的工做原理很是的简单,可是因为其检索效率过低,除非在特定状况下,不然实用性价值不大。
为了进一步理解,在这举个例子:
咱们假设有网页1和网页2:
网页1中仅包含一句话:厦门SEO顾问潇湘驭文为您提供厦门SEO培训服务。
网页2中也仅包含一句话:SEO是一门艺术。
通过搜索引擎初步分词以后,网页1和2的正向索引以下图所示:
假设使用正向索引,那么当你搜索SEO的时候,搜索引擎必须检索网页中的每个关键词,假设一个网页中包含成千上百个关键词,可想而知,会形成大量的资源浪费。因而倒排索引应运而生。
正向索引是关键词与文档一一对应的数据结构。
其以字或词为关键字进行索引,表中关键字所对应的记录表项记录了出现这个字或词的全部文档,一个表项就是一个字表段,它记录该文档的ID和字符在该文档中出现的位置状况。
因为每一个字或词对应的文档数量在动态变化,因此倒排表的创建和维护都较为复杂,可是在查询的时候因为能够一次获得查询关键字所对应的全部文档,因此效率高于正排表。
在全文检索中,检索的快速响应是一个最为关键的性能,而索引创建因为在后台进行,尽管效率相对低一些,但不会影响整个搜索引擎的效率。
归纳:正排索引是从文档到关键字的映射(已知文档求关键字),倒排索引是从关键字到文档的映射(已知关键字求文档)。
咱们再来看一下上边的例子用倒排索引是什么样的。
从上图能够一目了然,倒排索引能够直接参与排名。
好比你搜索“SEO”,搜索引擎能够快速检索出包含“SEO”搜索词的网页1和网页2,为后续的相关度和权重计算奠基基础,从而大大加快了返回搜索结果的速度。
再看一个例子:
倒排索引会对以上文档内容进行关键词分词,可使用关键词直接定位到文档内容。
当你搜索[科技公司]后,会当即返回序号id为[1,2,4,5]的文档,而不是去进行全文关键字匹配。
ES 中的查询请求有两种方式,一种是简易版的查询,另一种是使用JSON完整的请求体,叫作结构化查询(DSL)。
因为DSL查询更为直观也更为简易,因此大都使用这种方式。
DSL查询是POST过去一个JSON,因为POST的请求是JSON格式的,因此存在不少灵活性,也有不少形式。
举个例子,详细的可自行查询了解:
根据名称精准查询姓名:
GET ttyy/user/_search
{
"query": {
"term": {
"name": "奶茶"
}
}
}
其中 term 是表明彻底匹配,即不进行分词器分析,文档中必须包含整个搜索的词汇;相似的还有 Match;
由于 Elasticsearch 中默认的标准分词器分词器对中文分词不是很友好,会将中文词语拆分红一个一个中文的汉字,所以引入中文分词器 ik 插件。
演示传统分词器
{
"analyzer": "standard",
"text": "奥迪a4l"
}
{
"tokens": [
{
"token": "奥",
"start_offset": 0,
"end_offset": 1,
"type": "<IDEOGRAPHIC>",
"position": 0
},
{
"token": "迪",
"start_offset": 1,
"end_offset": 2,
"type": "<IDEOGRAPHIC>",
"position": 1
},
{
"token": "a4l",
"start_offset": 2,
"end_offset": 5,
"type": "<ALPHANUM>",
"position": 2
}
]
}
采用 ik 分词器后:
{
"analyzer": "ik_smart",
"text": "奥迪"
}
{
"tokens": [
{
"token": "奥迪",
"start_offset": 0,
"end_offset": 2,
"type": "CN_WORD",
"position": 0
},
{
"token": "a4l",
"start_offset": 2,
"end_offset": 5,
"type": "LETTER",
"position": 1
}
]
}
在搭建集群以前先了解一下es为何要实现集群。
ES集群中索引可能由多个分片构成,而且每一个分片能够拥有多个副本。经过将一个单独的索引分为多个分片,咱们能够处理不能在一个单一的服务器上面运行的大型索引,简单的说就是索引的大小过大,致使效率问题。不能运行的缘由多是内存也多是存储。
因为每一个分片能够有多个副本,经过将副本分配到多个服务器,能够提升查询的负载能力。
简而言之就是提升查询的负载能力。
数据存储。
一、每一个索引会被分红多个分片shards进行存储,默认建立索引是分配5个分片进行存储。
每一个分片都会分布式部署在多个不一样的节点上进行部署,该分片成为primary shards。
注意:索引的主分片primary shards定义好后,后面不能作修改。
二、为了实现高可用数据的高可用,主分片能够有对应的备分片replics shards,replic shards分片承载了负责容错、以及请求的负载均衡。
**注意: **每个主分片为了实现高可用,都会有本身对应的备分片,主分片对应的备分片不能存放同一台服务器上。,主分片primary shards能够和其余replics shards存放在同一个node节点上。
补充1:单台ES服务器中是没有备份分片的
补充2:主分片对应的备份分片不能存放在同一台服务器上。
以下图所示:
Node表示服务器,P表示主分片,R表示备份分片
准备三台服务器
服务器名称 | IP地址 |
---|---|
node-1 | 192.168.212.182 |
node-2 | 192.168.212.183 |
node-3 | 192.168.212.184 |
服务集群配置
vi elasticsearch.yml
cluster.name: myes ###保证三台服务器节点集群名称相同
node.name: node-1 #### 每一个节点名称不同 其余两台为 node-1 ,node-2
network.host: 192.168.212.180 #### 实际服务器ip地址
discovery.zen.ping.unicast.hosts: ["192.168.212.184", "192.168.212.185","192.168.212.186"]##多个服务集群ip
discovery.zen.minimum_master_nodes: 1
关闭防火墙 systemctl stop firewalld.service
默认底层开启9300 集群
验证集群效果:
http://192.168.212.185:9200/_cat/nodes?pretty
参考文章:
https://blog.csdn.net/weixin_39819880/article/details/82083034
https://www.cnblogs.com/dreamroute/p/8484457.html
我建立了一个java相关的公众号,用来记录本身的学习之路,感兴趣的小伙伴能够关注一下微信公众号哈:niceyoo