baixiaoji / supplier

It's the source!
1 stars 0 forks source link

学习至应用 Elasticsearch #30

Open baixiaoji opened 4 years ago

baixiaoji commented 4 years ago

这是什么东西?(明白该想project的定义)

学习 es 概念,作用于排查生产问题

es 是全文搜索引擎的一种

为什么要做这个东西?(想想做这个东西的动机)

生产过程出现,线下与线上表现不一致。

自己排查问题,同样查询了部分解释文档然后实践,问题并没有解决。所以索性系统化学习es。

如何做这个东西?(拆解细节)

回顾(项目过程中的执行、以及心态的变化)

资料

  1. 全文搜索引擎 Elasticsearch 入门教程
  2. 权威指南
  3. gitchat 专栏
baixiaoji commented 4 years ago

ES 是什么?

Elasticsearch 是可海量存储的分布式搜索分析引擎,基于Lucene搜索引擎库的一层封装的REST API。 对全文搜索支持良好(免费),生产中更多是查询一些日志信息或是海量查询的使用。

对比关系型数据库

设计理念相同,但是叫法不同。

在 ES 中启动一个 ES 实例,这个实例就相当于数据库,表在 ES 中被称为索引 Index,行称为文档 Document,列称为字段 Field ,Schema 被称为 Mapping ,数据库中查询语句 SQL 在 ES 中有相应的 DSL 查询语句。

因此建学生索引:

  1. 配置 ES,启动一个 ES 实例
  2. 新建一个学生索引
  3. 不需要配置字段属性,ES 会自动识别
  4. 一个 JSON 字符串代表一个学生,JSON 字符串中有学生属性字段 Field

image

像传统的关系型数据库,需要定义好每一个数据库的Schema,而后才能插入数据,ES 是基于HTTP,提供了一套 REST API 。

document方面是以JSON格式的数据插入,ES会根据字段自动创建,表中并不会有主键和外键等概念,存储一个大的JSON对象。

baixiaoji commented 4 years ago

安装 elasticsearch

docker 安装

docker pull elasticsearch:7.4.2

启动容器

docker run -p 9200:9200 -p 9300:9300 -e "discovery.type=single-node" elasticsearch:7.4.2 

向外暴露 9200 端口和9300端口,port 9200 是http协议,可以使用浏览器与ES交互(查询 节点信息和节点状态),port 9300 是 tcp 协议,es集群之间进行通讯使用。

启动成功,访问http://localhost:9200/即可访问ES集群信息。ES 提供了一个 Rest API _cat作为监控 ES 状态信息的接口(访问http://localhost:9200/_cat/即可)。

baixiaoji commented 4 years ago

安装 Kibana

docker 安装

docker pull kibana:7.4.2

启动kibana,并与 es 建立联系

docker run --link <容器ID>:elasticsearch -p 5601:5601 kibana:7.4.2

查看容器id

docker ps -a

启动完成http://localhost:5601/进行访问。

baixiaoji commented 4 years ago

以上方式过于麻烦,可以利用docker-compose进行意见启动,创建一个docker-compose.yml文件。

# docker-compose.yml 
version: '2.2'
services:
  cerebro:
    image: lmenezes/cerebro:0.8.3
    container_name: cerebro
    ports:
      - "9000:9000"
    command:
      - -Dhosts.0.host=http://elasticsearch:9200
    networks:
      - es7net
  kibana:
    image: docker.elastic.co/kibana/kibana:7.4.2
    container_name: kibana7
    environment:
      - I18N_LOCALE=zh-CN
      - XPACK_GRAPH_ENABLED=true
      - TIMELION_ENABLED=true
      - XPACK_MONITORING_COLLECTION_ENABLED="true"
    ports:
      - "5601:5601"
    networks:
      - es7net
  elasticsearch:
    image: docker.elastic.co/elasticsearch/elasticsearch:7.4.2
    container_name: es7_01
    environment:
      - cluster.name=eslearn
      - node.name=es7_01
      - bootstrap.memory_lock=true
      - "ES_JAVA_OPTS=-Xms512m -Xmx512m"
      - discovery.seed_hosts=es7_01,es7_02
      - cluster.initial_master_nodes=es7_01,es7_02
    ulimits:
      memlock:
        soft: -1
        hard: -1
    volumes:
      - es7data1:/usr/share/elasticsearch/data
    ports:
      - 9200:9200
    networks:
      - es7net
  elasticsearch2:
    image: docker.elastic.co/elasticsearch/elasticsearch:7.4.2
    container_name: es7_02
    environment:
      - cluster.name=eslearn
      - node.name=es7_02
      - bootstrap.memory_lock=true
      - "ES_JAVA_OPTS=-Xms512m -Xmx512m"
      - discovery.seed_hosts=es7_01,es7_02
      - cluster.initial_master_nodes=es7_01,es7_02
    ulimits:
      memlock:
        soft: -1
        hard: -1
    volumes:
      - es7data2:/usr/share/elasticsearch/data
    networks:
      - es7net
