Elk環境篇 --- 本地快速搭建你的ElasticSearch及Kibana

說出你的願望吧發表於2020-04-04

前言

ELK的基本介紹

ELK是三個軟體產品的首字母縮寫,Elasticsearch,Logstash 和 Kibana。這三款軟體都是開源軟體,通常是配合使用,而且又先後歸於 Elastic.co 公司名下,故被簡稱為 ELK 協議棧

左邊我們部署了多臺伺服器,然後我們通過logstash來採集資料,採集完成我們傳送到ES叢集中存起來,然後通過Kibana去展示到我們的瀏覽器中,就是這麼一個簡單的套路

Elasticsearch是個開源分散式搜尋引擎,它的特點有:開箱即用,分散式,零配置,自動發現,索引自動分片,索引副本機制,RESTful風格介面,多資料來源,自動搜尋負載等。

Logstash是一個完全開源的工具,他可以對你的日誌進行收集、過濾,並將其儲存供以後使用(比如供ES來進行搜尋)。

Kibana 也是一個開源和免費的工具,它Kibana可以為 Logstash 和 ElasticSearch 提供的日誌分析友好的 Web 介面,可以幫助您彙總、分析和搜尋重要資料日誌。

ELK的實現介紹

ELK 實現語言 簡介
ElasticSearch Java 實時的分散式搜尋和分析引擎,可用於全文檢索,結構化搜尋以及分析,基層基於Lucene。類似於Solr
Logstash JRuby 具有實時渠道能力的資料收集引擎,包含輸入、過濾、輸出模組,一般在過濾模組中做日誌格式化的解析工作
Kibana JavaScript 為ElasticSerach提供分析平臺和視覺化的Web平臺。他可以ElasticSerach的索引中查詢,呼喚資料,並生成各種維度的表圖

ELK的參考資料

ELK官網:https://www.elastic.co/

ELK官網文件:https://www.elastic.co/guide/index.html

ELK中文手冊:https://www.elastic.co/guide/cn/elasticsearch/guide/current/index.html

ELK中文社群:https://elasticsearch.cn/

一、Elasticsearch的部署

1.1 簡介

ElaticSearch,簡稱為ES, ES是一個開源的高擴充套件的分散式全文檢索引擎,它可以近乎實時的儲存、檢索資料;本身擴充套件性很好,可以擴充套件到上百臺伺服器,處理PB級別的資料。ES也使用Java開發並使用Lucene作為其核心來實現所有索引和搜尋的功能,但是它的目的是通過簡單的RESTful API來隱藏Lucene的複雜性,從而讓全文搜尋變得簡單。

下面是搜尋引擎提供的一些使用的案例

GayHub

2013年初,GitHub拋棄了Solr,採取ElasticSearch 來做PB級的搜尋。它使用ElasticSearch搜尋20TB的資料,包括13億檔案和1300億行程式碼”
複製程式碼

Wiki
維基百科:啟動以elasticsearch為基礎的核心搜尋架構

SoundCloud

SoundCloud使用ElasticSearch為1.8億使用者提供即時而精準的音樂搜尋服務
複製程式碼

Baidu

百度目前廣泛使用ElasticSearch作為文字資料分析,採集百度所有伺服器上的各類指標資料及使用者自定義資料,通過對各種資料進行多維分析展示,輔助定位分析例項異常或業務層面異常。目前覆蓋百度內部20多個業務線(包括Casio、雲分析、網盟、預測、文庫、直達號、錢包、風控等),單叢集最大100臺機器,200個ES節點,每天匯入30TB+資料
複製程式碼

Sina:使用ElasticSearch分析處理32億條實時日誌

Alibaba:使用ElasticSearch構建挖財自己的日誌採集和分析體系

1.2 使用準備

我把我用到的安裝包都上傳到百度雲了,有需要的可以自提,避免網路的尷尬?

連結:https://pan.baidu.com/s/17m0LmmRcffQbfhjSikIHhA 
提取碼:l1lj 
複製程式碼

首先我們得注意的是,ES是不能通過root使用者來進行啟動的,必須通過普通使用者來安裝啟動,這裡我們使用一個新建的使用者

解決方案也可以直接參考這個 https://www.cnblogs.com/gcgc/p/10297563.html

首先是下安裝包,然後再解壓一下即可,操作比較簡單這裡就不說明了

之後我們建立兩個資料夾,都在ES的目錄下建立即可

mkdir -p /usr/local/elasticsearch-6.7.0/logs/
mkdir -p /usr/local/elasticsearch-6.7.0/datas
複製程式碼

