技术流ken

运维拯救世界

ELK系列:Elasticsearch分布式搜索引擎详解(一)–技术流ken

elasticsearch介绍

Elasticsearch 是一个实时的分布式搜索分析引擎, 它能让你以一个之前从未有过的速度和规模,去探索你的数据。 它被用作全文检索、结构化搜索、分析以及这三个功能的组合

Elasticsearch是一个基于Apache Lucene(TM)的开源搜索引擎。无论在开源还是专有领域,Lucene可以被认为是迄今为止最先进、性能最好的、功能最全的搜索引擎库。 但是,Lucene只是一个库。想要使用它,你必须使用Java来作为开发语言并将其直接集成到你的应用中,更糟糕的是,Lucene非常复杂,你需要深入了解检索的相关知识来理解它是如何工作的。 Elasticsearch也使用Java开发并使用Lucene作为其核心来实现所有索引和

搜索的功能,但是它的目的是通过简单的RESTful API来隐藏Lucene的复杂性,从而让全文搜索变得简单。

1 Elasticsearch的功能

(1)分布式搜索和分析引擎

(2)全文检索,结构化检索,数据分析

(3)对海量数据进行近实时的处理

分布式:ES自动可以将海量数据分散到多台服务器上存储和检索

海量数据的处理:分布式以后,就可以采用大量的服务器去存储和检索数据,自然而然就可以实现海量数据的处理了

跟分布式/海量数据相反的,lucene,单机应用,只能在单台服务器上使用,最多只能处理单台服务器可以处理的数据量。

近实时:在秒级别对数据进行搜索和分析

2 Elasticsearcg的适用场景

(1)维基百科,全文检索,高亮,搜索推荐

(2)新闻网站,用户日志+社交网络数据,分析

(3)Stack Overflow(国外的程序异常讨论论坛),全文检索,搜索相关问题和答案

(4)GitHub(开源代码管理),搜索上亿行代码

(5)电商网站,检索商品

(6)日志数据分析,logstash采集日志,ES进行复杂的数据分析

(7)商品价格监控网站,用户设定某商品的价格阈值,当低于该阈值的时候,发视消息给用户

(8)BI系统,ES执行数据分析和挖掘,Kibana进行数据可视化

(9)国内,站内搜索(电商,招聘,门户)

(10)BI 系统,商业智能,分析用户消费趋势和用户群体的组成构成。

3 Elasticsearch的特点

(1)可以作为一个大型分布式集群(数百台服务器)技术,处理PB级数据,服务大公司,也可以运行在单机上,服务小公司

(2)Elasticsearch不是什么新技术,主要是将全文检索,数据分析以及分布式技术,合并在一起,才形成了独一无二的ES,lucene(全文检索)

(3)对用户而言,是开箱即用的,非常简单,作为中小型的应用,直接3分钟部署一下ES,就可以作为生产环境的系统来使用了,数据量不大,操作不是太复杂

(4)数据库的功能面对很多领域是不够的,优势:事务,各种联机事务型的操作,特殊的功能,比如全文检索,同义词处理,相关度排名,复杂数据分析,海量数据的近实时处理,Elasticsearch作为传统数据库的一个补充,提供了数据库所不能提供的很多功能。

4 Elasticsearcg的核心概念

1.1 索引词

在elastiasearch中索引词(term)是一个能够被索引的精确值。foo,Foo,FOO几个单词是不同的索引词。索引词(term)是可以通过term查询进行准确的搜索。

1.2 文本(text)

文本是一段普通的非结构化文字。通常,文本会被分拆成一个个的索引词,存储在elasticsearch的索引库中。为了让文本能够进行搜索,文本字段需要事先进行分析了;当对文本中的关键词进行查询的时候,搜索引擎应该根据搜索条件搜索出原文本。

1.3 分析(analysis)

分析是将文本转换为索引词的过程,分析的结果依赖于分词器。比如:FOO BAR,Foo-Bar和foo bar这几个词有可能会被分析成相同的索引词foo和bar,这些索引词存储在Elasticsearch的索引库中。

1.4 集群(cluster)

