美文网首页面试精选Java技术升华elasticsearch
Elasticsearch:基本概念、安装、快速开始

Elasticsearch:基本概念、安装、快速开始

作者: xiaogp | 来源:发表于2022-02-26 19:26 被阅读0次

摘要:Elasticsearch

《Elasticsearch搜索引擎构建入门与实战》第一章读书笔记

Elasticsearch特色优势

  • 实时性好:相比于Lucene,新增的数据数秒甚至1秒(缓存)内可以搜索到
  • 分布式架构设计:可以拓展到多台机器进行搜索
  • 提供REST风格API,相比于Lucene需要Java开发,ES支持HTTP请求来进行查询
  • 提供了聚合查询:ES可以对索引中的数据做聚合统计分析

Elasticsearch基本概念

  • 索引:要对进行数据存储和查询操作需要先建立索引,ES中的索引相当于传统数据库的库
  • 文档:相当于传统数据库的一条记录,就是ES中一个文档,一个文档可以包含一个或多个字段,每个字段可以有各种类型,文档的初始版本是1,每次写操作会自动版本号+1,查询时ES返回最大版本号的文档
  • 字段:常见的类型包括字符串,文本,数值,还有ES提供其他类型,比如数组,地理经纬,IP地址等,不同的数据类型ES支持不同的所有功能,比如文本可以基于分词搜索,地理经纬可以所有某点附近的文档
  • 映射:映射就是定义的数据结构schema,一旦设定之后不能更改,ES也提供了自动映射的功能,如果要写入的数据没有给定类型ES会自动推断
  • 集群和节点:多台机器一起协作作为集群,ES集群的节点数不受限制,一个节点就对应一台机器
  • 分片:ES会对数据进行切分存储到多台计算机中,均匀分摊单台机器的存储压力,ES默认一个索引5个分片,分片一定设置是不可以修改的,只能新建新索引解决一个节点可以被分配多个主分片。每个分片可以设置副分片,当主分片故障离线时副分片会充当主分片继续提供服务,保证了高可用
  • 副分片:在一个索引中主分片的副分片个数没有限制,默认ES不会启用副分片。一个主分片的所有副分片都存储在不同的机器上,保证一台机器宕机的情况下,其他机器的副分片可以提供服务。因此如果只设置了一个ES节点,且启动了至少一个副分片,实际上ES只会分配一个主分片,不会分配副分片

如上图,三个主分片P0,P1,P2,各自的副分片R0,R1,R2都分别在另外的机器上,一个三个节点存储分别分配了一个主分片,主分片的备份数量是1

  • DSL:领域特定语言,是用来定义查询的,HTML,CSS,SQL都属于DSL,ES中DSL使用JSON表达,查询的返回数据也是JSON格式

Elasticsearch和传统关系型数据库对比

  • 索引方式不同:关系型数据库大多是B-Tree索引,ES是倒排索引
  • 事务支持:ES不支持事务支持,ES使用乐观锁,不阻塞数据的更新操作,每次更新采用增加版本号的方式,导致某些更新操作可能失效,数据未更新成功。

悲观锁和乐观锁

  1. 悲观锁是基于一种悲观的态度类来防止一切数据冲突,它是以一种预防的姿态在修改数据之前把数据锁住,然后再对数据进行读写,是一种串行的方式,只要开始执行就会锁表,一般数据库本身锁的机制都是基于悲观锁的机制实现的
  2. 乐观锁是对于数据冲突保持一种乐观态度,操作数据时不会对操作的数据进行加锁(这使得多个任务可以并行的对数据进行操作),只有到数据提交的时候才通过一种机制来验证数据是否存在冲突(一般实现方式是通过加版本号然后进行版本号的对比方式实现),乐观锁并不会真的加锁,而是通过一些状态的检验达到操作互斥的效果
    例如有以下数据采用乐观锁的方式,用户A,B分别查询Name=zhangsan的这条记录,并进行修改再次写入数据库

    因为采用乐观锁,因此A,B都可以并行地拿到数据,用户A拿到之后将Name修改为lisi,在提交操作时,数据库会把之前查询到的version与现在的数据的version进行比较,版本相同则可以提交,版本不同则视为数据过期,过期则提交失败,如以下SQL更新语句
    update A set Name=lisi,version=version+1 where ID=#{id} and version=#{version}
    更新成功后数据库该记录变为

    此时用户B将Name改为wangwu,再提交时会失败,因为自身verson=1,而数据库内的version=2,数据过期
  • 查询语句不同:关系型数据库采用SQL,原因是查询比较简单直接,ES采用DSL来完成比较复杂的查询所有需求

  • 查询速度:如果字段少,数据量不打,关系型数据库查询速度很快,但是单表有上百字段和几十亿条数据查询速度就会变慢,随着数据量的增长速度越来越慢,ES可以支持对全字段做索引,单个索引存储上百字段或几十亿条数据查询速度都不会变慢

  • 数据的实时性:关系型数据库是实时的,插入之后立马可以查到,ES内存中的数据先写入缓存,默认1s之后统一刷入磁盘,才能被ES查到,因此ES是准实时的