就是建立了一個資料檔案和一個日誌的儲存資料夾而已

之後修改一下配置檔案,在config資料夾中 vim elasticsearch.yml

cluster.name: myes
node.name: node3
path.data: 自己的安裝路徑/elasticsearch-6.7.0/datas
path.logs: 自己的安裝路徑/elasticsearch-6.7.0/logs
network.host: 自己節點的地址
http.port: 9200
discovery.zen.ping.unicast.hosts: ["node1""node2""node3"]
bootstrap.system_call_filter: false
bootstrap.memory_lock: false
http.cors.enabled: true
http.cors.allow-origin: "*"

cluster.name --- 叢集的名字,預設ElasticSearch
node.name --- 節點名
path.data --- 資料檔案存放路徑
path.logs --- 日誌檔案存放路徑
http.port --- 訪問埠號
discovery.zen.ping.unicast.hosts: 叢集自動發現功能
bootstrap.system_call_filter: 
bootstrap.memory_lock: false
http.cors.enabled: true
http.cors.allow-origin: "*"
複製程式碼

這裡要注意path.data 和 path.logs記得路徑前要/,比如我的就是 path.data: /usr/local/elasticsearch-6.7.0/datas,當然大家都是聰明的孩子,估計是不會忘的

我們還可以設定一下最大和最小堆記憶體,在jvm.option配置檔案中,修改完之後分發到另外的節點上去即可,當然另外兩個節點的那個配置檔案也是按照上方的套路去改就好了。

cd /usr/local
scp -r elasticsearch-6.7.0/ node2:$PWD
scp -r elasticsearch-6.7.0/ node3:$PWD
複製程式碼

由於我的前兩臺虛擬機器不知道咋地就崩掉了,本身自己的電腦記憶體就不足。所以我就單節點了?

1.3 修改一些系統配置

1.3.1 普通使用者開啟檔案的最大數限制

問題錯誤資訊描述:

max file descriptors [4096for elasticsearch process likely too low, increase to at least [65536]
複製程式碼

解決方案:解除普通使用者開啟檔案的最大數限制,不然ES啟動時可能會報錯

sudo vi /etc/security/limits.conf

soft nofile 65536
hard nofile 131072
soft nproc 2048
hard nproc 4096
複製程式碼

這四行貼上上去即可

1.3.2 普通使用者啟動執行緒數限制

sudo vi /etc/sysctl.conf

新增下面兩行
vm.max_map_count=655360
fs.file-max=655360
複製程式碼

執行 sudo sysctl -p,使得配置生效

注意:以上兩個問題修改完成之後,一定要重新連線linux生效。關閉secureCRT或者XShell工具,然後重新開啟工具連線linux即可

1.3.3 重新連線工具後的行動

執行下面4個命令,沒問題即可

[hadoop@node01 ~]$ ulimit -Hn
131072
[hadoop@node01 ~]$ ulimit -Sn
65536
[hadoop@node01 ~]$ ulimit -Hu
4096
[hadoop@node01 ~]$ ulimit -Su
4096
複製程式碼

1.3.4 啟動ES叢集

nohup /usr/local/elasticsearch-6.7.0/bin/elasticsearch 2>&1 &
複製程式碼

啟動成功之後jsp即可看到es的服務程式,並且訪問頁面

http://node3:9200/?pretty
複製程式碼

注意:如果哪一臺機器服務啟動失敗,那麼就到哪一臺機器的logs去檢視錯誤日誌即可

出現這個頁面,就是已經啟動了,非常醜陋

1.3.5 elasticsearch-head外掛

由於es服務啟動之後,訪問介面比較醜陋,為了更好的檢視索引庫當中的資訊,我們可以通過安裝elasticsearch-head這個外掛來實現,這個外掛可以更方便快捷的看到es的管理介面

首先安裝一下node.js

1.3.6 Node.js

Node.js是一個基於 Chrome V8 引擎的 JavaScript 執行環境。

Node.js是一個Javascript執行環境(runtime environment),釋出於2009年5月,由Ryan Dahl開發,實質是對Chrome V8引擎進行了封裝。Node.js 不是一個 JavaScript 框架,不同於CakePHP、Django、Rails。Node.js 更不是瀏覽器端的庫,不能與 jQuery、ExtJS 相提並論。Node.js 是一個讓 JavaScript 執行在服務端的開發平臺,它讓 JavaScript 成為與PHP、Python、Perl、Ruby 等服務端語言平起平坐的指令碼語言。

安裝步驟參考:https://www.cnblogs.com/kevingrace/p/8990169.html

下載好安裝包之後,我們解壓,進行些配置即可

sudo ln -s /usr/local/node-v8.1.0-linux-x64/lib/node_modules/npm/bin/npm-cli.js /usr/local/bin/npm
sudo ln -s /usr/local/node-v8.1.0-linux-x64/bin/node /usr/local/bin/node
複製程式碼

然後修改環境變數

sudo vim .bash_profile

export NODE_HOME=/usr/local/node-v8.1.0-linux-x64
export PATH=:$PATH:$NODE_HOME/bin
複製程式碼

然後source一下

出現以上的這個node和npm的版本即可

1.3.7 elasticsearch-head外掛的安裝

線上安裝的話不太推薦,因為大家的網速都(你懂的),當然像我這種提前準備好了安裝包的就不一樣了

這時候我們把它解壓,然後修改一下Gruntfile.js

cd /usr/local/elasticsearch-head
vim Gruntfile.js
複製程式碼

你可以直接先shift+:,轉到命令模式,使用/hostname來找到這個引數,hostname: '你自己的節點ip'

之後

cd /usr/local/elasticsearch-head/_site
vim app.js
複製程式碼

和上面同樣的套路,先找http://這個關鍵字,然後把localhost改成自己的節點ip

之後我們就可以開啟服務了

cd /usr/local/elasticsearch-head/node_modules/grunt/bin/
nohup ./grunt server >/dev/null 2>&1 &
複製程式碼

之後訪問 http://你的節點ip:9100/即可訪問,當然也是一個好看不到哪去的頁面,還有就是,我這裡有兩個虛擬機器傻了,所以沒辦法就啟動了個單節點的

1.3.8 如何關閉

執行以下命令找到elasticsearch-head的外掛程式,然後使用kill -9 殺死程式即可

sudo yum install net-tools     
netstat -nltp | grep 9100
kill -9 88297
複製程式碼

1.3.9 Kibana的安裝

這個東西基本就是解壓就能用了

先準備個安裝包,然後解壓出來

cd /usr/local/kibana-6.7.0-linux-x86_64/config/
vi kibana.yml


配置內容如下:
server.host: "node3"
elasticsearch.hosts: ["http://node3:9200"]
複製程式碼

然後我們就可以開始啟動了

cd /usr/local/kibana-6.7.0-linux-x86_64
nohup bin/kibana >/dev/null 2>&1 &
複製程式碼

這種時候需要的就是等待即可

額,我們再等一小下?

這裡說它通知你你的叢集裡面啥資料都沒有,這時候隨便點第一個就是了

這種時候就算是安裝完成了。之後我們的互動方式就是DEV tools---開發者工具那裡去進行和ES的互動

二、簡單操作一下ElasticSearch

2.1 ES的一些概念

我們使用傳統的關係型資料庫來類比一下

Relational DB -> Databases -> Tables -> Rows -> Columns
Elasticsearch -> Indices   -> Types  -> Documents -> Fields
複製程式碼

我們平時接觸的比如MySQL,它是不是有多個資料庫,每個資料庫中有多張表table,每張表都有很多條資料Rows,然後資料又有欄位 Columns

而一個ES下面有很多個索引庫Indices,而它下面又有很多的Types,類似於table的東西,每一條資料都是documents,然後欄位就是Fields

2.2 一些專有名詞的解釋

2.2.1、索引 index

一個索引就是一個擁有幾分相似特徵的文件的集合。比如說,你可以有一個客戶資料的索引,另一個產品目錄的索引,還有一個訂單資料的索引。一個索引由一個名字來標識(必須全部是小寫字母的),並且當我們要對對應於這個索引中的文件進行索引、搜尋、更新和刪除的時候,都要使用到這個名字。在一個叢集中,可以定義任意多的索引。

2.2.2、型別 type

在一個索引中,你可以定義一種或多種型別。一個型別是你的索引的一個邏輯上的分類/分割槽,其語義完全由我們來定。通常,會為具有一組共同欄位的文件定義一個型別。比如說,我們假設你運營一個部落格平臺並且將你所有的資料儲存到一個索引中。在這個索引中,你可以為使用者資料定義一個型別,為部落格資料定義另一個型別,當然,也可以為評論資料定義另一個型別。

2.2.3、欄位Field

相當於是資料表的欄位,對文件資料根據不同屬性進行的分類標識

2.2.4、對映 mapping

其實就是類似於JavaBean一樣的東西。mapping是處理資料的方式和規則方面做一些限制,如某個欄位的資料型別、預設值、分析器、是否被索引等等,這些都是對映裡面可以設定的,其它就是處理es裡面資料的一些使用規則設定也叫做對映,按著最優規則處理資料對效能提高很大,因此才需要建立對映,並且需要思考如何建立對映才能對效能更好。

2.2.5、文件 document

一個文件是一個可被索引的基礎資訊單元。比如,你可以擁有某一個客戶的文件,某一個產品的一個文件,當然,也可以擁有某個訂單的一個文件。文件以JSON(Javascript Object Notation)格式來表示,而JSON是一個到處存在的網際網路資料互動格式。
在一個index/type裡面,你可以儲存任意多的文件。注意,儘管一個文件,物理上存在於一個索引之中,文件必須被索引/賦予一個索引的type。

2.2.6、接近實時 NRT

Elasticsearch是一個接近實時的搜尋平臺。這意味著,從索引一個文件直到這個文件能夠被搜尋到有一個輕微的延遲(通常是1秒以內)

2.2.7、分片和副本 shards & replicas

一個索引可以儲存超出單個結點硬體限制的大量資料。比如,一個具有10億文件的索引佔據1TB的磁碟空間,而任一節點都沒有這樣大的磁碟空間;或者單個節點處理搜尋請求,響應太慢。為了解決這個問題,Elasticsearch提供了將索引劃分成多份的能力,這些份就叫做分片。當你建立一個索引的時候,你可以指定你想要的分片的數量。每個分片本身也是一個功能完善並且獨立的“索引”,這個“索引”可以被放置到叢集中的任何節點上。分片很重要,主要有兩方面的原因:

允許你水平分割/擴充套件你的內容容量。 
允許你在分片之上進行分散式的、並行的操作,進而提高效能/吞吐量。
複製程式碼

至於一個分片怎樣分佈,它的文件怎樣聚合回搜尋請求,是完全由Elasticsearch管理的,對於作為使用者的你來說,這些都是透明的。

在一個網路環境裡,失敗隨時都可能發生,在某個分片/節點不知怎麼的就處於離線狀態,或者由於任何原因消失了,這種情況下,有一個故障轉移機制是非常有用的。為此目的,Elasticsearch允許你建立分片的一份或多份拷貝,這些拷貝叫做 replicas,或者中文翻譯過來可能叫副本。

replicas之所以重要,有兩個主要原因:

在分片/節點失敗的情況下,提供了高可用性。因為這個原因,複製分片從不與原/主要(original/primary)分片置於同一節點上。擴充套件你的搜尋量/吞吐量,因為搜尋可以在所有的 replicas 上並行執行。總之,每個索引可以被分成多個分片。一個索引也可以被複制0次(意思是沒有複製)或多次。一旦複製了,每個索引就有了主分片(作為複製源的原來的分片)和複製分片(主分片的拷貝)之別。shards & replicas 的數量可以在索引建立的時候指定。在索引建立之後,你可以在任何時候動態地改變 replicas 的數量,但是你事後不能改變分片的數量。

預設情況下,Elasticsearch中的每個索引被分片5個主分片和1個replicas,這意味著,如果你的叢集中至少有兩個節點,你的索引將會有5個主分片和另外5個複製分片(1個完全拷貝),這樣的話每個索引總共就有10個分片。

2.2.8、一個管理工具

curl是利用URL語法在命令列方式下工作的開原始檔傳輸工具,使用curl可以簡單實現常見的get/post請求。簡單的認為是可以在命令列下面訪問url的一個工具。在centos的預設庫裡面是有curl工具的,如果沒有yum安裝即可。

yum -y install curl
複製程式碼
curl
-X 指定http的請求方法 有HEAD GET POST PUT DELETE
-d 指定要傳輸的資料
-H 指定http請求頭資訊
複製程式碼

2.3 使用 Xput建立索引

2.3.1 建立索引

此時我們的索引中是僅有Kibana預設幫我們建立的索引的

在我們的kibana的dev tools當中執行以下語句

curl -XPUT http://node3:9200/blog01/?pretty
複製程式碼

kibana會自動幫我們進行一些格式的調整

執行成功後,此時我們又能看到所謂好看的頁面了?


2.3.2 插入一條資料

curl -XPUT http://node3:9200/blog01/article/1?pretty -d  '{"id""1""title""What is ELK"}'
複製程式碼

使用 PUT 動詞將一個文件新增到 /article(文件型別),併為該文件分配 ID 為1。URL 路徑顯示為index/doctype/ID(索引/文件型別/ID)。

我們可以在資料瀏覽模組點選blog01進行檢視

如果出現問題:Content-Type header [application/x-www-form-urlencoded] is not supported

此原因時由於ES增加了安全機制, 進行嚴格的內容型別檢查,嚴格檢查內容型別也可以作為防止跨站點請求偽造攻擊的一層保護。 官網解釋

http.content_type.required

2.3.3 查詢資料

curl -XGET http://node3:9200/blog01/article/1?pretty
複製程式碼

這個命令可以在Kibana執行,也可以在叢集執行

2.3.4 更新文件

更新操作和插入基本一致,因為就是有id就更新,無id就插入,和Java那塊的操作比較像

curl -XPUT http://node3:9200/blog01/article/1?pretty -d  '{"id""1""title"" What is elasticsearch"}'
複製程式碼

圖就不貼啦,玩玩就好

2.3.5 搜尋文件

curl -XGET "http://node3:9200/blog01/article/_search?q=title:elasticsearch" 
複製程式碼

2.3.6 刪除文件及索引

刪除文件

curl -XDELETE "http://node3:9200/blog01/article/1?pretty"
複製程式碼

刪除索引

curl -XDELETE http://node3:9200/blog01?pretty
複製程式碼

執行就會刪除了,這裡我就不執行了

2.4 ES的條件查詢

這裡先模擬一些資料出來

POST /school/student/_bulk
"index": { "_id": 1 }}
"name" : "tellYourDream""age" : 25 , "sex""boy""birth""1995-01-01" , "about""i like bigdata" }
"index": { "_id": 2 }}
"name" : "guanyu""age" : 21 , "sex""boy""birth""1995-01-02" , "about""i like diaocan" }
"index": { "_id": 3 }}
"name" : "zhangfei""age" : 18 , "sex""boy""birth""1998-01-02" , "about""i like travel" }
"index": { "_id": 4 }}
"name" : "diaocan""age" : 20 , "sex""girl""birth""1996-01-02" , "about""i like travel and sport" }
"index": { "_id": 5 }}
"name" : "panjinlian""age" : 25 , "sex""girl""birth""1991-01-02" , "about""i like travel and wusong" }
"index": { "_id": 6 }}
"name" : "caocao""age" : 30 , "sex""boy""birth""1988-01-02" , "about""i like xiaoqiao" }
"index": { "_id": 7 }}
"name" : "zhaoyun""age" : 31 , "sex""boy""birth""1997-01-02" , "about""i like travel and music" }
"index": { "_id": 8 }}
"name" : "xiaoqiao""age" : 18 , "sex""girl""birth""1998-01-02" , "about""i like caocao" }
"index": { "_id": 9 }}
"name" : "daqiao""age" : 20 , "sex""girl""birth""1996-01-02" , "about""i like travel and history" }
複製程式碼

