天天看點

ElasticSearch 介紹、安裝及簡單使用

文章目錄

      • 介紹
      • 基本概念
        • 全文搜尋(Full-text Search)
        • 反向索引(Inverted Index)
        • 節點&叢集(Node & Cluster)
        • 文檔(Document)
        • 索引(Index)
        • 類型(Type)
        • 文檔中繼資料(Document Metadata)
        • 字段(Field)
      • ElasticSearch與關系型資料庫對應關系
      • ElasticSearch與Solr對比
      • ElasticSearch安裝
      • ElasticSearch Head安裝
      • Kibana安裝
      • ElasticSearch增删改查
        • 新增文檔(Index API)
        • 修改文檔(Update API)
        • 查詢文檔(Get API)
        • 删除文檔(Delete API)
        • 批量操作(Bulk API)
        • 根據多個文檔ID擷取文檔(Multi Get API)
      • ES中文分詞器
        • 内置的标準分詞器standard
        • IK分詞器
      • 問題
        • 單機情況下增加索引叢集健康狀态是yellow
      • 參考網址

介紹

Elasticsearch 是大資料時代下的分布式搜尋引擎,底層基于 Lucene 實作。Elasticsearch 屏蔽了 Lucene 的底層細節,提供了分布式特性,同時對外提供了 Restful API,資料互動格式為JSON。Elasticsearch 以其易用性迅速赢得了許多使用者,被用在網站搜尋、日志分析等諸多方面。由于 ES 強大的橫向擴充能力,甚至很多人也會直接把 ES 當做 NoSQL 來用。

基本概念

全文搜尋(Full-text Search)

全文檢索是指計算機索引程式通過掃描文章中的每一個詞,對每一個詞建立一個索引,指明該詞在文章中出現的次數和位置,當使用者查詢時,檢索程式就根據事先建立的索引進行查找,并将查找的結果回報給使用者的檢索方式。

反向索引(Inverted Index)

該索引表中的每一項都記錄了屬性值與具有該屬性值的記錄的位址。由于不是由記錄找到屬性值而是通過屬性值找到記錄,是以叫作反向索引。譬如歌手張學友唱過《味道》這首歌曲,歌手辛曉琪和吳彥斌也唱過,我們能通過張學友找到他唱了《味道》這首歌曲,但是反過來我們通過《味道》這首歌曲能找到張學友和其他歌手,這樣通過屬性值找到記錄的方法就稱為反向索引,也就是反向索引。

ES是為記錄的每個字段都建立了反向索引,是以才能實作快速高效的搜尋功能。

具體反向索引結構可以參考ElasticSearch反向索引結構分析。

節點&叢集(Node & Cluster)

ElasticSearch本質上就是分布式搜尋引擎,允許多台伺服器協同工作,每台伺服器可以運作多個ElasticSearch執行個體,每個ElasticSearch執行個體就稱為一個節點(

Node

),一組節點就稱為一個叢集(

Cluster

)。

單節點的ES也可以是一個叢集。

文檔(Document)

文檔其實就是使用者送出給ES的一條資料,上面也說過ES資料互動格式都是JSON,是以這裡的文檔就是一條JSON資料。這裡的文檔可以類比成關系型資料庫中的記錄。JSON資料中含有多個字段,JSON裡的字段可以類比成關系型資料庫中表的字段。

索引(Index)

索引(Index)可以了解成文檔的集合,同在一個索引中的文檔共同建立反向索引。

索引(Index)可以類比成關系型資料庫中的庫(Database)。

類型(Type)

文檔可以分組,比如employee這個 Index 裡面,可以按部門分組,也可以按職級分組。這種分組就叫做 Type,它是

虛拟的邏輯分組

,用來過濾 Document,類似關系型資料庫中的資料表。

不同的Type應該有相似的結構,性質完全不同的資料應該存成兩個Index而不是一個Index裡不同的Type。

ES官網提出的Type觀念的演變情況如下

5.x版本中,一個Index下可以建立多個Type

6.x版本中,一個Index下隻能存在一個Type

7.x版本中,去除了Type的概念

8.x版本中,正式棄用

為什麼會被棄用?

因為同一個索引下,

不同type下若字段名是一樣的則ES會認為是一個字段而且類型必須一緻

,因為type隻是一個虛拟的邏輯分組。

不同type的資料存儲其他type的字段大量空值,造成資源浪費

,而且基于Lucene的反向索引是基于Index而不是Type的,多個Type反而會減慢搜尋速度。

文檔中繼資料(Document Metadata)

文檔中繼資料為_index、_type、_id