Elasticsearch架构原理

(1)节点的职责

节点按照职责可以分为master节点数据节点协调节点,每个节点的角色可以单独配置,默认每台机器都可以担任这三种角色。

  • master节点:维护ES集群工作,如创建删除索引,节点上线下线,健康状态监测等,master通过选举算法产生,在候选的机器中只能有一个master节点,可以配置node.master为true将当前节点作为master节点的候选
  • 数据节点:负责数据保存,修改,删除,查询,数据节点的工作是调用Lucene库进行索引操作,对内存和I/O消耗比较大
  • 协调节点:负责对接客户端请求,默认情况下协调节点可以是集群中的任一节点,当一个请求开始时该节点作为协调节点存在,请求结束该协调节点生命结束。协调节点将请求转发给其他节点,最终汇总结果输出。为了降低集群负荷,可以设置某些节点作为单独的协调节点,将这些节点的node.masternode.data全部设置为false即可,所有的数据请求都会发到这些单独设置的协调节点,例如图中的Client Node就是协调节点
(2)主分片和副分片

ES中索引由一个或多个分片组成,一个分片可以拥有0个或多个副分片,保证了高可用。

例如当node1发生宕机,P0消失,集群感知到P0消失之后会找到node3的R0充当为新的P0,此时只有node2和node3对外提供服务。



当node1恢复时,node1上面的主分片和副分片会分别从node2,node3同步数据,node1本来的P0变为R0


(3)文档读写流程

写流程
ES协调节点接受客户端请求,默认根据文档的_id值通过路由计算获得目标主分片,和主分片所在的节点,将客户端请求转发,写入该节点的主分片,然后对于该主分片的副分片,分别找到所在的节点再写入,等主副全部写好了,ES协调节点告诉客户端写入完成

路由计算
路由计算的目的是对于客户端发来的文档,找到文档要读取或者写入的主分片和主分片所在的节点,实际上是计算的分片ID,公式如下
shard=hash(routing)%number_of_primary_shards
routing:客户端提交的参数,默认是文档的_id
number_of_primary_shards:索引中的主分片个数
相当于就是对文档hash取模计算出到底去哪个分片,计算出主分片ID之后,ES的协调节点上存储了一份节点-分片的对照表,根据这个表找到主分片和副分片所在的机器节点,找到节点进行写入操作

读流程
当客户端收到请求文档的读取要求时,同样根据路由算法找到对应的主分片,协调节点根据对照表找到所有该主分片以及对应的副分片的节点,然后使用轮询算法从主/副中选取一个,数据传递给协调节点,再返回给客户端

轮询算法
轮询算法是最简单的一种负载均衡算法。它的原理是把来自用户的请求轮流分配给内部的节点,从节点1开始,直到节点N,然后重新开始循环。


Elasticsearch安装

(1)单机安装

进入该网站下载对应的压缩包 https://www.elastic.co/cn/downloads/elasticsearch

开始解压

tar -zxvf elasticsearch-8.0.0-linux-x86_64.tar.gz
cd elasticsearch-8.0.0
ll
total 884
drwxr-xr-x  9 root root   4096 2月   4 00:55 ./
drwxr-xr-x 11 root root   4096 2月  26 19:37 ../
drwxr-xr-x  2 root root   4096 2月   4 00:55 bin/
drwxr-xr-x  3 root root   4096 2月  26 19:37 config/
drwxr-xr-x  9 root root   4096 2月   4 00:55 jdk/
drwxr-xr-x  3 root root   4096 2月   4 00:55 lib/
-rw-r--r--  1 root root   3860 2月   4 00:47 LICENSE.txt
drwxr-xr-x  2 root root   4096 2月   4 00:52 logs/
drwxr-xr-x 65 root root   4096 2月   4 00:55 modules/
-rw-r--r--  1 root root 858789 2月   4 00:52 NOTICE.txt
drwxr-xr-x  2 root root   4096 2月   4 00:52 plugins/
-rw-r--r--  1 root root   2710 2月   4 00:47 README.asciidoc

ES不允许root用户启动,需要创建一个用户,并且将整个目录修改拥有者为该用户

root@ubuntu:/opt/elasticsearch-8.0.0# useradd  -s /bin/bash /us^C
root@ubuntu:/opt/elasticsearch-8.0.0# useradd -s /bin/bash -m es
root@ubuntu:/opt/elasticsearch-8.0.0# passwd es
Enter new UNIX password: 
Retype new UNIX password: 
passwd: password updated successfully
root@ubuntu:/opt/elasticsearch-8.0.0# su es

修改拥有者

root@ubuntu:/opt/elasticsearch-8.0.0# chown -R es /opt/elasticsearch-8.0.0

es默认配置进程占用内存1GB,如果机器内存不足可以修改配置

# 打开 confog/jvm.options
-Xms512m
-Xmx512m