直接copy到kibana下面執行即可

此時在ES-head這邊也能看的見

2.4.1 1、使用match_all做查詢

GET /school/student/_search?pretty
{
    "query": {
        "match_all": {}
    }
}
複製程式碼

問題:通過match_all匹配後,會把所有的資料檢索出來,但是往往真正的業務需求並非要找全部的資料,而是檢索出自己想要的;並且對於es叢集來說,直接檢索全部的資料,很容易造成GC現象。所以,我們要學會如何進行高效的檢索資料

2.4.2 通過關鍵欄位進行查詢

GET /school/student/_search?pretty
{
    "query": {
         "match": {"about""travel"}
     }
}
複製程式碼

如果此時想查詢喜歡旅遊的,並且不能是男孩的,怎麼辦?
【這種方式是錯誤的,因為一個match下,不能出現多個欄位值[match] query doesn't support multiple fields】,需要使用複合查詢

2.4.3 bool的複合查詢

當出現多個查詢語句組合的時候,可以用bool來包含。bool合併聚包含:must,must_not或者should, should表示or的意思
例子:查詢非男性中喜歡旅行的人

GET /school/student/_search?pretty
{
"query": {
   "bool": {
      "must": { "match": {"about""travel"}},
      "must_not": {"match": {"sex""boy"}}
     }
  }
}
複製程式碼