,這三者可以唯一表示一個文檔。_index表示文檔存放于哪個索引,_type表示文檔的對象類别,_id為文檔的唯一辨別。

字段(Field)

每個文檔都是一條JSON資料,JSON資料中的每個key就是字段(Field)。

ElasticSearch與關系型資料庫對應關系

ES早期是借鑒了關系型資料庫的模式,對應關系如下圖

ElasticSearch 介紹、安裝及簡單使用

對于最新的ES版本而言,由于棄用了Type概念,

一張表就對應一個索引

ElasticSearch與Solr對比

二者安裝都很簡單;

Solr 利用 Zookeeper 進行分布式管理,而 Elasticsearch 自身帶有分布式協調管理功能

;

Solr 支援更多格式的資料,而

Elasticsearch 僅支援json檔案格式

Solr 官方提供的功能更多,而 Elasticsearch 本身更注重于核心功能,進階功能多有第三方插件提供;

Solr 在

傳統的搜尋

應用中表現好于 Elasticsearch,但在

處理實時搜尋應用時效率明顯低于

Elasticsearch。

Solr 是傳統搜尋應用的有力解決方案,但 Elasticsearch 更适用于新興的實時搜尋應用。

ElasticSearch安裝

由于國内通路ElasticSearch官網很慢,是以建議從華為開源鏡像站下載下傳。

後續相關内容都以7.6.1版本來學習。并且相關服務都部署在Linux伺服器上。

ElasticSearch 介紹、安裝及簡單使用
  • 解壓檔案

    将檔案放到

    /usr/local/src/packages/es

    目錄下
    ElasticSearch 介紹、安裝及簡單使用
    解壓檔案并建立軟連接配接
cd /usr/local/src
tar zxPvf packages/es/elasticsearch-7.6.1-linux-x86_64.tar.gz
ln -s elasticsearch-7.6.1 elasticsearch

           
ElasticSearch 介紹、安裝及簡單使用
  • 建立ElasticSearch啟動使用者并給相關檔案夾賦予權限
useradd es
passwd es
chown -R es:es /usr/local/src/elasticsearch-7.6.1
chown -R es:es /usr/local/src/elasticsearch
           
  • 修改配置檔案

    elasticsearch-7.6.1/config/elasticsearch.yml

    目前主機名是: master
node.name: node-1
network.host: master
discovery.seed_hosts: ["master"]
           
  • 修改配置檔案

    /etc/security/limits.conf

    修改後通過

    ulimit -Hn 和 ulimit -Sn

    檢視是否生效
* soft nofile 655350
* hard nofile 655350
           
ElasticSearch 介紹、安裝及簡單使用
  • 修改配置檔案

    /etc/sysctl.conf

    并執行

    sysctl -p

    重新加載該配置檔案
vm.max_map_count=655360
           
  • 啟動ElasticSearch
cd /usr/local/src/elasticsearch/bin
./elasticsearch
# 或者 ./elasticsearch -d 以背景程序的方式啟動
           
ElasticSearch 介紹、安裝及簡單使用
  • 驗證ElasticSearch是否正常

    在浏覽器上輸入 http://master:9200/ 得到下圖所示

    ElasticSearch 介紹、安裝及簡單使用
    curl方式通路

    curl -XGET "http://master:9200"

    ElasticSearch 介紹、安裝及簡單使用

ElasticSearch Head安裝

該工具是GitHub開源的項目elasticsearch-head,能連接配接上ElasticSearch叢集并以可視化的界面呈現資訊。

該項目不僅提供了前端項目連接配接ElasticSearch的方式,也提供了Chrome插件方式,我們此處用Chrome插件方式即可。

插件下載下傳位址是https://raw.githubusercontent.com/mobz/elasticsearch-head/master/crx/es-head.crx

為了能夠臨時解析通路該位址,需要在

C:\Windows\System32\drivers\etc\hosts

檔案添加如下内容,添加後就可以下載下傳了。

199.232.28.133  raw.githubusercontent.com
           

然後解壓檔案

es-head.crx

ElasticSearch 介紹、安裝及簡單使用

打開Chrome浏覽器的擴充程式頁面

chrome://extensions/

并選擇剛剛解壓的檔案夾

es-head

ElasticSearch 介紹、安裝及簡單使用

會出現如下圖的插件

ElasticSearch 介紹、安裝及簡單使用

點選紅框按鈕即可

ElasticSearch 介紹、安裝及簡單使用

在輸入框輸入ElasticSearch的HTTP通路位址,點選連接配接看到如下圖即為正常

ElasticSearch 介紹、安裝及簡單使用

