不点蓝字,我们哪来故事?

大家都知道现在是大数据的时代,海量的数据对企业带来的是更大的挑战,只有关系型数据库已经不能满足企业的需求了。这时候很多企业开始引入搜索引擎。
Elasticsearch是一个搜索引擎。
用数据库,也可以实现搜索的功能,为什么还需要搜索引擎呢?
就像 Stackoverflow 的网友说的:
A relational database can store data and also index it. A search engine can index data but also store it.
数据库(理论上来讲,Elasticsearch 也是数据库,这里的数据库,指的是关系型数据库),首先是存储,搜索只是顺便提供的功能,
而搜索引擎,首先是搜索,但是不把数据存下来就搜不了,所以只好存一存。
术业有专攻,专攻搜索的搜索引擎,自然会提供更强大的搜索能力。
下面我们就要来正式介绍一下时下最火的搜索引擎 - Elasticsearch。
看看它到底有什么魔力,为什么备受各大企业的青睐。
本系列基于Elasticsearch 7.6.x 版本
Elasticsearch概述
Elasticsearch,简称es,是一个开源的、高扩展的、分布式全文搜索引擎。
它可以近乎实时的存储、检索数据。本身拓展性很好,可以扩展到上百台机器,处理PB级别的数据。
es是使用Java开发并使用Lucene作为其核心来实现所有索引和搜索的功能。但是它的目的是通过简单的Restful API来隐藏Lucene的复杂性,从而使全文搜索变得简单。
根据国际权威的数据库产品测评机构DB Engines的统计,在2016年1月,Elasticsearch已超过solr等,成为排名第一的搜索引擎类应用。
上面提到es是一个基于Apache Lucene的开源搜索引擎。无论在开源还是专有领域,Lucene可以被认为是迄今为止最先进、性能最好的、功能最全的搜索引擎库。
但是,Lucene只是一个库,想要使用它,必须使用Java来作为开发语言并将其直接集成到你的应用中,更糟糕的是,Lucene非常复杂,你需要深入研究了解检索相关知识来理解它是如何工作的。
历史
接下来想聊聊Elasticsearch是怎么诞生,好知道当初这项技术是为了解决什么“痛点”而来的这个世界。(这个痛点有点浪漫)
多年前,一个叫做刚结婚不就的失业开发者Shay Banon,由于妻子要去伦敦学厨师,他便跟着去了。在他找工作的过程中,为了给妻子构建一个食谱的所搜引擎,他开始构建一个早期版本的Lucene。
我老婆啥时候给我出点难题,让我写出一个改变世界的开源应用啊!顺便提一句:这样的开发人员还能失业,真的离谱。
直接基于Lucene工作会比较困难,所以Shay Banon开始抽象Lucene代码以便Java程序员可以在应用中添加搜索功能。他发布了他的第一个开源项目,叫做Compass。
后来Shay Banon找到一份工作,这份工作处在高性能和内存数据网格的分布式环境中,因此高性能的、实时的、分布式的搜索引擎也是必须的。然后他决定重写Compass库使其成为一个独立的服务,叫做Elasticsearch。
第一个公开版本出现在2010年2月,在那之后Elasticsearch已经成为Github上最受欢迎的项目之一,代码贡献者超过300人。一家主营Elasticsearch的公司就此成立,他们一边提供商业支持,一边开发新功能,不过Elasticsearch将永远开源且对所有人可用。
使用场景
维基百科。全文检索,高亮,搜索推荐。
The Guardian,类似搜狐新闻。用户行为日志(点击,浏览,收藏,评论)+ 社交网络数据(对某某新闻的相关看法)。
Stack Overflow(国外程序异常讨论社区,这个各位猿应该很熟悉吧)。全文检索,搜索相关问题和答案。
Github。搜索代码。
电商网站。检索商品。
日志数据分析,logstash采集日志,es进行复杂的数据分析。
商品价格监控网站。用户设定某商品的价格阈值,当低于该阈值时,发消息通知用户。
BI系统。类似大型商场集团,分析某某区域最近三年的用户消费金额趋势以及用户群体的构成,产出相关的数据报表。es执行数据分析与挖掘,kibana进行数据可视化。
Elasticsearch的核心概念
通过上面的描述,已经大概知道es是什么、并且它能做什么。但是关于es,我们需要掌握的概念,还有一些:
集群、节点、索引、类型、文档、分片、映射
一脸懵逼?别慌,其实很简单,和关系型数据库一对比来看,就明白了。
| 关系型数据库 | Elasticsearch |
|---|---|
| 数据库(databases) | 索引(indices) |
| 表(tables) | 类型(types) |
| 行(rows) | 文档(documents) |
| 字段(columns) | field |
es(集群)中可以包含多个索引(数据库),每个索引中可以包含多个类型(表),每个类型下又可以包含多个文档(行),每个文档中又包含多个字段(field)。
物理设计
es在后台把每个索引划分成多个分片,每个分片可以在集群中的不同服务器间迁移。
逻辑设计
一个索引类型中,包含多个文档,比如说文档1,文档2。当我们搜索一篇文档时,可以通过这样一个顺序找到它:索引 => 类型 => 文档ID,通过这个组合我们就能索引到某个具体的文档。
文档
es是面向文档的,意味着索引和搜索数据的最小单位是文档,es中,文档有几个重要属性:
自我包含。一篇文档同时包含字段和对应的值,也就是同时包含 key:value。
可以使层次型的。就像Json。
灵活的结构。文档不依赖预先定义的模式,我们知道关系型数据中,要提前定义字段才能使用,在es中,对于字段是非常灵活的,有时候,我们甚至可以忽略字段,或者动态添加一个新的字段。
尽管我们可以随意的新增和忽略某个字段,但是每个字段的类型非常重要,比如一个年龄字段的类型,可以是字符串,也可以是整型。因为es会保存字段和类型之间的映射以及其它设置。这种映射具体到每个映射的每种类型,这也是为什么在es中,类型有时候也称为映射类型。
类型
类型是文档的容器,就像关系型数据库一样,表格是行的容器。类型中对于字段的定义称为映射,比如name映射为字符串类型。我们说文档是无模式的,它们不需要拥有映射中所定义的所有字段。
比如新增一个字段,es是怎么做的呢?它会自动将新字段加入映射,但是不确定这个字段是什么类型,es就会开始猜,如果这个值是18,那么es会认为它是整型。但是es也可能猜的不对,所以最安全的方式就是提前定义好所需要的映射,这点和关系型数据库就殊途同归了。
索引
索引是映射类型的容器,es中的索引是一个非常大的文档集合。索引存储了映射类型的字段和其他设置,然后它们被存储到了各个分片上。
节点和分片是如何工作的?
一个集群至少有一个节点,而一个节点就是一个es进程,节点可以有多个索引,如果你创建索引,那么索引默认将会有5个分片(primary shard,又称为主分片)构成。每一个主分片会有一个副本(replica shard,又称为复制分片)。
在集群中,主分片和对应的复制分片都不会在同一个节点内,这样有利于某个节点挂了,数据也不会丢失。实际上,一个分片就是一个Lucene索引,一个包含倒排索引的文件目录,倒排索引的结构使得es在不扫描全部文档的情况下,就能告诉你哪些文档包含特定的关键字。
可能很多小伙伴还不知道倒排索引是什么,这里解释一下:
es使用的是倒排索引的结构,采用Lucene倒排索引作为底层。这种结构适用于快速的全文搜索,一个索引由文档中所有不重复的列表构成,对于每一个词,都有一个包含它的文档列表。例如,现在有两个文档,每个文档包含如下内容:
Write once, bug anywhere, good job // 文档1包含的内容
good good study, day day up // 文档2包含的内容为了创建倒排索引,我们首先要将每个文档拆分成独立的词(或称为词条或者tokens),然后创建一个包含所有不重复的词条的排序列表,然后列出每个词条出现在哪个文档:
term 文档1 文档2 Write 有 无 once 有 无 bug 有 无 anywhere 有 无 job 有 无 good 有 有 study 无 有 day 无 有 day 无 有 up 无 有 假如现在我试图去搜索bug anywhere,只需要查看包含每个词条的文档
trem 文档1 文档2 good 有 有 job 有 无 total 2 1 搜索出来的结果,文档1的权重比较高,文档2的权重比较低,也可以理解为匹配度。
如果没有别的条件,这两个包含关键字的文档都将返回。
Elasticsearch与Solr对比
提到es,就不得不提Solr,这哥俩经常被摆到牌面上作比较,我可以通过简单的对比,看一下es是如何在搜索引擎的市场占有率上逐步超越Solr的。
Solr简介
Solr是Apache下的一个顶级开源项目,也是采用Java开发,也是基于Lucene的全文搜索服务器。
Solr提供了比Lucene更为丰富的查询语言,同时实现了可配置、可拓展,并对索引、搜索性能进行了优化。
Solr可以读了运行,运行在Jetty、Tomcat等这些Servlet容器中,Solr索引的实现方式很简单,用POST方法想Solr服务器发送一个描述Field及内容的XML文档,Solr根据XML文档添加、删除、更新索引。Solr搜索只需要发送HTTP GET请求,然后对Solr返回的XML、JSON等格式的查询结果进行解析,组织页面布局。Solr不提供构建UI的功能,Solr提供了一个管理界面,通过管理界面可以查询Solr的配置和运行情况。
Solr是一个独立的企业级搜索应用服务器,他对外提供类似于Web-service的API接口。
既然es和Solr都是以Lucene作为其核心,那么在这两者比较之前,我们还是得对Lucene有一个基本的认识。
Lucene简介
Lucene是apache软件基金会4 jakarta项目组的一个子项目,是一个开放源代码的全文检索引擎工具包,但它不是一个完整的全文检索引擎,而是一个全文检索引擎的架构,提供了完整的查询引擎和索引引擎,部分文本分析引擎(英文与德文两种西方语言)。
Lucene的目的是为软件开发人员提供一个简单易用的工具包,以方便的在目标系统中实现全文检索的功能,或者是以此为基础建立起完整的全文检索引擎。Lucene是一套用于全文检索和搜寻的开源程序库,提供了一个简单却强大的应用程序接口,能够做全文索引和搜寻。在Java开发环境里Lucene是一个成熟的免费开源工具。就其本身而言,Lucene是当前以及最近几年最受欢迎的免费Java信息检索程序库。
Lucene是一个全文检索引擎架构,那么什么是全文检索引擎?
国外具有代表性的有Google、Fast/AllTheWeb、AltaVista等,国内著名的有百度。
他们都是通过从互联网上提取各个网站的信息(以网页文字为主)而建立的数据库,检索与用户查询条件匹配的相关记录,然后按一定的顺序将结果返回给用户,因此他们是真正的搜索引擎。
从搜索结果来源的角度,全文搜索引擎又可细分为两种
一种是拥有自己的检索程序(Indexer),俗称”蜘蛛(Spider)“程序或”机器人(Robot)“程序,并自建网页数据库,搜索结果直接从自身的数据库中取出,如上面提到的几家引擎。
另一种是租用其他搜索引擎的数据库,并按自定的格式排列搜索结果,如Lycos引擎。
对比
上面介绍完了es和Solr,还有Lucene,相信大家对搜索引擎这个概念,应该有一定的认识了,当我们聊到搜索的时候,最关注的关键点是什么?第一个肯定是准确性,如果查出来的东西都不准确,那肯定不能称之为合格的搜索引擎;还有一个是性能,如何在海量的数据中更快地查出数据,这肯定也是企业非常关心的。下面我们就性能方面,来对es和Solr进行一个比较。
1.当单纯的对已有数据进行搜索时,Solr更快。