2.4.4、bool的複合查詢中的should

should表示可有可無的(如果should匹配到了就展示,否則就不展示)
例子:
查詢喜歡旅行的,如果有男性的則顯示,否則不顯示

GET /school/student/_search?pretty
{
"query": {
   "bool": {
      "must": { "match": {"about""travel"}},
      "should": {"match": {"sex""boy"}}         
     }
  }
}
複製程式碼

2.4.5、term匹配

使用term進行精確匹配(比如數字,日期,布林值或 not_analyzed的字串(未經分析的文字資料型別))
語法

"term": { "age"20 }}
"term": { "date""2018-04-01" }}
"term": { "sex": “boy” }}
"term": { "about""travel" }}
複製程式碼

例子:查詢喜歡旅行的

GET /school/student/_search?pretty
{
"query": {
   "bool": {
      "must": { "term": {"about""travel"}},
      "should": {"term": {"sex""boy"}}         
     }}
}
複製程式碼

2.4.6、使用terms匹配多個值

GET /school/student/_search?pretty
{
"query": {
   "bool": {
      "must": { "terms": {"about": ["travel","history"]}}          
     }
  }
}
複製程式碼

2.4.7、Range過濾

Range過濾允許我們按照指定的範圍查詢一些資料:操作範圍:

gt: --- 大於
gae: --- 大於等於
lt: --- 小於
lte: --- 小於等於
複製程式碼

