Elastic Stack之搜索引擎基础
作者:尹正杰
版权声明:原创作品,谢绝转载!否则将追究法律责任。
一.搜索引擎概述
1>.什么是搜索引擎
搜索引擎(Search Engine)是指根据一定的策略、运用特定的计算机程序从互联网上搜集信息,在对信息进行组织和处理后,为用户提供检索服务,将用户检索相关的信息展示给用户的系统。搜索引擎包括全文索引、目录索引、元搜索引擎、垂直搜索引擎、集合式搜索引擎、门户搜索引擎与免费链接列表等。目前在全球比较出名的2款搜索引擎莫过于Google和baidu啦!同时,我们站点内部也需要搜索引擎,最常见的比如日志分析系统。搜索引擎是我们常见而且通用的需求。
简单的说,搜索引擎是由索引组件和搜索组件两部分组成。
索引组件是面向数据存储和索引构建,搜索组件是面向用户提供搜索功能以及将用户提供的搜索请求转换成可用的查询语句并通过索引完成查询过程(或搜索过程)。对于搜索引擎来讲,有一个著名的索引类型叫做倒排索引。倒排索引的作用主要是通过关键词去查对应文档的。不像我们有一个表去找某一行数据。
在索引组件比较出名就是Lucene,对于搜索组件比较出名的就是ElasticSearch,Solr,Nutch,(后两者更偏向于数据获取组件,尤其是Nutch,一开始只是网络爬虫)。
2>.优秀的开源搜索引擎
在开源领域中,优秀的搜索引擎代表就是Lucene和Sphinx。
Lucene: Lucene是apache软件基金会4 jakarta项目组的一个子项目,是一个开放源代码的全文检索引擎工具包,但它不是一个完整的全文检索引擎,而是一个全文检索引擎的架构,提供了完整的查询引擎和索引引擎,部分文本分析引擎(英文与德文两种西方语言)。Lucene的目的是为软件开发人员提供一个简单易用的工具包,以方便的在目标系统中实现全文检索的功能,或者是以此为基础建立起完整的全文检索引擎。 Lucene是一套用于全文检索和搜寻的开源程式库,由Apache软件基金会支持和提供。Lucene提供了一个简单却强大的应用程式接口,能够做全文索引和搜寻。在Java开发环境里Lucene是一个成熟的免费开源工具。就其本身而言,Lucene是当前以及最近几年最受欢迎的免费Java信息检索程序库。人们经常提到信息检索程序库,虽然与搜索引擎有关,但不应该将信息检索程序库与搜索引擎相混淆。 Sphinx: Sphinx是一个基于SQL的全文检索引擎,可以结合MySQL,PostgreSQL做全文搜索,它可以提供比数据库本身更专业的搜索功能,使得应用程序更容易实现专业化的全文检索。Sphinx特别为一些脚本语言设计搜索API接口,如PHP,Python,Perl,Ruby等,同时为MySQL也设计了一个存储引擎插件。Sphinx 单一索引最大可包含1亿条记录,在1千万条记录情况下的查询速度为0.x秒(毫秒级)。Sphinx创建索引的速度为:创建100万条记录的索引只需 3~4分钟,创建1000万条记录的索引可以在50分钟内完成,而只包含最新10万条记录的增量索引,重建一次只需几十秒。 Sphinx的主要特性包括:高速索引 (在新款CPU上,近10 MB/秒); 高速搜索 (2-4G的文本量中平均查询速度不到0.1秒); 高可用性 (单CPU上最大可支持100 GB的文本,100M文档); 提供良好的相关性排名 支持分布式搜索; 提供文档摘要生成; 提供从MySQL内部的插件式存储引擎上搜索 支持布尔,短语, 和近义词查询; 支持每个文档多个全文检索域(默认最大32个); 支持每个文档多属性; 支持断词; 支持单字节编码与UTF-8编码。
3>.Solr
Lucene自己只是一个库,不能单独拿来使用,若要使用它需要对它进行二次开发。若你想使用一套完整的搜索引擎解决方案可以考虑使用Solr。Solr是为非开发人员提供的一套解决方案!
Solr是一个独立的企业级搜索应用服务器,它对外提供类似于Web-service的API接口。用户可以通过http请求,向搜索引擎服务器提交一定格式的XML文件,生成索引;也可以通过Http Get操作提出查找请求,并得到XML格式的返回结果。但是巧妇难为无米之炊啊!我们只有Solr是无法帮用户搜索数据的,要想搜索那就得有数据,也就是说你得为Solr提供数据信息以供搜索。
二.Lucene相关概念
1>.什么是Lucene
Apache开元项目Lucene,Lucene只是一个索引链,它没有提供任何前端的可用界面。如下图所示,它可以帮我们把获取到的原始内容构建成文档,还能做文档分析,而且还能创建出索引来。换句话说,它自身不获取文档且不提供搜索界面。所以我们可以所Lucene只是一个开发库。因此我们可以利用Lucene来进行二次开发,我们只需要把前端页面写出来,让用户键入需要搜索的关键字,底层通过Lucene实现文档搜索,将搜索的结果在通过我们自己开发的web界面返回给前端用户,而搜索组件需要构建查询,进行切词以便对用户键入的关键字进行分析并运行查询,最终搜索引擎将查询结果返回给用户,这个功能已经有开源组件帮我们实现了,他就是著名的ElasticSearch工具。
Lucene提供了类似传统关系型数据库的存储和查询能力,但是Lucene没有确定的全局模式。换句话说,luncene不像SQL数据库中的表一样,需要定义好表才能存储数据,它的内部文档存储无需提前定义好任何结构(我们称之为没有全局模式的)。
2>.Lucene的基本概念
一.文档(Document):
文档是索引和搜索的最原子单位,它包含了一个或者多个域的容器。一个文档可以包含一个键值对,也可以包含N个键值对,而真正搜索时是搜索的value。
二.域(field):
文档中包含了大量的键值对,那个键我们称之为域,沿用了SQL中的叫法,也可以称之为字段。创建域的时候,我们可以为域指定多个选项(索引选项,存储选项,项向量使用选项)来控制Lucene将文档添加进域索引后对改域可以执行哪些操作,这个过程我们通常称为域的分析过程。
索引选项用于通过倒排索引来控制文本是否被搜索:
Index.ANYLYZED:分析(切词)并单独作为索引项(表示要使用分析器将域中的值分解成各个独立的分词,并且使得各个分词都能够被搜索)。
Index.Not_ANYLYZED:和ANYYZED相反,表示不分析(不切词),把整个内容当做一个索引项。
Index.ANYLYZED_NORMS:类似于Index.ANYLYZED,但不存储token和Norm(加权基准)信息。
Index.Not_ANYLYZED_NORMS:类似于Index.Not_ANYLYZED,但不存储值Norm(加权基准)信息。
存储选项,是否存储域的真实值:
store.YES:存储真实值。
store.NO:不存储真实值。
域向量使用选项:
域向量选项用于在搜索期间该文档所有的唯一项都能完全从文档中检索时使用。
三.文档和域的加权操作
需要定义加权计算标准。
3>.Lucene如何执行搜索
查询Lucene索引时,它返回的是一个有序的scoreDoc对象,查询时,Luncen会为每个文档计算出其score,而后根据score进行排序。Lucene想要完成查询功能,它对外提供了大量的API,接下来我们简单的了解一下:
IndexSearcher:搜索索引入口。
Query及其子类。
QueryParser :查询分析器。
TopDocs:保存某一次查询操作当中,分值较高的前10个scoreDoc对象。
scoreDoc:指的是搜索结果。
4>.Lucene的多样化查询
我们知道Lucene的查询操作最终都是通过调用IndexSearcher来完成搜索的。而IndexSearcher中有一个叫search方法完成搜索。同时完成搜索时还要传入Query实例作为参数来进行。 TermQuery: 对索引中的特定域进行搜索。Term是索引中的最小索引片段,每个Term包含了一个域名和一个文本值。 TermRangeQuery: 可以指明域方位可以在索引中的特定域中进行搜索,能搜索指定的多个域名。 NumericRangeQuery: 做数值范围搜索。 PrefixQuery: 用来搜索以指定字符串开头的项。 BooleanQuery: 用来实现组合搜索。组合逻辑有:AND,OR,NOT。 PhraseQuery: 根据位置信息来定位对应文档的。 WildcardQuery: 可以结合?或者*来完成通配查询。 FuzzyQuery: 模糊查询,Lenvenshtein。
三.ElasticSearch基本概念
1>.什么是ElasticSearch
ElasticSearch就是基于Lucene的API封装成了一个搜索组件。但是除了搜索功能以外,ElasticSearch还提供了一些更强大的功能。ElasticSearch在Lucene所提供的API基础之上又额外新增了把自己构建为分布式。换句话说,ElasticSearch能够分布式的将Lucene所提供的索引组建成Shards的形式,分片分布于多个节点上,从而构建成分布式实时查询组件。
上面我们用自己的话说了一下ES的概念,接下来我们用比较官方的话在来说一下ES的概念。ES是一个基于Lucene实现的开源,分布式,Restful的全文搜索引擎;此外,它还是一个分布式实时文档存储,其中每个文档的每个field均是被索引的数据,且可被搜索,也是一个带实时分析功能的分布式搜索引擎,能够扩展至数以百计的节点实时处理PB级别的数据。
2>.ES的基本组件
索引(index):
文档容器,换句话说,索引是具有类似属性的文档的集合(索引就是一个拥有几分相似特征的文档的集合。)。类似于关系型数据库中的表。索引名必须使用小写字母。一个ES可以创建任意个索引。
类型(type):
类型是索引内部的逻辑分区,其意义完全取决于用户需求,一个索引内部可定义一个或多个类型。一般来说,类型就是拥有相同域的文档的预定义。
文档(Document):
文档是Lucene索引和搜索的原子单位(一个文档是可以被索引的基础信息单元。),它包含了一个或多个域(每个域的组成部分:一个名字,一个或多个值,拥有多个值的域,通常称为多值域),是域的容器,基于JSON格式表示。
映射(mapping):
原始内容存储为文档之前需要事先进行分析,例如:切词,过滤掉某些词等;映射用于定义此分析机制该如何实现。除此之外,ES还为映射提供了诸如将域中的内容排序等功能。
3>.ES集群组件
Cluster: ES的集群标识为集群名称,早期版本(ES1.x版本)默认是“elasticsearch”,本篇博客安装的是ES6.5,默认的名称为"my-application"。节点就是靠此名字来决定加入到哪个集群中。一个节点只能属于一个集群。 Node: 运行了单个ES实例的主机即节点。用于存储数据,参与集群索引即搜索操作。节点的标识靠节点名。 Shard: 将索引切割成为物理存储组件,但每一个shard都是一个独立且完整的索引,创建索引时,ES默认将其分割为5个shard。当然,用户也可以按需自定义。创建完成之后不可修改。shard有两种类型,即primary shard(主)和replica shard(从) primary shard(主): primary shard用于文档存储,每个新的索引都会自动创建出5个主shard(默认),每个primary shard都应该有一个副本(replica shard)。另外,到底有几个副本,用户是可以自定义的,可以支持动态改变。 replica shard(从): replica shard是primary shard的副本,用于冗余数据及查询时的负载均衡。
4>.ES Cluster工作过程
启动是,通过多播(默认)或单播方式在9300/tcp查找同一集群中的其他节点(依靠我们定义的集群名称),并与之建立通信。
集群中的所有节点会选举出一个主节点负责管理整个集群状态,以及在集群范围内决定各shards的分布式,站在用户角度而言,每个均可接受相应用户的各类需求。
集群有三种状态:green,red,yellow。
yellow状态:
集群处于修复状态,一旦启动修复过程,主节点可以检查所有可用shard,并确定primary shard(如果没有发现可用的primary shard,就会把replica shard提升为primary shard,此时replica shard的数量会减少一个,副本不够时会自动添加)。所以我们会说,在yellow状态时,各replica shard均处于未分配模式(也就是说,此时由primary shard负责写入和读取,并没有读写分离,吞吐能力相对较低!)。primary shard将会查找所有的replica shard并将其配置为副本。当primary shard发现找到可用replica shard少于用于定义的副本数量时,它会自动找一个节点并启动复制过程直到满足用于定义的副本数量。
red状态:
集群处于不可用状态
green状态:
集群处于正常状态。
5>.ElasticSearch官网 (https://www.elastic.co/)
Elastic官方products连接地址:https://www.elastic.co/cn/products。
四.Elastic Stack基本概念
1>.Logstash
我们知道 ElasticSearch只能完成数据的搜索和存储功能,而它无法直接收取数据,因此ElasticSearch一开始收购Logstash这块产品用来做日志收集。Logstash是一个开源数据收集引擎,具有实时管道功能。Logstash可以动态地将来自不同数据源的数据统一起来,并将数据标准化到你所选择的目的地。
Logstash是使用jruby进行开发的。它在使用的时候会很吃内存!为了分析日志它可能会用到几个G的大小,是一个非常重量级的产品。因此,各个公司开始纷纷自己研发日志收集工具。因为它太笨重了。如果公司的开发人力有限的话一开始就只能使用ELK工具来完成日志收集分析操作。
2>.beats
刚刚我们提到了Logstash是很吃内存的,是一个重量级的,因此很多有能力的公司都在开始研发自己的日志收集工具而摒弃Logstash。如Scribe是facebook开源的日志收集系统等等,而Elastic 公司也不甘示弱,使用了C++和go语言研发了beats工具(其安装大小很小!功能也相对齐全),比如收集日志的可以使用filebeat,收集网络日志可以用packagebeat,从Windows事件日志收集的可以用eventbeat等等。
3>.kibana
Kibana是一个开源的分析和可视化平台,设计用于和Elasticsearch一起工作。你用Kibana来搜索,查看,并和存储在Elasticsearch索引中的数据进行交互。你可以轻松地执行高级数据分析,并且以各种图标、表格和地图的形式可视化数据。Kibana使得理解大量数据变得很容易。它简单的、基于浏览器的界面使你能够快速创建和共享动态仪表板,实时显示Elasticsearch查询的变化。
4>.Elastic Stack功能划分
Elasticsearch:
是一个搜索引擎和数据存储。它能够将客户端发来的数据进行切词,分析,存储并支持检索。
logstash:
它是一个数据抽取(Extracl),转换(Transform)和装入(Load)的工具,简称ELT工具。和我们大数据生态圈的Sqoop角色有着类似的功能。虽然说logstash在日志收集方面被大家挤兑,但是不能否定它还有其他的优点。
Kibana:
利用ElasticSearch的API,它可以实现实时的数据查询展示等功能。
虽说官方建议将logstash更换为filebeat工具来实现ETL操作,因此我们可以将ELK,换名称之为EFK,事实上我们应该成为ELFK,而官方给他们起了一个名称叫做Elastic Stack(翻译为:Elastic 工具链)。