簡介
Elasticsearch 是一個以 Apache Lucene 為核心,分散式的 RESTful 風格的搜尋和數據分析引擎。它是以 JSON 的形式儲存資料,並提供即時的分析及搜尋。
Kibana 將 Elasticsearch 中的資料以視覺化的方式呈現,並提供操作 Elastic Stack 的 UI 介面。
ik analyzer 是一個 Elasticsearch 的中文分詞 plugin,由於 Elasticsearch 預設對於中文的分詞是一個字一個字切割,沒有分詞的話,中文搜尋的效果會比較差,所以我們需要加上中文分詞的 plugin, 讓搜尋的結果更好。
基本概念
Elasticsearch 和一般 RDBMS 的架構不同,所以在名詞上也不一樣,以下表格是 MySQL 和 Elasticsearch 名詞的對應關係:
MySQL | Elasticsearch |
---|---|
Server | Node |
Database | Index |
Table | Type |
Row | Document |
Column | Field |
在 Elasticsearch 中,Index 的名稱必須是小寫,而同一個 Index、同一個 Type 中的每筆 record 的資料欄位不需要相同 (NoSQL的概念)。另外,根據此文章,在 Elasticsearch 6.x 版只允許每個 Index 包含一個 Type,在 7.x 版將會完全移除 Type.
安裝及設定
安裝&設定 Elasticsearch
在安裝 Elasticsearch 之前,需要先安裝 Java 環境:
1 | $ sudo apt-get update |
安裝完 Java 後,就可以來安裝 Elasticsearch, 直接下載並解壓縮即可:
1 | $ wget https://artifacts.elastic.co/downloads/elasticsearch/elasticsearch-6.7.2.tar.gz |
設定 Elasticsearch (<ES_DIR>/config/elasticsearch.yml
):
cluster name
如果有多台 Elasticsearch node 要加入 cluster, 則必須定義相同的 cluster name.
1 | cluster.name: cluster_name |
node.name
自訂義 node name.
1 | node.name: node1 |
bootstrap.memory_lock
設定為 true 是為了防止 swap 到 ES 的 memory.
1 | bootstrap.memory_lock: true |
network
1 | # ------------------------ Network ------------------------ |
thread_pool
可以參考 Elasticsearch官網
index
For index/delete operations. Thread pool type is fixed
with a size of # of available processors
, queue_size of 200. The maximum size of this pool is 1 + # of available processors
.
write
For single-document index/delete/update and bulk requests. Thread pool type is fixed with a size of # of available processors
, queue_size of 200. The maximum size for this pool is 1 + # of available processors
.
The size
parameter controls the number of threads, and defaults to the number of cores times 5.
1 | # Thread pool |
ps. 如果不知道機器的 available processors,可以使用 nproc
指令來查詢。
接下來修改 JVM 的設定,Elasticsearch 預設的 JVM 大小為 1GB, 如果需要調整 memory 大小,可以在 ./elasticsearch-6.7.2/config/jvm.options
做修改:
1 | # Xms represents the initial size of total heap space |
ps. Elasticsearch 最多只會使用系統的 50% memory, 且不建議設定超過 32GB.
設定好之後啟動 Elasticsearch:
1 | $ cd elasticsearch-6.7.2/bin |
啟動時可能會遇到一些問題,這裡列了目前有遇到的錯誤訊息和解決方式,如果啟動時有出現這些錯誤訊息可以參考以下解法:
vm.max_map_count 太小
Error message:1
max virtual memory areas vm.max_map_count [65530] is too low, increase to at least
解決方式: 增加
vm.max_map_count
的大小限制,vm.max_map_count
是用來限制 process 在 Virtual Memory Areas 擁有的最大數量。1
$ sudo sysctl -w vm.max_map_count=262144
無法 lock memory
Error message:1
Unable to lock JVM Memory: error=12, reason=Cannot allocate memory
解決方式: 修改
/etc/security/limits.conf
設定1
2
3# allow user 'userA' mlockall
userA soft memlock unlimited
userA hard memlock unlimited接著重新登入即可生效。
NullPointerException
Error message:1
2[ERROR][o.e.b.Bootstrap ] Exception
java.lang.NullPointerException: null解決方式: 設定 cgroup
1
2
3
4
5
6
7
8
9
10
11
12$ sudo mount -t cgroup -o rw,nosuid,nodev,noexec,relatime,cpu,cpuacct cgroup /sys/fs/cgroup/cpu,cpuacct
# 如果設定 line 1 的指令後,一樣無法啟動,請再試著設定以下內容:
# sudo mount -t cgroup -o rw,nosuid,nodev,noexec,relatime,freezer cgroup /sys/fs/cgroup/freezer
# sudo mount -t cgroup -o rw,nosuid,nodev,noexec,relatime,blkio cgroup /sys/fs/cgroup/blkio
# sudo mount -t cgroup -o rw,nosuid,nodev,noexec,relatime,hugetlb cgroup /sys/fs/cgroup/hugetlb
# sudo mount -t cgroup -o rw,nosuid,nodev,noexec,relatime,devices cgroup /sys/fs/cgroup/devices
# sudo mount -t cgroup -o rw,nosuid,nodev,noexec,relatime,net_cls,net_prio cgroup /sys/fs/cgroup/net_cls,net_prio
# sudo mount -t cgroup -o rw,nosuid,nodev,noexec,relatime,cpuset cgroup /sys/fs/cgroup/cpuset
# sudo mount -t cgroup -o rw,nosuid,nodev,noexec,relatime,memory cgroup /sys/fs/cgroup/memory
# sudo mount -t cgroup -o rw,nosuid,nodev,noexec,relatime,pids cgroup /sys/fs/cgroup/pids
# sudo mount -t cgroup -o rw,nosuid,nodev,noexec,relatime,perf_event cgroup /sys/fs/cgroup/perf_event
安裝&設定 ik analyzer
參考 ik analyzer, 使用 elasticsearch-plugin 安裝 ik analyzer:
1 | $ ./bin/elasticsearch-plugin install https://github.com/medcl/elasticsearch-analysis-ik/releases/download/v6.7.2/elasticsearch-analysis-ik-6.7.2.zip |
NOTE: 將 6.7.2
替換為所使用的 Elasticsearch 版本。
接著設定 Dictionary, 可以準備自定義的字典檔讓搜尋效果更好, 字典及設定檔可以放在 <ES_DIR>/config/analysis-ik/
或是 <ES_DIR>/plugins/analysis-ik/config/
底下,再來在 IKAnalyzer.cfg.xml
設定使用自定義的字典:
1 |
|
最後重新啟動 Elasticsearch 就可以使用 ik analyzer.
安裝&設定 Kibana
直接從 Kibana 網站中下載並解壓縮:
1 | $ wget https://artifacts.elastic.co/downloads/kibana/kibana-6.7.2-linux-x86_64.tar.gz |
設定 <KIBANA_DIR>/config/kibana.yml
:
1 | # Kibana host and port |
執行 Kibana:
1 | $ ./bin/kibana |
啟動 Kibana 之後,開啟瀏覽器進入: http://localhost:5601
,如果有正常連線到 Elasticsearch 就會看到以下畫面:
操作 Elasticsearch
設定 Mapping
在建立索引之前,要先設定 Index 的 mapping,設定資料欄位的 datatype, format, analyzer 等等,讓搜尋效果可以更好,詳細的 Mapping 設定方式可以參考官方文件,這裡範例是指定資料欄位使用 ik analyzer:
1 | $ curl -XPOST 'http://localhost:9200/index/type/_mapping' -H 'Content-Type:application/json' -d' |
設定回傳的資料量限制
Elasticsearch 預設的 from + size 最多為 10000, 如果需要增加大小,需要修改以下設定:
1 | $ curl -XPUT 'http://<host>:<port>/<index>/_settings' -d' |
但是有可能會占用更多記憶體,所以要小心設定。
設定 Log level
當資料量大的時候,在 Elasticsearch 做全文搜尋時,CPU 使用率常常會很高,甚至到達 100%,我們可以透過設定 Log level 來減少 IO,降低 CPU 使用率:
1 | $ curl -XPUT 'http://<host>:<port>/<index>/_settings' -d' |
檢查狀態
Index 狀態
1 | $ curl -XGET http://127.0.0.1:9200/_cat/indices?v |
回傳結果:
1 | health status index uuid pri rep docs.count docs.deleted store.size pri.store.size |
- health: index 的健康狀態
- red: 資料缺損,無法使用
- yellow: 資料只有一份,沒有 shards, 如果單一節點損壞的話,無法回復
- green: 資料有 shards 的備,如果單點損壞還是可以正常檢索
- status: 是否啟用
- index: 索引名稱
- uuid: unique key
- pri: 主要 shards 數量
- rep: 備份 shards 數量
- docs.count: index 中 doc 筆數
- docs.deleted: index 中刪除的 doc 筆數
- store.size: 儲存主要和備份資料所占用的空間
- pri.store.size: 儲存主要資料所佔用的空間
線程狀態
1 | $ curl -s -XGET http://127.0.0.1:9200/_cat/thread_pool?v |
Cluster 狀態
1 | $ curl -XGET http://127.0.0.1:9200/_cat/health?v |
Node 狀態
1 | $ curl -XGET http://127.0.0.1:9200/_cat/nodes?v |
新增資料
基本的指令格式:
1 | $ curl -XPUT 'http://<host>:<port>/<index>/<type>/<doc_id>' -d ' |
其中 doc_id
不一定要有,如果沒有指定 doc_id
, HTTP request method 需使用 POST
. For example:
1 | # 指定 doc_id |
查詢資料 (By doc_id)
基本指令格式:
1 | $ curl 'http://<host>:<port>/<index>/<type>/<doc_id>?pretty=true |
其中 URL 參數 pretty=true
代表以方便讀取的格式回傳, for example:
1 | $ curl 'http://localhost:9200/index/type/1?pretty=true' |
回傳結果:
1 | { |
刪除資料
使用 DELETE
method, for example:
1 | $ curl -XDELETE 'http://localhost:9200/index/type/1' |
也可以直接刪除 Index 中的所有資料:
1 | $ curl -XDELETE 'http://localhost:9200/index' |
更新資料
使用 PUT
method, 重新發送一次 request 即可:
1 | $ curl -XPUT http://localhost:9200/index/type/1 -H 'Content-Type:application/json' -d' |
回傳結果:
1 | { |
我們可以看到回傳的結果中 _version
是 2, result
為 updated
, 代表是更新資料而不是新增資料。
搜尋
使用 Elasticsearch 最重要的就是搜尋的功能,我們使用它所提供的 Search API 來搜尋:
取得所有紀錄
使用 GET
method, 後面加上 _search
:
1 | $ curl 'http://localhost:9200/index/type/_search' |
回傳結果:
1 | { |
全文搜尋
Elasticsearch 有自己的查詢語法,詳細可以參考 Query DSL, 這裡的範例是搜尋 美國
並將比對到的地方 highlight:
1 | $ curl 'localhost:9200/index/type/_search' -d ' |
搜尋結果:
1 | { |
備份
Elasticsearch 的備份,可以參考由 taskrabbit 開發的 elasticsearch-dump 工具來做資料的備份及轉移。
操作 Kibana
由於從 cmd 操作 Elasticsearch 比較難閱讀,Kibana 提供漂亮的介面,讓我們可以更方便地操作 Elasticsearch, 並將 Elasticsearch 中的資料以視覺化的方式呈現,這裡我們簡單介紹一下 Kibana 的使用方式。
一進到 Kibana 頁面,我們可以看到左側主選單有以下幾個功能:
- Discover: 檢視每個索引下的紀錄筆數和內容。
- Visualize: 將搜尋結果是以視覺化的圖表呈現,並可以將搜尋結果或圖表儲存。
- Dashboard: 組合多個已儲存的圖表或搜尋結果,方便一次瀏覽所有資訊。
- Dev Tools: 是一個方便的除錯測試工具,可以在 Console 輸入指令直接操作 Elasticsearch.
- Management: 設定 Kibana 對應的 Elasticsearch index patterns, 管理已儲存的搜尋結果 object、視覺化圖表以及進階的設定。
如果是第一次使用,我們需要先到 Management 建立 Index pattern, 這樣就可以在 Discover 中搜尋特定條件的資料,並且在 Visualize 中以視覺化圖表的方式呈現,最後透過 Dashboard 組合多個搜尋結果 object 和圖表,一次瀏覽所需要的資訊。