例子:查詢出大於20歲,小於等於25歲的學生

GET /school/student/_search?pretty
{
"query": {
   "range": {
    "age": {"gt":20,"lte":25}
         }
      }
}
複製程式碼

2.4.8、exists和 missing過濾

exists和missing過濾可以找到文件中是否包含某個欄位或者是沒有某個欄位

例子:
查詢欄位中包含age的文件

GET /school/student/_search?pretty
{
"query": {
   "exists": {
    "field""age"  
         }
      }
}
複製程式碼

2.4.9、bool的多條件過濾

用bool也可以像之前match一樣來過濾多行條件:

must: --- 多個查詢條件的完全匹配,相當於 and 。
must_not: --- 多個查詢條件的相反匹配,相當於 not 。
should: --- 至少有一個查詢條件匹配, 相當於 or
複製程式碼

例子:
過濾出about欄位包含travel並且年齡大於20歲小於30歲的同學

GET /school/student/_search?pretty
{
  "query": {
    "bool": {
      "must": [
        {"term": {
          "about": {
            "value""travel"
          }
        }},{"range": {
          "age": {
            "gte"20,
            "lte"30
          }
        }}
      ]
    }
  }
}
複製程式碼

2.4.10、查詢與過濾條件合併

通常複雜的查詢語句,我們也要配合過濾語句來實現快取,用filter語句就可以來實現

例子:查詢出喜歡旅行的,並且年齡是20歲的文件

GET /school/student/_search?pretty
{
  "query": {
   "bool": {
     "must": {"match": {"about""travel"}},     
     "filter": [{"term":{"age"20}}]
     }
  }
}
複製程式碼

2.5 ES 中的重要概念Mappings & Settings

Mappings主要用於定義ES中的欄位型別,在es當中,每個欄位都會有預設的型別,根據我們第一次插入資料進去,es會自動幫我們推斷欄位的型別,當然我們也可以通過設定mappings來提前自定義我們欄位的型別

DELETE  document
PUT document
{
  "mappings": {
    "article" : {
      "properties":
      {
        "title" : {"type""text"} , 
        "author" : {"type""text"} , 
        "titleScore" : {"type""double"

      }
    }
  }
}
複製程式碼

之後可以使用get document/article/_mapping來檢視

Settings 主要用於定義分片數及副本數。

DELETE document
PUT document
{
  "mappings": {
    "article" : {
      "properties":
      {
        "title" : {"type""text"} , 
        "author" : {"type""text"} , 
        "titleScore" : {"type""double"

      }
    }
  }
}

GET /document/_settings
複製程式碼

因為我的節點就只有一個,就不截圖ES-head那邊的圖了,沒啥用?

三、ES的分頁解決方案

模擬一些資料再說,直接複製上去Kibana執行即可

DELETE us
POST /_bulk
"create": { "_index""us""_type""tweet""_id""1" }}
"email" : "john@smith.com""name" : "John Smith""username" : "@john" }
"create": { "_index""us""_type""tweet""_id""2" }}
"email" : "mary@jones.com""name" : "Mary Jones""username" : "@mary" }
"create": { "_index""us""_type""tweet""_id""3" }}
"date" : "2014-09-13""name" : "Mary Jones""tweet" : "Elasticsearch means full text search has never been so easy""user_id" : 2 }
"create": { "_index""us""_type""tweet""_id""4" }}
"date" : "2014-09-14""name" : "John Smith""tweet" : "@mary it is not just text, it does everything""user_id" : 1 }
"create": { "_index""us""_type""tweet""_id""5" }}
"date" : "2014-09-15""name" : "Mary Jones""tweet" : "However did I manage before Elasticsearch?""user_id" : 2 }
"create": { "_index""us""_type""tweet""_id""6" }}
"date" : "2014-09-16""name" : "John Smith",  "tweet" : "The Elasticsearch API is really easy to use""user_id" : 1 }
"create": { "_index""us""_type""tweet""_id""7" }}
"date" : "2014-09-17""name" : "Mary Jones""tweet" : "The Query DSL is really powerful and flexible""user_id" : 2 }
"create": { "_index""us""_type""tweet""_id""8" }}
"date" : "2014-09-18""name" : "John Smith""user_id" : 1 }
"create": { "_index""us""_type""tweet""_id""9" }}
"date" : "2014-09-19""name" : "Mary Jones""tweet" : "Geo-location aggregations are really cool""user_id" : 2 }
"create": { "_index""us""_type""tweet""_id""10" }}
"date" : "2014-09-20""name" : "John Smith""tweet" : "Elasticsearch surely is one of the hottest new NoSQL products""user_id" : 1 }
"create": { "_index""us""_type""tweet""_id""11" }}
"date" : "2014-09-21""name" : "Mary Jones""tweet" : "Elasticsearch is built for the cloud, easy to scale""user_id" : 2 }
"create": { "_index""us""_type""tweet""_id""12" }}
"date" : "2014-09-22""name" : "John Smith""tweet" : "Elasticsearch and I have left the honeymoon stage, and I still love her.""user_id" : 1 }
"create": { "_index""us""_type""tweet""_id""13" }}
"date" : "2014-09-23""name" : "Mary Jones""tweet" : "So yes, I am an Elasticsearch fanboy""user_id" : 2 }
"create": { "_index""us""_type""tweet""_id""14" }}
"date" : "2014-09-24""name" : "John Smith""tweet" : "How many more cheesy tweets do I have to write?""user_id" : 1 }
複製程式碼