Kibana安裝

  • 解壓檔案

    将檔案放到

    /usr/local/src/packages/es

    目錄下
ElasticSearch 介紹、安裝及簡單使用

解壓檔案并建立軟連接配接

cd /usr/local/src
tar zxPvf packages/es/kibana-7.6.1-linux-x86_64.tar.gz
ln -s kibana-7.6.1-linux-x86_64 kibana
           
  • 賦予權限
chown -R es:es /usr/local/src/kibana-7.6.1-linux-x86_64
chown -R es:es /usr/local/src/kibana
           
  • 修改配置檔案

    /usr/local/src/kibana-7.6.1-linux-x86_64/config/kibana.yml

server.host: "master"
elasticsearch.hosts: ["http://master:9200"]
i18n.locale: "zh-CN"
           
  • 啟動Kibana,預設端口是

    5601

cd /usr/local/src/kibana-7.6.1-linux-x86_64/bin
./kibana
           
  • 在浏覽器上輸入

    http://master:5601/

    ElasticSearch 介紹、安裝及簡單使用
    ElasticSearch 介紹、安裝及簡單使用
    同時也能在ElasticSearch Head插件看到Kibana自己的索引,如下圖
    ElasticSearch 介紹、安裝及簡單使用

ElasticSearch增删改查

新增文檔(Index API)

新增文檔有兩種方式

  • PUT /<index>/_doc/<_id>

  • POST /<index>/_doc/

<index>

必須傳入,如果索引不存在預設情況下會自動建立索引

<_id>

是可選的,如果用

PUT

方法必須要傳入

<_id>

,如果用

POST

方法則會自動生成ID

GET /student/_search
{
  "query": {
    "match_all": {}
  }
}

PUT /student/_doc/1
{
  "name": "jackie",
  "age": 26,
  "school": "ShenZhen University",
  "desc": "技術宅, 動漫愛好者, 大資料"
}


POST /student/_doc
{
  "name": "marry",
  "age": 27,
  "sex": "girl",
  "desc": "可愛的女生"
}
           
ElasticSearch 介紹、安裝及簡單使用
ElasticSearch 介紹、安裝及簡單使用

我們可以在ElasticSearch Head插件裡查詢到剛剛插入的資料

ElasticSearch 介紹、安裝及簡單使用

修改文檔(Update API)

POST /<index>/_update/<_id>

可用于更新該文檔的指定字段内容,若想全部更新則可以使用上面提到的

PUT

方法

POST /student/_update/1
{
  "doc": {
    "sex": "boy",
    "age": "28"
  }
}
           
ElasticSearch 介紹、安裝及簡單使用

查詢文檔(Get API)

GET <index>/_doc/<_id>

GET /student/_doc/1
           
ElasticSearch 介紹、安裝及簡單使用

删除文檔(Delete API)

DELETE /<index>/_doc/<_id>

DELETE /student/_doc/1
           
ElasticSearch 介紹、安裝及簡單使用

批量操作(Bulk API)

BULK API

就是在單個API調用中執行多個

Index

Create

Delete

Update

操作,減少了開銷,大大提高了索引速度。

但是單個API中到底執行多少個Action性能最好需要根據叢集的配置來實驗優化選擇合适的Action數。

POST _bulk
{ "index" : { "_index" : "test", "_id" : "1" } }
{ "field1" : "value1" }
{ "delete" : { "_index" : "test", "_id" : "2" } }
{ "create" : { "_index" : "test", "_id" : "3" } }
{ "field1" : "value3" }
{ "update" : {"_id" : "1", "_index" : "test"} }
{ "doc" : {"field2" : "value2"} }
           

請求格式如下

POST /_bulk

POST /<index>/_bulk
           

資料格式如下

action_and_meta_data\n
optional_source\n
action_and_meta_data\n
optional_source\n
....
action_and_meta_data\n
optional_source\n
           
  • Index

    Create

    操作期望下一行就是

    source

    内容。如果文檔

    document

    已存在那麼

    Create

    會報錯,

    Index

    則會根據需要更新或添加一個

    document

  • Update

    操作期望下一行是

    partial doc, upsert, and script and its options

  • Delete

    操作下一行無内容即可。

如批量插入資料

由于我指定了往

lol

這個索引插入資料,是以

action_and_meta_data

沒有顯示指定索引

