Elasticsearch快速入門和環境搭建
- 2021 年 6 月 1 日
- 筆記
- docker, elasticsearch, Kibana
內容概述
本文內容主要集中在應用層,通過下面幾個部分介紹當前最流行的搜索工具: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官方倉庫拉取鏡像會很慢,所以在安裝完成後,需要在設置中將倉庫的地址替換為國內源,這裡推薦//docker.mirrors.ustc.edu.cn
,速度很快,設置如下:
{
"registry-mirrors": [
"//docker.mirrors.ustc.edu.cn"
]
}
下面我們使用docker安裝Elasticsearch
和kibana
鏡像,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實例,分別是elasticsearch
和kibana
。
在本地瀏覽器中,訪問//127.0.0.1:5601/
,可以看到kibana
的界面如下:
創建好的kibana
已經默認添加了Elasticsearch
的配置,通過管理工具可以很方便的查看ES集群的狀態,索引情況,刪除索引等。
下面通過dev tools
創建索引,dev tools
提供的命令提示很方便,並且可以把已寫好的請求保存在瀏覽器緩存中,非常適合用來學習Elasticsearch
。
這裡通過ES提供的RESTful Api
創建了第一個索引, 並且設置了該索引中的mapping
,ES的地址已經設置過,這裡可以不寫完整的域名,對應的curl完整請求如下:
curl --location --request PUT '//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,這些例子都是直接在kibana
的dev 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
會被分詞為call
,aaa
和service
,所有包含這三個詞的文檔都會被搜索出來,例如下面:
//普通搜索,兩個文檔都會返回
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"
}
}
}
那如果條件是包含call
,aaa
和service
,但是不一定是連着的,該如何搜索呢?可以使用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。
以上內容屬個人學習總結,如有不當之處,歡迎在評論中指正