关闭ssl认证和用户名密码认证

# config/elasticsearch.yml
xpack.security.http.ssl:
  enabled: false

xpack.security.enabled: false

下面启动es

root@ubuntu:/opt/elasticsearch-8.0.0/bin# su - es
es@ubuntu:~$ cd /opt/elasticsearch-8.0.0/bin/
es@ubuntu:/opt/elasticsearch-8.0.0/bin$ ./elasticsearch

http访问9200端口

root@ubuntu:~# curl http://127.0.0.1:9200
{
  "name" : "ubuntu",
  "cluster_name" : "elasticsearch",
  "cluster_uuid" : "9T7jMwqUR_qSchEC6Hpn0w",
  "version" : {
    "number" : "8.0.0",
    "build_flavor" : "default",
    "build_type" : "tar",
    "build_hash" : "1b6a7ece17463df5ff54a3e1302d825889aa1161",
    "build_date" : "2022-02-03T16:47:57.507843096Z",
    "build_snapshot" : false,
    "lucene_version" : "9.0.0",
    "minimum_wire_compatibility_version" : "7.17.0",
    "minimum_index_compatibility_version" : "7.0.0"
  },
  "tagline" : "You Know, for Search"
}

目录下新增的data目录就是存储索引数据的文件

(2)安装Kibana

Kibana提供ES的查询可视化功能,同时提供DEV Tools,可以与ES进行交互请求。Kibana版本最好es版本一致

wget https://artifacts.elastic.co/downloads/kibana/kibana-8.0.0-linux-x86_64.tar.gz

解压,求改拥有者

tar -zxvf kibana-8.0.0-linux-x86_64.tar.gz
mv kibana-8.0.0 /opt/
chown -R es /opt/kibana-8.0.0

在kibana的配置文件中,默认elasticsearch.hosts为对应的ES HTTP服务地址

#elasticsearch.hosts: ["http://localhost:9200"]

如果允许其他计算机访问kibana,修改server.host为0.0.0.0

#server.host: "localhost"

然后先启动es,再启动kibana

es@ubuntu:/opt/kibana-8.0.0$ cd bin/
es@ubuntu:/opt/kibana-8.0.0/bin$./kibana

http端口号5601打开kibana界面


Elasticsearch快速开始

以下操作全部基于kibana的console

(1)创建索引

通过PUT请求,JSON中定义mappings,三个字段分别是text(文本),keyword(关键词),double(小数)类型

PUT /my_index
{
  "mappings": {
   "properties": {
      "title":{
         "type": "text"
     },
     "city":{
         "type": "keyword"
     },
     "price": {
         "type": "double"
     }
   }
  }
}
(2)写入文档

使用POST请求,加入请求体JSON数据,指定文档的_id为001

POST /my_index/_doc/001
{
  "title":"好再来酒店",
  "city": "青岛",
  "price": 578.23
}
(3)根据_id搜索文档

使用GET请求,在请求路由中指定_id

GET /my_index/_doc/001

查看返回结果,显示了该文档的_id,_version(版本号1),_source(返回的字段)

{
  "_index" : "my_index",
  "_id" : "001",
  "_version" : 1,
  "_seq_no" : 0,
  "_primary_term" : 1,
  "found" : true,
  "_source" : {
    "title" : "好再来酒店",
    "city" : "青岛",
    "price" : 578.23
  }
}
(4)根据一般字段搜索文档

进行复杂搜索时需要用到GET请求的_search路由和query请求体,本例查找price是578.23 的文档,使用term搜索

GET /my_index/_search
{
  "query": {
    "term": {
       "price": {
         "value": 578.23  
        }
     }
  }
}

看一下返回

{
  "took" : 1,
  "timed_out" : false,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 1,
      "relation" : "eq"
    },
    "max_score" : 1.0,
    "hits" : [
      {
        "_index" : "my_index",
        "_id" : "001",
        "_score" : 1.0,
        "_source" : {
          "title" : "好再来酒店",
          "city" : "青岛",
          "price" : 578.23
        }
      }
    ]
  }
}

返回结果除了文档详情之外还显示了_shards分片信息,一共一个分片,hits信息一共一条符合要求的文档

(5)文本字段搜索

文本模糊搜索需要使用query中的match关键字

GET /my_index/_search
{
  "query": {
    "match": {
       "title":  "好再" 
     }
  }
}

查看返回结果

{
  "took" : 5,
  "timed_out" : false,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 1,
      "relation" : "eq"
    },
    "max_score" : 0.5753642,
    "hits" : [
      {
        "_index" : "my_index",
        "_id" : "001",
        "_score" : 0.5753642,
        "_source" : {
          "title" : "好再来酒店",
          "city" : "青岛",
          "price" : 578.23
        }
      }
    ]
  }
}

返回来对应的文档,耗费了5ms(took关键字)

相关文章

网友评论

    本文标题:Elasticsearch:基本概念、安装、快速开始

    本文链接:https://www.haomeiwen.com/subject/nqmqrrtx.html