POST /lol/_bulk
{"index":{"_id": "1"}}
{"heroId":1,"name":"黑暗之女","alias":"Annie","title":"安妮","roles":["mage"],"attack":2,"magic":10,"difficulty":6,"goldPrice":4800,"couponPrice":2000,"keywords":["安妮","黑暗之女","火女","Annie","anni","heianzhinv","huonv","an","hazn","hn"]}
{"index":{"_id": "2"}}
{"heroId":2,"name":"狂戰士","alias":"Olaf","title":"奧拉夫","roles":["fighter","tank"],"attack":9,"magic":3,"difficulty":3,"goldPrice":1350,"couponPrice":1500,"keywords":["狂戰士","奧拉夫","kzs","alf","Olaf","kuangzhanshi","aolafu"]}
{"index":{"_id": "3"}}
{"heroId":3,"name":"正義巨像","alias":"Galio","title":"加裡奧","roles":["tank","mage"],"attack":1,"magic":6,"difficulty":5,"goldPrice":3150,"couponPrice":2000,"keywords":["正義巨像","加裡奧","Galio","jla","zyjx","zhengyijuxiang","jialiao"]}
{"index":{"_id": "4"}}
{"heroId":4,"name":"卡牌大師","alias":"TwistedFate","title":"崔斯特","roles":["mage"],"attack":6,"magic":6,"difficulty":9,"goldPrice":4800,"couponPrice":3000,"keywords":["卡牌大師","崔斯特","卡牌","TwistedFate","kp","cst","kpds","kapaidashi","cuisite","kapai"]}
{"index":{"_id": "5"}}
{"heroId":5,"name":"德邦總管","alias":"XinZhao","title":"趙信","roles":["fighter","assassin"],"attack":8,"magic":3,"difficulty":2,"goldPrice":3150,"couponPrice":2500,"keywords":["德邦總管","德邦","趙信","XinZhao","db","dbzg","zx","debangzongguan","debang","zhaoxin"]}
           

如批量删除資料

由于我的API裡沒有顯示指定索引,是以在

action_and_meta_data

必須要顯示指定哪個索引

POST /_bulk
{"delete":{"_index": "lol", "_id": "1"}}
{"delete":{"_index": "lol", "_id": "2"}}
{"delete":{"_index": "lol", "_id": "3"}}
{"delete":{"_index": "lol", "_id": "4"}}
{"delete":{"_index": "lol", "_id": "5"}}
           

如批量更新資料

POST /lol/_bulk
{"update":{"_id": "1"}}
{"doc": {"age": 11}}
{"update":{"_id": "2"}}
{"doc": {"age": 12}}
{"update":{"_id": "3"}}
{"doc": {"age": 13}}
           

當然批量操作的Action類型是可以混用的。

普通插入的

Curl

語句如下,需要指定請求頭

Content-Type: application/json

但是批量操作如果用

Curl

的方式,則必須将請求資料存入檔案,指定請求頭

Content-Type: application/x-ndjson

,然後使用

--data-binary "@filename"

指定資料檔案。如下所示

ElasticSearch 介紹、安裝及簡單使用

根據多個文檔ID擷取文檔(Multi Get API)

Multi Get API

可以根據多個文檔ID批量擷取文檔資料。既可以檢索多個索引的多個文檔,也可以檢索單個索引的多個文檔。

API請求格式如下。

GET /_mget

GET /<index>/_mget
           

請求體參數如下圖

ElasticSearch 介紹、安裝及簡單使用

下面就是通過

/_mget

API批量擷取文檔的例子

GET /lol/_mget
{
  "ids": ["1","2","3"]
}

# 隻想擷取指定字段
GET /lol/_mget
{
  "docs": [
    {
    "_id": "1",
    "_source": {
      "include": ["name", "age"]  
    }
  },
  {
    "_id": "2",
    "_source": {
      "include": ["name", "age"]  
    }
  },
  {
    "_id": "5",
    "_source": {
      "include": ["name", "age"]  
    }
  }
 ]
}

GET /lol/_mget
{
  "docs": [
    {
    "_id": "1",
    "_source": ["name", "age"]
  },
  {
    "_id": "2",
    "_source": ["name", "age"]
  },
  {
    "_id": "5",
    "_source": ["name", "age"]
  }
 ]
}
           

ES中文分詞器

内置的标準分詞器standard

我們以

中華人民共和國國歌

為例進行分詞

# 預設分詞器
# standard  whitespace
POST /_analyze
{
  "text": "中華人民共和國國歌",
  "tokenizer": "standard"
}
           

如下圖所示,将每個漢字當成了一個

token

ElasticSearch 介紹、安裝及簡單使用
ElasticSearch 介紹、安裝及簡單使用

IK分詞器

  • 安裝

該項目elasticsearch-analysis-ik已在GitHub開源。

由于我們的ElasticSearch版本是7.6.1,是以也需要下載下傳對應版本的IK分詞器。

