elasticsearch入门知识整理

Elasticsearch是一个基于Apache Lucene(TM)的开源搜索引擎。

但是,Lucene只是一个库。Lucene本身并不提供高可用性及分布式部署。想要发挥其强大的作用,你需使用Java并要将其集成到你的应用中。L

Elasticsearch也是使用Java编写并使用Lucene来建立索引并实现搜索功能,但是它的目的是通过简单连贯的RESTful API让全文搜索变得简单并隐藏Lucene的复杂性。

Elasticsearch不仅仅是Lucene和全文搜索引擎,它还提供:

  • 分布式的实时文件存储,每个字段都被索引并可被搜索
  • 实时分析的分布式搜索引擎
  • 可以扩展到上百台服务器,处理PB级结构化或非结构化数据

Elasticsearch 是一个搜索和分析引擎。Logstash 是服务器端数据处理管道,能够同时从多个来源采集数据,转换数据,然后将数据发送到诸如 Elasticsearch 等“存储库”中。Kibana 则可以让用户在 Elasticsearch 中使用图形和图表对数据进行可视化。

一、基础概念-快速入门

节点 Node、集群 Cluster 和分片 Shards

ElasticSearch 是分布式数据库,允许多台服务器协同工作,每台服务器可以运行多个实例。单个实例称为一个节点(node),一组节点构成一个集群(cluster)。分片是底层的工作单元,文档保存在分片内,分片又被分配到集群内的各个节点里,每个分片仅保存全部数据的一部分。

Cluster也就是集群的意思。Elasticsearch集群由一个或多个节点组成,可通过其集群名称进行标识。 在config/elasticsearch.yml里定制我们的集群的名字 。

一个集群由一个或多个node组成 。

根据node的作用,可以分为如下的几种:

master-eligible:可以作为主node。一旦成为主node,它可以管理整个cluster的设置及变化:创建,更新,删除index;添加或删除node;为node分配shard

data:数据node

ingest: 数据接入(比如 pipepline)

machine learning (Gold/Platinum License)

Shard: Elasticsearch提供了将索引划分成多份的能力,这些份就叫做分片(shard)。当你创建一个索引的时候,你可以指定你想要的分片(shard)的数量。每个分片本身也是一个功能完善并且独立的“索引”,这个“索引”可以被放置到集群中的任何节点上 ,

两种类型的分片:primary shard和replica shard。 主副本和副本分片之间的主要区别在于只有主分片可以接受索引请求。副本和主分片都可以提供查询请求。

Primary shard: 每个文档都存储在一个Primary shard。 索引文档时,它首先在Primary shard上编制索引,然后在此分片的所有副本上(replica)编制索引。索引可以包含一个或多个主分片。 此数字确定索引相对于索引数据大小的可伸缩性。 创建索引后,无法更改索引中的主分片数。
Replica shard: 每个主分片可以具有零个或多个副本。 副本是主分片的副本,有两个目的:

增加故障转移:如果主要故障,可以将副本分片提升为主分片

提高性能:get和search请求可以由主shard或副本shard处理。

#为每个index设置相应的shard数值
curl -XPUT http://localhost:9200/another_user?pretty -H 'Content-Type: application/json' -d '
{
    "settings" : {
        "index.number_of_shards" : 2,
        "index.number_of_replicas" : 1
    }
}'

索引 Index、类型 Type 和文档 Document

对比我们比较熟悉的 MySQL 数据库:

index → db
type → table
document → row

如果我们要访问一个文档元数据应该包括囊括 index/type/id 这三种类型

index 是单个数据库的同义词。每个 Index (即数据库)的名字必须是小写。 Elastic 会索引所有字段,经过处理后写入一个反向索引(Inverted Index)。查找数据的时候,直接查找该索引。 索引是文档的集合, 每个Index一个或许多的documents组成,并且这些document可以分布于不同的shard之中。 在Elasticsearch中的文档可以有object及nested结构。一个index是一个逻辑命名空间,它映射到一个或多个主分片,并且可以具有零个或多个副本分片。

$ curl -X GET 'http://localhost:9200/_cat/indices?v'

