Elasticsearch快速入門和環境搭建

技術Fun發表於2021-06-01

內容概述

本文內容主要集中在應用層,通過下面幾個部分介紹當前最流行的搜尋工具:Elasticsearch,瞭解這些內容後,可以快速開始使用它。

  • 什麼是Elasticsearch,為什麼要使用它?
  • 基礎概念:節點,索引,型別對映和文件
  • 本地環境搭建,建立第一個index
  • 常用RESTful Api示例

什麼是Elasticsearch,為什麼要使用它?

Elasticsearch 是一個分散式、RESTful 風格的搜尋和資料分析引擎。

它基於Lunece實現,使用java語言編寫。Lunece是一個優秀的搜尋引擎庫,但它使用起來非常複雜。

Elasticsearch通過對 Lunece的封裝,隱藏了複雜性,提供了使用簡單的RESTful Api。

同時也實現了分散式叢集特性,具有儲存資料大,查詢效能好,擴充套件方便等特點。

為什麼要使用它

在業務開發中,基於ES的特性,通常有下面這些場景需要使用它:

  • 儲存大量資料。通過在使用mysql儲存的時候,資料的單位是G。使用ES的時候,資料的單位是T。由此可以看出ES使用於大資料量的儲存場景,基於分散式特性,它也支援備份和容災,並且可以很容易水平擴充套件容量。
  • 分詞搜尋引擎。ES具有強大的分詞能力,可以支援高效能的實時搜尋。
  • 高效資料分析。ES提供的聚合分析功能,可實現對儲存的大量資料的近實時統計分析。

基礎概念簡介

要使用ES,需要了解幾個最基本的概念,節點(node),索引(index),型別對映(mapping)和文件(doc)。

節點(node)

節點是組成ES叢集的基本單位,每個節點是一個執行的ES例項。每個物理機器上可以有多個節點,使用不同的埠和節點名稱。

節點按主要功能可以分為三種:主節點(Master Node),協調節點(Coordianting Node)和資料節點(Data Node)。下面簡單介紹下:

  • 主節點:處理建立,刪除索引等請求,維護叢集狀態資訊。可以設定一個節點不承擔主節點角色
  • 協調節點:負責處理請求。預設情況下,每個節點都可以是協調節點。
  • 資料節點:用來儲存資料。可以設定一個節點不承擔資料節點角色

索引(index)

索引是ES中的邏輯概念,是文件的容器。對ES的操作,基本都是對索引操作,一個ES叢集中,可以建立多個索引。

索引定義了一組文件的資料模型和處理方法。每個索引可以有多個主分片和副本分片,分別儲存在不同的節點。

  • 主分片的作用是對索引的擴容,使一個索引的容量可以突破單機的限制。
  • 副本分片是對資料的保護,每個主分片對應一個或多個副本分片,當主分片所在節點當機時,副本分片會被提升為對應的主分片使用。
  • 一個主分片和它的副本分片,不會分配到同一個節點上。
  • 一個索引的分片數在建立時指定,如果要修改需要重建索引,代價很高。

型別對映(mapping)

mapping定義了一個索引中,文件儲存的每個欄位的資料型別。根據資料型別的不同,在新增文件時對每個欄位的處理也不同。

例如,對text型別的欄位,會先使用分詞器分詞,生成倒排索引,用於之後的搜尋。對keyword型別的欄位,不會分詞,搜尋時只能精確查詢。

一個簡單的mapping示例如下:

{
    "javalogs": { //索引名稱
        "mappings": {
            "properties": {
                "log_content": { //text型別,分詞,用於之後的分詞索引
                    "type": "text"
                },
                "date": {//時間型別
                    "type": "date" 
                },
                "log_level": { //keyword型別,不分詞
                    "type": "keyword" 
                },
                "ip": {
                    "type": "keyword"
                }
            }
        }
    }
}

在6.x版本中,每個索引中還可以有多個type,區分不同的mapping。在7.x中,type被取消,每個索引只有一個type:_doc

文件(doc)

  • 文件是Elasticsearch中的最小單位,每個索引都是有數量眾多的文件組成的。

  • 文件中包含多個欄位,每個欄位的型別由mapping定義。

  • 在一個索引中每個文件都有一個唯一id,可以在新增時指定,也可以自動生成。

下面通過一張圖來描述,節點(node),索引(index)和文件(doc)之間的關係。

本地環境搭建,建立第一個index

一切知識都要通過實踐掌握,所以在瞭解基本的概念和邏輯後,下面就進入實踐環節。

這裡推薦使用docker來搭建本地開發環境,docker對應windows和mac系統都有桌面版本,使用非常方便。因為網路限制,直接使用docker官方倉庫拉取映象會很慢,所以在安裝完成後,需要在設定中將倉庫的地址替換為國內源,這裡推薦https://docker.mirrors.ustc.edu.cn,速度很快,設定如下:

{
  "registry-mirrors": [
    "https://docker.mirrors.ustc.edu.cn"
  ]
}

下面我們使用docker安裝Elasticsearchkibana映象,kibana是es官方配套的視覺化分析工具,使用它的頁面dev tools可以很方便的通過api操作es。

因為要同時部署兩個docker映象,這裡推薦使用docker-composer,桌面版安裝完成後就帶有該命令,需要的配置如下:

services:
  kibana:
    image: kibana:7.2.0
    container_name: kibana-simple
    environment:
      - TIMELION_ENABLED=true
    ports:
      - "5601:5601"
    networks:
      - mynetwork
  elasticsearch:
    image: elasticsearch:7.2.0
    container_name: es-simple
    environment:
      - cluster.name=mytestes #這裡就是ES叢集的名稱
      - node.name=es-simple #節點名稱
      - bootstrap.memory_lock=true
      - network.publish_host=elasticsearch #節點發布的網路名稱
      - discovery.seed_hosts=es-simple #設定叢集中的主機地址
      - cluster.initial_master_nodes=es-simple #手動設定可以成為master的節點集合
    ulimits:
     memlock:
      soft: -1
      hard: -1
    volumes:
      - esdata1:/usr/local/elasticsearch/simpledata
    ports:
      - 9200:9200
    networks:
      - mynetwork

volumes:
  esdata1:
    driver: local

networks:
  mynetwork:
    driver: bridge

建立一個名稱為docker-compose.yaml檔案,複製下面的配置到檔案中,然後再檔案所在目錄執行docker-compose up,之後會啟動兩個docker例項,分別是elasticsearchkibana

在本地瀏覽器中,訪問http://127.0.0.1:5601/,可以看到kibana的介面如下:

建立好的kibana已經預設新增了Elasticsearch的配置,通過管理工具可以很方便的檢視ES叢集的狀態,索引情況,刪除索引等。

kibana-monitor

下面通過dev tools建立索引,dev tools提供的命令提示很方便,並且可以把已寫好的請求儲存在瀏覽器快取中,非常適合用來學習Elasticsearch

create-index

這裡通過ES提供的RESTful Api建立了第一個索引, 並且設定了該索引中的mapping,ES的地址已經設定過,這裡可以不寫完整的域名,對應的curl完整請求如下:

curl --location --request PUT 'http://127.0.0.1:9200/javalogs' \
--header 'Content-Type: application/json' \
--data-raw '{
    "mappings": {
        "properties": {
            "log_content": {
                "type": "text"
            },
            "date": {
                "type": "date"
            },
            "log_level": {
                "type": "keyword"
            },
            "ip": {
                "type": "keyword"
            }
        }
    }
}'

常用RESTful Api示例

下面介紹下Elasticsearch中常用的api,這些例子都是直接在kibanadev tools中執行的,如果想用curl訪問,可參考前一節中的轉換例子。

新增文件

//自動生成_id
POST javalogs/_doc
{
  "log_content" : "get user_id 123456",
  "date" : "2020-04-15T11:09:08",
  "log_level": "info",
  "ip": "10.223.32.67"
}
//指定_id
POST javalogs/_doc/111
{
  "log_content" : "api response in 55ms",
  "date" : "2020-04-15T11:09:07",
  "log_level": "info",
  "ip": "10.223.32.67"
}

查詢文件-不分詞型別

ES在文件查詢時,對於不分詞的查詢,直接按值查詢即可,例如下面這樣:

//不分詞型別查詢
POST javalogs/_search
{
  "query": {
    "match": {
      "ip": "10.223.32.67"
    }
  }
}

查詢文件-分詞型別

這裡主要說下分詞型別的查詢,對於分析型別的field在查詢時,也會預設把查詢的語句分詞。假設有兩個文件如下:

//文件1
{
  "log_content" : "call aaa service error",
  "date" : "2020-04-15T11:09:07",
  "log_level": "error",
  "ip": "10.223.32.67"
}

//文件2
{
  "log_content" : "call bbb service error",
  "date" : "2020-04-15T11:09:08",
  "log_level": "error",
  "ip": "10.223.32.67"
}

當搜尋條件為call aaa service時,實際上會把兩個文件都搜尋出來。
這是因為在搜尋時,條件call aaa service會被分詞為callaaaservice,所有包含這三個詞的文件都會被搜尋出來,例如下面:

//普通搜尋,兩個文件都會返回
POST javalogs/_search
{
  "query": {
    "match": {
      "log_content": "call aaa service"
    }
  }
}

那如果想要只搜尋包含call aaa service的文件,應該如何做呢?

按照上面的分析,需要同時包含這三個詞,並且按照給定的順序,才返回對應的文件,那麼這個可以使用match_phrase實現,示例如下:

//文件必須同時包含三個詞,並且順序與搜尋條件一致才會返回。這裡只會返回-文件1
POST javalogs/_search
{
  "profile": "true", 
  "query": {
    "match_phrase": {
      "log_content": "call aaa service"
    }
  }
}

那如果條件是包含callaaaservice,但是不一定是連著的,該如何搜尋呢?可以使用operator操作符實現。

例如有第三個文件如下:

//文件3
{
  "log_content" : "call inner aaa service error",
  "date" : "2020-04-15T11:09:08",
  "log_level": "error",
  "ip": "10.223.32.67"
}

要想把文件1文件2都搜尋出來,查詢的示例如下:

//文件中同時包含call,aaa和service就會返回,不按順序。會返回-文件1和文件2
POST javalogs/_search
{
  "query": {
    "match": {
      "log_content": 
      {
        "query": "call aaa service",
        "operator": "and"
      }
    }
  }
}

上面就是對Elasticsearch的簡單介紹和實戰操作示例,希望能幫助大家快速入門使用ES。

以上內容屬個人學習總結,如有不當之處,歡迎在評論中指正

相關文章