集群由一个或多个节点组成,对外提供服务,对外提供索引和搜索功能。在所有节点,一个集群有一个唯一的名称默认为“elasticsearch”.此名称是很重要的,因为每个节点只能是集群的一部分,当该节点被设置为相同的集群名称时,就会自动加入集群。当需要有多个集群的时候,要确保每个集群的名称不能重复,,否则节点可能会加入到错误的集群。请注意,一个节点只能加入到一个集群。此外,你还可以拥有多个独立的集群,每个集群都有其不同的集群名称。

1.5 节点(node)

一个节点是一个逻辑上独立的服务,它是集群的一部分,可以存储数据,并参与集群的索引和搜索功能。就像集群一样,节点也有唯一的名字,在启动的时候分配。如果你不想要默认名称,你可以定义任何你想要的节点名.这个名字在理中很重要,在Elasticsearch集群通过节点名称进行管理和通信.一个节点可以被配置加入到一个特定的集群。默认情况下,每个节点会加人名为Elasticsearch 的集祥中,这意味着如果你在网热动多个节点,如果网络畅通,他们能彼此发现井自动加人名为Elasticsearch 的一个集群中,你可以拥有多个你想要的节点。当网络没有集祥运行的时候,只要启动一个节点,这个节点会默认生成一个新的集群,这个集群会有一个节点。

1.6 分片(shard)

分片是单个Lucene 实例,这是Elasticsearch管理的比较底层的功能。索引是指向主分片和副本分片的逻辑空间。 对于使用,只需要指定分片的数量,其他不需要做过多的事情。在开发使用的过程中,我们对应的对象都是索引,Elasticsearch 会自动管理集群中所有的分片,当发生故障的时候,Elasticsearch 会把分片移动到不同的节点或者添加新的节点。

一个索引可以存储很大的数据,这些空间可以超过一个节点的物理存储的限制。例如,十亿个文档占用磁盘空间为1TB。仅从单个节点搜索可能会很慢,还有一台物理机器也不一定能存储这么多的数据。为了解决这一问题,Elasticsearch将索引分解成多个分片。当你创建一个索引,你可以简单地定义你想要的分片数量。每个分片本身是一个全功能的、独立的单元,可以托管在集群中的任何节点。

1.7 主分片

每个文档都存储在一个分片中,当你存储一个文档的时候,系统会首先存储在主分片中,然后会复制到不同的副本中。默认情况下,一个索引有5个主分片。 你可以事先制定分片的数量,当分片一旦建立,则分片的数量不能修改。

1.8 副本分片

每一个分片有零个或多个副本。副本主要是主分片的复制,其中有两个目的:

– 增加高可用性:当主分片失败的时候,可以从副本分片中选择一个作为主分片。

– 提高性能:当查询的时候可以到主分片或者副本分片中进行查询。默认情況下,一个主分片配有一个副本,但副本的数量可以在后面动态地配置增加。副本分片必部署在不同的节点上,不能部署在和主分片相同的节点上。

 

分片主要有两个很重要的原因是:

– 允许水平分割扩展数据。

– 允许分配和井行操作(可能在多个节点上)从而提高性能和吞吐量。

这些很强大的功能对用户来说是透明的,你不需要做什么操作,系统会自动处理。

1.9 复制

复制是一个非常有用的功能,不然会有单点问题。 当网络中的某个节点出现问题的时

候,复制可以对故障进行转移,保证系统的高可用。因此,Elasticsearch 允许你创建一个或多个拷贝,你的索引分片就形成了所谓的副本或副本分片。

复制是重要的,主要的原因有:

– 它提供丁高可用性,当节点失败的时候不受影响。需要注意的是,一个复制的分片

不会存储在同一个节点中。

– 它允许你扩展搜索量,提高并发量,因为搜索可以在所有副本上并行执行。

每个索引可以拆分成多个分片。索引可以复制零个或者多个分片。一旦复制,每个索引就有了主分片和副本分片。分片的数量和副本的数量可以在创建索引时定义。 当创建索引后,你可以随时改变副本的数量,但你不能改变分片的数量。