type: 类型是文档的逻辑容器,类似于表是行的容器。 您将具有不同结构(模式)的文档放在不同类型中。在Elasticsearch 6.0以后,一个Index只能含有一个type。这其中的原因是:相同index的不同映射type中具有相同名称的字段是相同; 在Elasticsearch索引中,不同映射type中具有相同名称的字段在Lucene中被同一个字段支持。在默认的情况下是_doc。在未来8.0的版本中,type将被彻底删除。

Document : Index 里面单条的记录, 多条 Document 构成了一个 Index , Document 使用 JSON 格式表示 。Elasticsearch是面向文档的,这意味着您索引或搜索的最小数据单元是文档。文档在Elasticsearch中有一些重要的属性:

它是独立的。文档包含字段(名称)及其值。
它可以是分层的。可以将其视为文档中的文档。字段的值可以很简单,就像位置字段的值可以是字符串一样。它还可以包含其他字段和值。例如,位置字段可能包含城市和街道地址。
结构灵活。您的文档不依赖于预定义的架构。例如,并非所有事件都需要描述值,因此可以完全省略该字段。但它可能需要新的字段,例如位置的纬度和经度。

文档通常是数据的JSON表示形式
Type,它是虚拟的逻辑分组,用来过滤 Document 。

$ curl 'localhost:9200/_mapping?pretty=true'   #列出每个 Index 所包含的 Type

二、使用 RESTful API 与 Elasticsearch 进行交互

可以使用 RESTful API 通过端口 9200 和 Elasticsearch 进行通信

curl -X <VERB> '<PROTOCOL>://<HOST>:<PORT>/<PATH>?<QUERY_STRING>' -d '<BODY>'

部件名作用VERB适当的 HTTP 方法 或 谓词 : GETPOSTPUTHEAD 或者 DELETEPROTOCOL http 或者 https(如果你在 Elasticsearch 前面有一个 https 代理)HOSTElasticsearch 集群中任意节点的主机名,或者用 localhost 代表本地机器上的节点。PORT运行 Elasticsearch HTTP 服务的端口号,默认是 9200PATHAPI 的终端路径(例如 _count 将返回集群中文档数量)。Path 可能包含多个组件,例如:_cluster/stats_nodes/stats/jvmQUERY_STRING任意可选的查询字符串参数 (例如 ?pretty 将格式化地输出 JSON 返回值,使其更容易阅读)BODY一个 JSON 格式的请求体 (如果请求需要的话)

Elastic 默认一次返回10条结果,可以通过size字段改变这个设置。

#新建 Index
$ curl -X PUT 'localhost:9200/weather'                  
#删除Index
$ curl -X DELETE 'localhost:9200/weather'               
#新增数据 
$ curl -X PUT 'localhost:9200/accounts/person/1' -d '
{
  "user": "张三",
  "title": "工程师",
  "desc": "数据库管理"
}' 
$ curl -X POST 'localhost:9200/accounts/person' -d '
{
  "user": "李四",
  "title": "工程师",
  "desc": "系统管理"
}'
#更新记录
$ curl -X PUT 'localhost:9200/accounts/person/1' -d '
{
    "user" : "张三",
    "title" : "工程师",
    "desc" : "数据库管理,软件开发"
}' 
#删除记录
$ curl -X DELETE 'localhost:9200/accounts/person/1'
#查询记录
$ curl -X GET 'localhost:9200//db/user/2'
#计算集群中文档的数量
curl -XGET 'http://localhost:9200/_count?pretty' -d '
{
    "query": {
        "match_all": {}
    }
}
'
#查询记录
$ curl 'localhost:9200/accounts/person/_search'  -d '
{
  "query" : { "match" : { "desc" : "软件" }}
}'

参考:
https://blog.csdn.net/UbuntuTouch/article/details/99443042
https://zhuanlan.zhihu.com/p/54384152
http://www.ruanyifeng.com/blog/2017/08/elasticsearch.html

批量处理 bulk

批量处理命令。在一次的REST请求中,可以完成很多的操作。 在输入命令时,我们需要特别的注意:千万不要添加除了换行以外的空格,否则会导致错误 。 一个好的起点是批量处理1000到5,000个文档,总有效负载在5MB到15MB之间

通过bulk API为数据编制索引时,您不应在集群上进行任何查询/搜索。 这样做可能会导致严重的性能问题

Open/close Index