2.当实时建立索引时,Solr会产生io阻塞,查询性能较差,es具有明显的优势。

3.随着数据量增加,Solr的搜索效率会变得更低,而es则没有明显的变化。

4.在你的应用中使用Solr,如果转变为使用es作为搜索基础设施后,性能提高50倍。

总结
es基本是开箱即用,而Solr安装会稍微复杂一些。
Solr利用Zookeeper进行分布式管理,而es则天生支持分布式。
Solr支持更多格式的数据,如JSON、XML、CSV,而es仅支持JSON。
Solr官方提供的功能更多,而es本身更注重与核心功能,高级功能多由第三方插件提供,例如图形化界面就需要Kibana支持。
Solr查询快,但更新索引慢(即插入删除慢),用于电商等查询多的应用。
es建立索引快(即相对于Solr来说查询慢),即实时性查询快,用于Facebook、新浪等搜索。
Solr是传统搜索应用的有力解决方案,但es更适用于新兴的实时搜索应用。
Solr比较成熟,有一个更大、更成熟的开发和贡献者社区,而es相对开发维护者较少,更新太快,学习成本较高。
ELK
在我们正式开始实操之前,还有一个概念性的东西想和大家聊一下,就是目前最火的ELK。
ELK是三大开源框架Elasticsearch、Logstash、Kibana的缩写。
市面上也称之为Elastic Stack。前面已经介绍了Elasticsearch,那么什么是Logstash呢?
Logstash是ELK的中央数据流引擎,用于从不同目标(文件/数据存储/MQ)收集不同格式的数据,经过过滤后支持输出到不同目的地(文件/MQ/Redis/Elasticsearch/Kafka等)。
而Kibana则可以将Elasticsearch的数据通过友好的页面展示出来,提供实时分析的功能。
很多程序员只要提到ELK就是说它是一个日志分析架构技术的总称,但实际上ELK不仅仅适用于日志分析,它还可以支持其他任何数据分析和收集的场景,日志分析和收集只是更具有代表性而已。
Elasticsearch安装
好了,现在我们就开始进入正题啦!
注意:es由于是基于Java开发的,所以es对Java版本是有要求的。就目前来说,如果你想本地安装es,那么JDK1.8是最低要求。
es的安装非常简单,之前我有一篇讲es和Spring Boot集成的博客中有讲过es的安装,但当时安装的是6.x版本的,这里我们装7.6.x版本其实也没什么不同,不过我还是把步骤写出来。
下载
官网下载地址:https://www.elastic.co/cn/downloads/past-releases#elasticsearch