3.1 size+from淺分頁

按照一般的查詢流程來說,如果我想查詢前10條資料:

  1. 客戶端請求發給某個節點
  2. 節點轉發給個個分片,查詢每個分片上的前10條
  3. 結果返回給節點,整合資料,提取前10條
  4. 返回給請求客戶端

from定義了目標資料的偏移值,size定義當前返回的事件數目

查詢前5條的資料

GET /us/_search?pretty
{
  "from" : 0 , "size" : 5
}
複製程式碼

從第5條開始算,查詢5條

GET /us/_search?pretty
{
  "from" : 5 , "size" : 5
}
複製程式碼

之後我們在Java API當中就是這樣來查詢我們ES的資料,不過這種淺分頁只適合少量資料,因為隨from增大,查詢的時間就會越大,而且資料量越大,查詢的效率指數下降

優點:from+size在資料量不大的情況下,效率比較高

缺點:在資料量非常大的情況下,from+size分頁會把全部記錄載入到記憶體中,這樣做不但執行速遞特別慢,而且容易讓ES出現記憶體不足而掛掉

3.2 深分頁scroll

對於上面介紹的淺分頁,當Elasticsearch響應請求時,它必須確定docs的順序,排列響應結果。

如果請求的頁數較少(假設每頁20個docs), Elasticsearch不會有什麼問題,但是如果頁數較大時,比如請求第20頁,Elasticsearch不得不取出第1頁到第20頁的所有docs,再去除第1頁到第19頁的docs,得到第20頁的docs。

解決的方式就是使用scroll,scroll就是維護了當前索引段的一份快照資訊--快取(這個快照資訊是你執行這個scroll查詢時的快照)。
可以把 scroll 分為初始化和遍歷兩步: 1、初始化時將所有符合搜尋條件的搜尋結果快取起來,可以想象成快照; 2、遍歷時,從這個快照裡取資料;

初始化

GET us/_search?scroll=3m

"query": {"match_all": {}},
 "size"3
}
複製程式碼

初始化的時候就像是普通的search一樣,其中的scroll=3m代表當前查詢的資料快取3分鐘。Size:3 代表當前查詢3條資料

在遍歷時候,拿到上一次遍歷中的scrollid,然後帶scroll引數,重複上一次的遍歷步驟,知道返回的資料為空,就表示遍歷完成

GET /_search/scroll
{
  "scroll" : "1m",
  "scroll_id" : "DnF1ZXJ5VGhlbkZldGNoBQAAAAAAAShGFnE5ZURldkZjVDFHMHVaODdBOThZVWcAAAAAAAEoSRZxOWVEZXZGY1QxRzB1Wjg3QTk4WVVnAAAAAAABKEcWcTllRGV2RmNUMUcwdVo4N0E5OFlVZwAAAAAAAShIFnE5ZURldkZjVDFHMHVaODdBOThZVWcAAAAAAAEoShZxOWVEZXZGY1QxRzB1Wjg3QTk4WVVn"
}
複製程式碼