volumes:
  es7data1:
    driver: local
  es7data2:
    driver: local

networks:
  es7net:
    driver: bridge

服务有 cerebro 用来监控 ES 健康状态的,kibana 是 ES 的可视化图像界面,elasticsearch 则是就是 ES。

对应的目录下,执行命令

docker-compose up  

后续访问:

  1. localhost:5601 进入kibana界面
  2. localhost:9000 进入 cerebro界面,监控ES状态
baixiaoji commented 4 years ago

Kibana 界面说明

image

baixiaoji commented 4 years ago

Kibana 的图表操作是一个有趣的项目 #31

baixiaoji commented 4 years ago

elasticsearch REST API

后续操作,基于 elasticsearch@7.x,版本7之后存在一些变更,也就是类型统一改成了_doc

Index 操作 (将document插入index操作,行话 Index此处为动词)

PUT class/_doc/1
{
  "name": "baiji",
  "gender": "male",
  "age": 23
}

若发现同样的数据,删除之前的document,更新成插入document,然后将_version+1,result为updated。

create 操作

解决若出现相同id之后,无法插入。

PUT class/_create/1
{
  "name": "baiji",
  "gender": "male",
  "age": 23
}

无法得知接下来的id,如何插入新的document,是否自动生产Id呢? 将方法给成POST

POST class/_create
{
  "name": "baixiaoji",
  "gender": "male",
  "age": 23
}

update 操作

POST class/_update/1
{
  "doc": {
  "age": 24  
  }
}

get 操作

使用 GET 命令,指定索引/类型/ID 就可以查询到相应的文档。我们存的数据都被包裹在 _source 字段中。

GET class/_doc/1

那无法知道id怎么办?

Bulk 批量操作

一条一条语句执行,对网络IO不友好,ES提供了Bulk API,支持批量插入数据,减少网络IO。 Bulk 支持 Index create update delete 操作。

PUT _bulk
{"delete":{"_index":"class","_id":"1"}}
{"index": {"_index": "class", "_id": "1"}}
{  "name": "baiji","gender": "male","age": 23}
{"create": {"_index": "class","_id": "2"}}
{  "name": "baixiaoji","gender": "male","age": 24}
{"_update": {"_id": "1", "_index": "class"}}
{"doc": {"age": 18}}

mget 批量读

GET _mget 
{
  "docs": [
    {"_index": "class", "_id": 1},
    {"_index": "class", "_id": "2"}
    ]
}

其余操作

设置Index初始化的分片以及给每一个分配配置的副本数量

PUT /class1
{
  "settings": {
    "number_of_replicas": 1,
    "number_of_shards": 2  
  }
}

POST class1/_doc
{
  "name": "kevin",
  "gender": "male",
  "age": 23
}
baixiaoji commented 4 years ago

elasticsearch REST API

上面get查询出现一个问题,不知道id怎么办, es提供改了_search api

GET class/_search?q=name:baixiaoji

OR 或运算

GET class/_search?q=name:(baixiaoji OR baiji)
GET class/_search?q=name:baixiaoji baiji

AND 和运算

GET class/_search?q=name:(baixiaoji AND baiji)
GET class/_search?q=name:"baixiaoji baiji"

NOT 非运算

GET class/_search?q=name:(NOT baiji)

两种查询 Term 和 Phrase

ES 在对某个字段进行查询时,会分为两种查询方式,Term 与 Phrase 。简单来说就是把文本查询条件看做是一个“词”,还是“多个词”。使用双引号就是Term查询,否则搜视Phrase查询。

范围查询

GET class/_search?q=age:<24
GET class/_search?q=age:(>=18 AND <=23)
baixiaoji commented 4 years ago

elasticsearch REST API

通配符查询

// * 匹配 0 或 多个 字符
GET class/_search?q=name:bai*
// ? 匹配 0 或 1 各字符
GET class/_search?q=name:bai?iaoji
// 其实就是正则的使用
GET class/_search?q=name.keyword:/ziqi [0-9]{1} deng/

分页

GET class/_search
{
  "from": 0, "size": 1
}