默认情況下,每个索引分配5个分片和一个副本,这意味着你的集群节点至少要有两个节点,你将拥有5个主要的分片和5个副本分片共计10个分片.

每个Elasticsearch分片是一个Lucene 的索引。有文档存储数量限制,你可以在一个

单一的Lucene索引中存储的最大值为lucene-5843,极限是2147483519(=integer.max_value-128)个文档。你可以使用cat/shards API监控分片的大小。

1.10 索引

索引是具有相同结构的文档集合。例如,可以有一个客户信息的索引,包括一个产品目录的索引,一个订单数据的索引。 在系统上索引的名字全部小写,通过这个名字可以用来执行索引、搜索、更新和删除操作等。在单个集群中,可以定义多个你想要的索引。

1.11 类型

在索引中,可以定义一个或多个类型,类型是索引的逻辑分区。在一般情况下,一种类型被定义为具有一组公共字段的文档。例如,让我们假设你运行一个博客平台,并把所有的数据存储在一个索引中。在这个索引中,你可以定义一种类型为用户数据,一种类型为博客数据,另一种类型为评论数据。

1.12 文档

文档是存储在Elasticsearch中的一个JSON格式的字符串。它就像在关系数据库中表的

一行。每个存储在索引中的一个文档都有一个类型和一个ID,每个文档都是一个JSON对象,存储了零个或者多个字段,或者键值对。原始的JSON 文档假存储在一个叫作Sour的字段中。当搜索文档的时候默认返回的就是这个字段。

1.13 映射

映射像关系数据库中的表结构,每一个索引都有一个映射,它定义了索引中的每一个字段类型,以及一个索引范围内的设置。一个映射可以事先被定义,或者在第一次存储文档的时候自动识别。

1.14 字段

文档中包含零个或者多个字段,字段可以是一个简单的值(例如字符串、整数、日期),也可以是一个数组或对象的嵌套结构。字段类似于关系数据库中表的列。每个字段都对应一个字段类型,例如整数、字符串、对象等。字段还可以指定如何分析该字段的值。

1.15 主键

ID是一个文件的唯一标识,如果在存库的时候没有提供ID,系统会自动生成一个ID,文档的 index/type/id必须是唯一的。

 

 

5. Elasticsearch核心概念VS数据库核心概念

Elasticsearch 数据库

=========================

Document 行

Type 表

Index 库

filed 字段

 

 

6.Elasticsearch6.6版本部署安装

官方文档:
https://www.elastic.co/guide/en/elasticsearch/reference/current/install-elasticsearch.html

 

第一步:上传安装包并解压

[root@ken1 ~]# yum install java -y
[root@ken1 ~]# yum install elasticsearch-6.6.0.rpm -y

 

第二步:修改配置文件

[root@ken1 ~]# grep -E -v "^$|^#" /etc/elasticsearch/elasticsearch.yml 
node.name: node-1   #标识该节点,和主机名无关
path.data: /var/lib/elasticsearch
path.logs: /var/log/elasticsearch
bootstrap.memory_lock: true  #锁住内存,和/etc/elasticsearch/jvm.options配合使用
network.host: 192.168.64.4  #监听的主机名
http.port: 9200

 

第三步:启动

[root@ken1 ~]#  sudo systemctl daemon-reload
[root@ken1 ~]#  sudo systemctl enable elasticsearch.service
Created symlink from /etc/systemd/system/multi-user.target.wants/elasticsearch.service to /usr/lib/systemd/system/elasticsearch.service.
[root@ken1 ~]#  sudo systemctl restart elasticsearch.service

 

第四步:发现启动不了报如下的错误