注意:每次都要傳引數scroll,重新整理搜尋結果的快取時間,另外不需要指定index和type(不要把快取的時時間設定太長,佔用記憶體)

對比:

淺分頁,每次查詢都會去索引庫(本地資料夾)中查詢pageNum*page條資料,然後擷取掉前面的資料,留下最後的資料。 這樣的操作在每個分片上都會執行,最後會將多個分片的資料合併到一起,再次排序,擷取需要的。

深分頁,可以一次性將所有滿足查詢條件的資料,都放到記憶體中。分頁的時候,在記憶體中查詢。相對淺分頁,就可以避免多次讀取磁碟。

四、ES的中文分詞器IK

ES預設對英文文字的分詞器支援較好,但和lucene一樣,如果需要對中文進行全文檢索,那麼需要使用中文分詞器,同lucene一樣,在使用中文全文檢索前,需要整合IK分詞器。那麼我們接下來就來安裝IK分詞器,以實現中文的分詞

4.1 下載

wget https://github.com/medcl/elasticsearch-analysis-ik/releases/download/v6.7.0/elasticsearch-analysis-ik-6.7.0.zip
複製程式碼

然後在ES的目錄中新建一個目錄存放這個外掛

mkdir -p /usr/local/elasticsearch-6.7.0/plugins/analysis-ik

unzip elasticsearch-analysis-ik-6.7.0.zip  -d /usr/local/elasticsearch-6.7.0/plugins/analysis-ik/
複製程式碼

然後你再分發到其它的機器即可

cd /usr/local/elasticsearch-6.7.0/plugins 
scp -r analysis-ik/ node2:$PWD 
複製程式碼

之後你需要重啟ES的服務

ps -ef|grep elasticsearch | grep bootstrap | awk '{print $2}' |xargs kill -9
nohup /kkb/install/elasticsearch-6.7.0/bin/elasticsearch 2>&1 &
複製程式碼

4.2 體驗一把

在kibana中建立索引庫並配置IK分詞器

delete iktest
PUT /iktest?pretty
{
    "settings" : {
        "analysis" : {
            "analyzer" : {
                "ik" : {
                    "tokenizer" : "ik_max_word"
                }
            }
        }
    },
    "mappings" : {
        "article" : {
            "dynamic" : true,
            "properties" : {
                "subject" : {
                    "type" : "text",
                    "analyzer" : "ik_max_word"
                }
            }
        }
    }
}
複製程式碼

在建立索引庫的時候,我們指定分詞方式為ik_max_word,會對我們的中文進行最細粒度的切分,現在來看下效果

這裡你可以看到,我的id被分成了好幾塊

你還可以用下面的語法對你的查詢進行高亮,比如這個效果

POST /iktest/article/_search?pretty
{
    "query" : { "match" : { "subject" : "抗擊肺炎" }},
    "highlight" : {
        "pre_tags" : ["<font color=red>"],
        "post_tags" : ["</font>"],
        "fields" : {
            "subject" : {}
        }
    }
}
複製程式碼

4.3 配置熱詞更新

我們可以發現我的ID是被分割成好幾塊的,因為在外掛它的視角中“說出你的願望吧”並不是個熱詞,但是我們可以告訴它我這是個熱詞?

比如現在,影流之主,蔡徐坤,都是被分掉的,那我們怎麼配置呢?就需要我們經常能夠實時的更新我們的網路熱詞,我們可以通過tomcat來實現遠端詞庫來解決這個問題。

4.4 安裝一個tomcat

安裝tomcat就隨便來一個就好了

然後你需要去到它的ROOT路徑下,比如我的是

cd /usr/local/apache-tomcat-8.5.34/webapps/ROOT
然後new一個file出來
vi hot.dic 
複製程式碼

然後儲存退出即可

接下來啟動你的tomcat,要是啟動成功就會能看到一個bootstrap服務

能訪問到hot.dic即可

4.5 修改一下分詞器的配置

其實就是修改這個檔案

點進來有一些中文註釋,然後你看到這個

把這一行的註釋去掉,然後就配置上我們剛剛可以訪問到的tomcat的詞的路徑,也就是 http://192.168.200.11:8080/hot.dic 即可

然後把這個配置檔案也分發到另外兩個節點上

然後我們重啟一下ES即可,現在再進行分詞,就會有關鍵字了

finally

這篇主要就是部署了,後面會涉及操作一些api啥的,篇幅就不搞這麼長啦?

相關文章