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

前言

ELK的基本介紹

ELK是三個軟件產品的首字母縮寫,Elasticsearch,Logstash 和 Kibana。這三款軟件都是開源軟件,一般是配合使用,並且又前後歸於 Elastic.co 公司名下,故被簡稱爲 ELK 協議棧html

左邊咱們部署了多臺服務器,而後咱們經過logstash來採集數據,採集完成咱們發送到ES集羣中存起來,而後經過Kibana去展現到咱們的瀏覽器中,就是這麼一個簡單的套路node

Elasticsearch是個開源分佈式搜索引擎,它的特色有:開箱即用,分佈式,零配置,自動發現,索引自動分片,索引副本機制,RESTful風格接口,多數據源,自動搜索負載等。linux

Logstash是一個徹底開源的工具,他能夠對你的日誌進行收集、過濾,並將其存儲供之後使用(好比供ES來進行搜索)。git

Kibana 也是一個開源和免費的工具,它Kibana能夠爲 Logstash 和 ElasticSearch 提供的日誌分析友好的 Web 界面,能夠幫助您彙總、分析和搜索重要數據日誌。github

ELK的實現介紹

ELK 實現語言 簡介
ElasticSearch Java 實時的分佈式搜索和分析引擎,可用於全文檢索,結構化搜索以及分析,基層基於Lucene。相似於Solr
Logstash JRuby 具備實時渠道能力的數據收集引擎,包含輸入、過濾、輸出模塊,通常在過濾模塊中作日誌格式化的解析工做
Kibana JavaScript 爲ElasticSerach提供分析平臺和可視化的Web平臺。他能夠ElasticSerach的索引中查找,呼喚數據,並生成各類維度的表圖

ELK的參考資料

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

ELK官網文檔:https://www.elastic.co/guide/...數據庫

ELK中文手冊:https://www.elastic.co/guide/...apache

ELK中文社區:https://elasticsearch.cn/npm

1、Elasticsearch的部署

1.1 簡介

ElaticSearch,簡稱爲ES, ES是一個開源的高擴展的分佈式全文檢索引擎,它能夠近乎實時的存儲、檢索數據;自己擴展性很好,能夠擴展到上百臺服務器,處理PB級別的數據。ES也使用Java開發並使用Lucene做爲其核心來實現全部索引和搜索的功能,可是它的目的是經過簡單的RESTful API來隱藏Lucene的複雜性,從而讓全文搜索變得簡單。bootstrap

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

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/...

首先是下安裝包,而後再解壓一下便可,操做比較簡單這裏就不說明了

以後咱們建立兩個文件夾,都在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 [4096] for 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/kevin...

下載好安裝包以後,咱們解壓,進行些配置便可

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的交互

2、使用RESTful的方式去操做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.一、索引 index

一個索引就是一個擁有幾分類似特徵的文檔的集合。好比說,你能夠有一個客戶數據的索引,另外一個產品目錄的索引,還有一個訂單數據的索引。一個索引由一個名字來標識(必須所有是小寫字母的),而且當咱們要對對應於這個索引中的文檔進行索引、搜索、更新和刪除的時候,都要使用到這個名字。在一個集羣中,能夠定義任意多的索引。

2.2.二、類型 type

在一個索引中,你能夠定義一種或多種類型。一個類型是你的索引的一個邏輯上的分類/分區,其語義徹底由咱們來定。一般,會爲具備一組共同字段的文檔定義一個類型。好比說,咱們假設你運營一個博客平臺而且將你全部的數據存儲到一個索引中。在這個索引中,你能夠爲用戶數據定義一個類型,爲博客數據定義另外一個類型,固然,也能夠爲評論數據定義另外一個類型。

2.2.三、字段Field

至關因而數據表的字段,對文檔數據根據不一樣屬性進行的分類標識

2.2.四、映射 mapping

其實就是相似於JavaBean同樣的東西。mapping是處理數據的方式和規則方面作一些限制,如某個字段的數據類型、默認值、分析器、是否被索引等等,這些都是映射裏面能夠設置的,其它就是處理es裏面數據的一些使用規則設置也叫作映射,按着最優規則處理數據對性能提升很大,所以才須要創建映射,而且須要思考如何創建映射才能對性能更好。

2.2.五、文檔 document

一個文檔是一個可被索引的基礎信息單元。好比,你能夠擁有某一個客戶的文檔,某一個產品的一個文檔,固然,也能夠擁有某個訂單的一個文檔。文檔以JSON(Javascript Object Notation)格式來表示,而JSON是一個處處存在的互聯網數據交互格式。
在一個index/type裏面,你能夠存儲任意多的文檔。注意,儘管一個文檔,物理上存在於一個索引之中,文檔必須被索引/賦予一個索引的type。

2.2.六、接近實時 NRT

Elasticsearch是一個接近實時的搜索平臺。這意味着,從索引一個文檔直到這個文檔可以被搜索到有一個輕微的延遲(一般是1秒之內)

2.2.七、分片和副本 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.八、一個管理工具

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 一、使用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.四、bool的複合查詢中的should

should表示無關緊要的(若是should匹配到了就展現,不然就不展現)
例子:
查詢喜歡旅行的,若是有男性的則顯示,不然不顯示

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

2.4.五、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.六、使用terms匹配多個值

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

2.4.七、Range過濾

Range過濾容許咱們按照指定的範圍查找一些數據:操做範圍:

gt: --- 大於
gae: --- 大於等於
lt: --- 小於
lte: --- 小於等於

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

GET /school/student/_search?pretty
{
"query": {
   "range": {
    "age": {"gt":20,"lte":25}
         }
      }
}

2.4.八、exists和 missing過濾

exists和missing過濾能夠找到文檔中是否包含某個字段或者是沒有某個字段

例子:
查找字段中包含age的文檔

GET /school/student/_search?pretty
{
"query": {
   "exists": {
    "field": "age"  
         }
      }
}

2.4.九、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.十、查詢與過濾條件合併

一般複雜的查詢語句,咱們也要配合過濾語句來實現緩存,用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那邊的圖了,沒啥用😂

3、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 分爲初始化和遍歷兩步: 一、初始化時將全部符合搜索條件的搜索結果緩存起來,能夠想象成快照; 二、遍歷時,從這個快照裏取數據;

初始化

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條數據,而後截取掉前面的數據,留下最後的數據。 這樣的操做在每一個分片上都會執行,最後會將多個分片的數據合併到一塊兒,再次排序,截取須要的。

深分頁,能夠一次性將全部知足查詢條件的數據,都放到內存中。分頁的時候,在內存中查詢。相對淺分頁,就能夠避免屢次讀取磁盤。

4、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啥的,篇幅就不搞這麼長啦😶

相關文章
相關標籤/搜索