[root@ken1 ~]# tail -f /var/log/elasticsearch/elasticsearch.log 
[2019-11-24T22:38:47,665][INFO ][o.e.n.Node               ] [node-1] starting ...
[2019-11-24T22:39:05,496][INFO ][o.e.t.TransportService   ] [node-1] publish_address {192.168.64.4:9300}, bound_addresses {192.168.64.4:9300}
[2019-11-24T22:39:05,522][INFO ][o.e.b.BootstrapChecks    ] [node-1] bound or publishing to a non-loopback address, enforcing bootstrap checks
[2019-11-24T22:39:05,530][ERROR][o.e.b.Bootstrap          ] [node-1] node validation exception
[1] bootstrap checks failed
[1]: memory locking requested for elasticsearch process but memory is not locked
[2019-11-24T22:39:05,538][INFO ][o.e.n.Node               ] [node-1] stopping ...
[2019-11-24T22:39:05,560][INFO ][o.e.n.Node               ] [node-1] stopped
[2019-11-24T22:39:05,561][INFO ][o.e.n.Node               ] [node-1] closing ...
[2019-11-24T22:39:05,578][INFO ][o.e.n.Node               ] [node-1] closed

 

官方解决方案:

https://www.elastic.co/guide/en/elasticsearch/reference/6.4/setup-configuration-memory.html
https://www.elastic.co/guide/en/elasticsearch/reference/6.4/setting-system-settings.html#sysconfig
### 修改启动配置文件
systemctl edit elasticsearch
### 增加如下参数
[Service]
LimitMEMLOCK=infinity
### 重新启动
systemctl daemon-reload
systemctl restart elasticsearch

 

 

第五步:等几分钟再次查看

[root@ken1 ~]# ss -tnl | grep 9200
LISTEN     0      128    ::ffff:192.168.64.4:9200                    :::*                  

 

第六步:验证

有如下的输出表示正常启动

[root@ken1 ~]# curl 192.168.64.4:9200 
{
  "name" : "node-1",
  "cluster_name" : "elasticsearch",
  "cluster_uuid" : "H23XG8gwSpKc1gcFoHKz1w",
  "version" : {
    "number" : "6.6.0",
    "build_flavor" : "default",
    "build_type" : "rpm",
    "build_hash" : "a9861f4",
    "build_date" : "2019-01-24T11:27:09.439740Z",
    "build_snapshot" : false,
    "lucene_version" : "7.6.0",
    "minimum_wire_compatibility_version" : "5.6.0",
    "minimum_index_compatibility_version" : "5.0.0"
  },
  "tagline" : "You Know, for Search"
}

 

交互

 

所有其他语言可以使用RESTful API通过端口9200和Elasticsearch进行通信,你可以用你最喜爱的web客户端访问Elasticsearch.事实上,正如你所看到的,你甚至可以使用curl命令来和Elasticsearch交互 。

一个 Elasticsearch 请求和任何 HTTP 请求一样由若干相同的部件组成:

curl -X<VERB> '<PROTOCOL>://<HOST>:<PORT>/<PATH>?<QUERY_STRING>' -d '<BODY>'
VERB 适当的 HTTP 方法 或 谓词 : GET`、 `POST`、 `PUT`、 `HEAD 或者 `DELETE`。 PROTOCOL http 或者 https`(如果你在 Elasticsearch 前面有一个 `https 代理)
HOST  Elasticsearch 集群中任意节点的主机名,或者用 localhost 代表本地机器上的节点。 
PORT  运行 Elasticsearch HTTP 服务的端口号,默认是 9200 。
PATH API 的终端路径(例如 _count 将返回集群中文档数量)。Path 可能包含多个组件,例如: _cluster/stats 和 _nodes/stats/jvm 。
QUERY_STRING 任意可选的查询字符串参数 (例如 ?pretty 将格式化地输出 JSON 返回值,使其更容易 阅读)
BODY 一个 JSON 格式的请求体 (如果请求需要的话)

1.1 通用参数

1.1.1 pretty参数

当你在任何请求中添加了参数?pretty=true时,请求的返回值是经过格式化后的JSON数据,这样阅读起来更加方便。

系统还提供了另一种格式的格式化,?format=yaml,YAML格式,这将导致返回的结果具有可读的YAML格式。

1.1.2 human参数

对于统计数据,系统支持计算机数据,同时也支持比较适合人类阅读的数据。?human=true,默认是false

1.1.3 响应过滤filter_path

所有的返回值通过filter_path减少返回值的内容,多个值可以用逗号分开。也可以使用通配符*

 

curl命令行交互