安裝步驟很簡單,将下載下傳好的

elasticsearch-analysis-ik-7.6.1.zip

放到

/usr/local/src/packages/es

目錄下,将解壓到

es-home/plugins/ik

檔案夾後重新開機ES即可。

# 在ES的HOME/plugins下建立ik檔案夾
su - es
mkdir -p /usr/local/src/elasticsearch-7.6.1/plugins/ik
# 将IK分詞器壓縮包解壓到/usr/local/src/elasticsearch-7.6.1/plugins/ik
su - root
cd /usr/local/src/packages/es
unzip elasticsearch-analysis-ik-7.6.1.zip -d /usr/local/src/elasticsearch-7.6.1/plugins/ik
chown -R es:es /usr/local/src/elasticsearch-7.6.1/plugins/ik
           

啟動會看到如下加載了插件

loaded plugin [analysis-ik]

的日志

ElasticSearch 介紹、安裝及簡單使用
  • ik_max_word 分詞
# ik_max_word即最細粒度分詞器,窮盡可能
POST /_analyze
{
  "text": "中華人民共和國國歌",
  "tokenizer": "ik_max_word"
}
           
ElasticSearch 介紹、安裝及簡單使用
ElasticSearch 介紹、安裝及簡單使用
  • ik_smart 分詞
# ik_smart即最粗粒度分詞器
POST /_analyze
{
  "text": "中華人民共和國國歌",
  "tokenizer": "ik_smart"
}
           
ElasticSearch 介紹、安裝及簡單使用
  • ik_max_word 和 ik_smart 什麼差別?
ik_max_word: 會将文本做最細粒度的拆分,比如會将“中華人民共和國國歌”拆分為“中華人民共和國,中華人民,中華,華人,人民共和國,人民,人,民,共和國,共和,和,國國,國歌”,會窮盡各種可能的組合,适合 Term Query;

ik_smart: 會做最粗粒度的拆分,比如會将“中華人民共和國國歌”拆分為“中華人民共和國,國歌”,适合 Phrase 查詢。
           
  • 自定義詞典

    我們以

    聖槍遊俠盧錫安

    為例進行分詞,我想得到兩個

    token

    聖槍遊俠

    盧錫安

    ,但是

    ik_max_word

    ik_smart

    都無法得到我想要的結果,是以需要自定義詞典。
  1. 修改配置檔案

    ES-HOME/plugins/ik/config/IKAnalyzer.cfg.xml

    添加了兩個詞典檔案

    custom/my.dic

    custom/lol.dic

    (編碼格式必須是

    UTF-8

    )
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE properties SYSTEM "http://java.sun.com/dtd/properties.dtd">
<properties>
        <comment>IK Analyzer 擴充配置</comment>
        <!--使用者可以在這裡配置自己的擴充字典 -->
        <entry key="ext_dict">custom/my.dic;custom/lol.dic</entry>
         <!--使用者可以在這裡配置自己的擴充停止詞字典-->
        <entry key="ext_stopwords"></entry>
        <!--使用者可以在這裡配置遠端擴充字典 -->
        <!-- <entry key="remote_ext_dict">words_location</entry> -->
        <!--使用者可以在這裡配置遠端擴充停止詞字典-->
        <!-- <entry key="remote_ext_stopwords">words_location</entry> -->
</properties>

           
  1. 在自定義詞典

    custom/lol.dic

    中添加

    token

    ElasticSearch 介紹、安裝及簡單使用
  2. 驗證結果
    ElasticSearch 介紹、安裝及簡單使用
    ElasticSearch 介紹、安裝及簡單使用

問題

單機情況下增加索引叢集健康狀态是yellow

在增加

test

索引後叢集狀态是

yellow

POST /test/_doc
{
  "name": "marry",
  "age": 27,
  "sex": "girl",
  "desc": "可愛的女生"
}
           
ElasticSearch 介紹、安裝及簡單使用

這是因為預設自動建立的索引

number_of_replicas=1

即預設副本數為1

ElasticSearch 介紹、安裝及簡單使用

由于此處是單機不需要副本,可以通過AP将該索引副本數設定為0即可

# 設定索引的副本數為0
PUT /test/_settings
{
  "number_of_replicas": "0"
}
           
ElasticSearch 介紹、安裝及簡單使用

參考網址

ElasticSearch7.6官網文檔

ElasticSearch與Solr對比

ElasticSearch反向索引結構分析

狂神說ES教程

ElasticSearch在Linux上安裝遇到的問題

ElasticSearch中文分詞器

ElasticSearch官網client API

繼續閱讀