lasticsearch支持索引的在线/离线模式。 使用脱机模式时,在群集上几乎没有任何开销地维护数据。 关闭索引后,将阻止读/写操作。 当您希望索引重新联机时,只需打开它即可。 但是,关闭索引会占用大量磁盘空间。 您可以通过将cluster.indices.close.enable的默认值从true更改为false来禁用关闭索引功能,以避免发生意外。

Freeze/unfreeze index

冻结索引(freeze index)在群集上几乎没有开销(除了将其元数据保留在内存中),并且是只读的。 只读索引被阻止进行写操作。冻结索引受到限制,以限制每个节点的内存消耗。 每个节点的并发加载的冻结索引数受search_throttled线程池中的线程数限制,默认情况下为1。 默认情况下,即使已明确命名冻结索引,也不会针对冻结索引执行搜索请求。 这是为了防止由于误将冻结的索引作为目标而导致的意外减速。 如果要包含冻结索引做搜索,必须使用查询参数ignore_throttled = false来执行搜索请求

两类搜索:

  • queries 进行全文搜索
  • aggregations 对数据进行统计及分析

搜索结果中 hits数组里,可以看到所有的结果。_score的项。它表示搜索结果的相关度。这个分数值越高,表明搜索匹配的相关度越高 。

index的mapping

Elasticsearch号称是schemaless,在实际所得应用中,每一个index都有一个相应的mapping。这个mapping在我们生产第一个文档时已经生产。它是对每个输入的字段进行自动的识别从而判断它们的数据类型。我们可以这么理解schemaless:

不需要事先定义一个相应的mapping才可以生产文档。字段类型是动态进行识别的。这和传统的数据库是不一样的
如果有动态加入新的字段,mapping也可以自动进行调整并识别新加入的字段

自动识别字段有一个问题,那就是有的字段可能识别并不精确,

注意:我们不能为已经建立好的index动态修改mapping。这是因为一旦修改,那么之前建立的索引就变成不能搜索的了。一种办法是reindex从而重新建立我们的索引。如果在之前的mapping加入的字段,那么我们可以不用重新建立索引

对于一个keyword类型的项来说,这个项里面的所有字符都被当做一个字符串。它们在建立文档时,不需要进行index。keyword字段用于精确搜索,aggregation和排序(sorting)

使用match query时,默认的操作是OR

bool请求通常是must,must_not, should及filter的一个或其中的几个一起组合形成的。should只有在特殊的情况下才会影响hits。在正常的情况下它不会影响搜索文档的个数。那么在哪些情况下会影响搜索的结果呢?这种情况就是针对只有should的搜索情况,也就是如果你在bool query里,不含有must, must_not及filter的情况下,一个或更多的should必须有一个匹配才会有结果

Elasticsearch有位置查询

match查询时时不用分先后顺序的

把 所感兴趣的数据导入到Elasticsearch , 可以通过:

Beats:我们可以通过beats把数据导入到Elasticsearch中
Logstash:我们可以Logstash把数据导入。Logstash的数据来源也可以是Beats
REST API:我们可以通过Elastic所提供的丰富的API来把数据导入到Elasticsearch中。我们可以通过Java, Python, Go, Nodejs等各种Elasticsearch API来完成我们的数据导入。

Elasticsearch可以实现秒级的搜索速度,其中很重要的一个原因就当一个文档被存储的时候,同时它也对文档的数据进行了索引(indexing)

Analyzer分为三个部分:Char Filters, Tokenizer及 Token Filter。它们的作用分别如下:

Char Filter: 字符过滤器的工作是执行清除任务,例如剥离HTML标记。
Tokenizer: 下一步是将文本拆分为称为标记的术语。 这是由tokenizer完成的。 可以基于任何规则(例如空格)来完成拆分。 有关tokennizer的更多详细信息,请访问以下URL:https://www.elastic.co/guide/en/elasticsearch/reference/current/analysis-tokenizers.html。
Token filter: 一旦创建了token,它们就会被传递给token filter,这些过滤器会对token进行规范化。 Token filter可以更改token,删除术语或向token添加术语。

在默认的情况下,standard analyzer是Elasticsearch的缺省分析器:

没有 Char Filter
使用standard tokonizer
把字符串变为小写,同时有选择地删除一些stop words等。默认的情况下stop words为_none_,也即不过滤任何stop words。


发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注