1.1.1 计算文档数量

[root@ken1 ~]# curl -XGET 'http://192.168.47.75:9200/_count?pretty' -H 'Content-Type: application/json' -d '   
{
  "query": { "match_all": {}
  } 
}
'
{
  "count" : 0,
  "_shards" : {
    "total" : 0,
    "successful" : 0,
    "skipped" : 0,
    "failed" : 0
  }
}

 

es-head插件交互

 

官方地址

由于网络原因下载不下来

https://github.com/mobz/elasticsearch-head

 

采用给谷歌浏览器安装扩展程序实现安装

 

 

如果连接不上:

在/etc/elasticsearch/elasticsearch.yml文件末尾加上

http.cors.enabled: true 
http.cors.allow-origin: "*"

 

 

相关操作API–增删改查

 

1.创建索引

[root@ken1 ~]# curl -XPUT '192.168.64.4:9200/ken?pretty'
{
  "acknowledged" : true,
  "shards_acknowledged" : true,
  "index" : "ken"
}

 

浏览器可查看到如下的信息

2.删除索引

[root@ken1 ~]# curl -XDELETE '192.168.64.4:9200/ken?pretty'
{
  "acknowledged" : true
}

 

再次查看浏览器,索引已经被删除

 

3.往索引里面插入数据

[root@ken1 ~]# curl -XPUT '192.168.64.4:9200/ken?pretty'   #索引不创建在插入数据的时候也会自动创建
[root@ken1 ~]# curl -XPUT '192.168.64.4:9200/ken/user/1?pretty' -H 'Content-Type: application/json' -d'
{
    "first_name" : "John",
    "last_name": "Smith",
    "age" : 25,
    "about" : "I love to go rock climbing", "interests": [ "sports", "music" ]
}
'

 

浏览器查看

 

 

插入多条数据

[root@ken1 ~]# curl -XPUT '192.168.64.4:9200/ken/user/2?pretty' -H 'Content-Type: application/json' -d' {
"first_name": "Jane",
"last_name" : "Smith",
"age" : 32,
"about" : "I like to collect rock albums", "interests": [ "music" ]
}
'
[root@ken1 ~]# curl -XPUT '192.168.64.4:9200/ken/user/3?pretty' -H 'Content-Type: application/json' -d' {
"first_name": "Douglas", 
"last_name" : "Fir",
"age" : 35,
"about": "I like to build cabinets", "interests": [ "forestry" ]
} '

index 相当于MySQL的库

type 相当于MySQL的表

id 相当于MySQL主键,不能重复,可由系统自动生成随机ID

 

 

4.查数据

[root@ken1 ~]# curl -XGET '192.168.64.4:9200/ken/user/_search?q=last_name:Smith&pretty'

显示如下

[root@ken1 ~]# curl -XGET '192.168.64.4:9200/ken/user/_search?q=last_name:Smith&pretty'
{
  "took" : 65,
  "timed_out" : false,
  "_shards" : {
    "total" : 5,
    "successful" : 5,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : 2,
    "max_score" : 0.2876821,
    "hits" : [
      {
        "_index" : "ken",
        "_type" : "user",
        "_id" : "2",
        "_score" : 0.2876821,
        "_source" : {
          "first_name" : "Jane",
          "last_name" : "Smith",
          "age" : 32,
          "about" : "I like to collect rock albums",
          "interests" : [
            "music"
          ]
        }
      },
      {
        "_index" : "ken",
        "_type" : "user",
        "_id" : "1",
        "_score" : 0.2876821,
        "_source" : {
          "first_name" : "John",
          "last_name" : "Smith",
          "age" : 25,
          "about" : "I love to go rock climbing",
          "interests" : [
            "sports",
            "music"
          ]
        }
      }
    ]
  }
}

 

但是书写过于复杂,我们可以通过浏览器进行上述查找

例如:我们想查找最后一个名字是Smith和年龄大于30小于35的人

 

改数据创建索引等操作

都可以在如下界面进行

如下就是创建了一个索ken1

 

 

 

总结如下

 

 

 

发表评论

电子邮件地址不会被公开。