选择相应的版本,这里我们选7.6.2

根据你的系统选择相应的es安装包。
下载完成后,解压

解压完成后,可以看到上图的目录结构:
bin:启动文件目录。
config:配置文件目录,我们进到这个目录里面看看:
elasticsearch.yml:es的配置文件(这里面可以配置一些集群信息,日志输出的路径,端口等)。
jvm.options:JVM的配置文件(打开这个配置文件会发现,当你启动es时,默认就会使用1G的内存,家境贫困的小伙伴请慎重!必要时可以自己修改)。
log4j2.properties:日志配置文件。
还有一些角色配置文件。
jdk:环境。
lib:相关的jar包目录(这里打开会看到许多Lucene的相关jar包)。
logs:日志目录。
modules:功能模块目录。
plugins:插件目录(重要)。
启动
在bin目录下
sh elasticsearch发现报错
./elasticsearch-env: line 116: syntax error near unexpected token `<'这是由于bash 3.0后,shell中加入了新的符号"<<<" 可以获取子任务,把 elasticsearch-env 文件中第116行代码中的
< <(env)改为<<< `env`再启动

在浏览器输入
http://localhost:9200/

则说明我们的安装已经成功。
安装可视化界面
Elasticsearch-Head
目前es的可视化界面有许多插件可以供我们选择,但是使用过的比较多的一般是Head和Kibana。
官网:https://github.com/mobz/elasticsearch-head/
可以看到这是一个前端项目,所以这里需要安装Nodejs和npm环境。
还有一种方式是我们可以安装Chrome插件,下载地址:
https://www.gugeapps.net/webstore/detail/elasticsearch-head/ffmkiejjmecolpfloofpjologoblkegm
下载完成后,直接拖拽至拓展程序即可:

这时你打开插件,输入你本地的es地址点击连接

如果你的绿色背景文字部分显示的和我一样那么你就是已经连接了,我们可以点击右上角的信息,则就会显示es的基本信息。
如果你显示的是”集群健康值:未连接“则说明你可能存在跨域问题。
解决跨域问题也很简单,只需要在es的配置文件elasticsearch.yml文件中添加以下配置即可:
http.cors.enabled: true
http.cors.allow-origin: "*"
然后重启一下es服务即可。
使用Chrome插件不会存在跨域问题,如果你的Elasticsearch-head是在本地安装的,则会出现跨域问题。
这样我们的Head插件就安装完成了,我们可以把它当做一个数据库查看工具,以后可以在这里查询数据。
但是如果对数据进行操作,我们还是需要安装Kibana。
Kibana
Kibana是一个针对es的开源分析及可视化平台,用来搜索、查看存储在Elasticsearch索引中的数据。
Kibana可以通过各种图表进行高级数据分析及展示。Kibana让海量数据更容易理解。
它操作简单,基于浏览器的用户界面可以快速创建仪表盘(dashboard)实时显示es查询动态。设置Kibana非常简单,无需编码或者额外的基础架构,几分钟内就可以完成Kibana安装并启动es索引检测。
官网:https://www.elastic.co/cn/kibana
下载
这里的注意事项是:Kibana的版本,要和你使用的es版本一致,否则可能会出现奇奇怪怪的问题。
所以这里我们的Kibana也下载7.6.2的版本。
https://www.elastic.co/cn/downloads/past-releases/kibana-7-6-2
注意:要有Nodejs环境
安装
下载完成后,解压。
解压完成后,进入解压目录启动
nohup bin/kibana &如果你想停止Kibana,则需要用 lsof -i:5601 查出Kibana的进程id,通过 kill -9 pid 命令停止进程。Win系统和Linux系统同理。
然后在浏览器输入:http://localhost:5601/

即可看到Kibana的图形界面了。
以后我们用到最多的,就是我们的开发工具

同时Kibana也支持汉化,只需要修改Kibana的配置文件即可。
在安装目录的config文件夹下有个Kibana.yml文件,只需在文件的末尾加上
i18n.locale: "zh-CN"然后我们来重启一下Kibana

汉化已经生效了。
总结
这一篇我们先对es有一个基本的认识,也熟悉了es的环境搭建。具体的使用,想放到下一篇来写,因为我发现博客的篇幅太长,很容易就劝退观看的小伙伴...这么贴心的博主不多了!你还不关注一下!



Hi
感谢你的到来
我不想错过你
编程那些烦心事







