【1】Elasticsearch概述
① 什麼是全文檢索
全文檢索是指計算機索引程序通過掃描文章中的每一個詞,對每一個詞建立一個索引,指明該詞在文章中出現的次數和位置。當用戶查詢時,檢索程序就根據事先建立的索引進行查找,並將查找的結果反饋給用戶的檢索方式。這個過程類似於通過字典中的檢索字表查字的過程。全文搜索搜索引擎數據庫中的數據。
② lucene
Lucene是apache軟件基金會4 jakarta項目組的一個子項目,是一個開放源代碼的全文檢索引擎工具包,但它不是一個完整的全文檢索引擎,而是一個全文檢索引擎的架構,提供了完整的查詢引擎和索引引擎,部分文本分析引擎(英文與德文兩種西方語言)。Lucene的目的是爲軟件開發人員提供一個簡單易用的工具包,以方便的在目標系統中實現全文檢索的功能,或者是以此爲基礎建立起完整的全文檢索引擎。
對於我們目前來說,lucene,就是一個jar包,裏面包含了封裝好的各種建立倒排索引,以及進行搜索的代碼,包括各種算法。我們就用java開發的時候,引入lucene jar,然後基於lucene的api進行去進行開發就可以了。
lucene官網地址:http://lucene.apache.org/core/
在線文檔地址:http://lucene.apache.org/core/8_2_0/index.html
③ 什麼是Elasticsearch
Elasticsearch是一個實時分佈式搜索和分析引擎。它用於全文搜索、結構化搜索、分析。Elasticsearch基於lucene並隱藏複雜性,提供簡單易用的restful api接口、java api接口(還有其他語言的api接口)。
全文檢索: 將非結構化數據中的一部分信息提取出來,重新組織,使其變得有一定結構,然後對此有一定結構的數據進行搜索,從而達到搜索相對較快的目的。
結構化檢索: 我想搜索商品分類爲日化用品的商品都有哪些,select * from products where category_id='日化用品'
。
數據分析: 電商網站,最近7天牙膏這種商品銷量排名前10的商家有哪些;新聞網站,最近1個月訪問量排名前3的新聞版塊是哪些。
④ Elasticsearch的適用場景
- 維基百科,類似百度百科,牙膏,牙膏的維基百科,全文檢索,高亮,搜索推薦。
- The Guardian(國外新聞網站),類似搜狐新聞,用戶行爲日誌(點擊,瀏覽,收藏,評論)+ 社交網絡數據(對某某新聞的相關看法),數據分析,給到每篇新聞文章的作者,讓他知道他的文章的公衆反饋(好,壞,熱門,垃圾,鄙視,崇拜)。
- Stack Overflow(國外的程序異常討論論壇),IT問題,程序的報錯,提交上去,有人會跟你討論和回答,全文檢索,搜索相關問題和答案,程序報錯了,就會將報錯信息粘貼到裏面去,搜索有沒有對應的答案
- GitHub(開源代碼管理),搜索上千億行代碼。
- 國內:站內搜索(電商,招聘,門戶,等等),IT系統搜索(OA,CRM,ERP,等等),數據分析(ES熱門的一個使用場景)。
⑤ Elasticsearch的特點
- 可以作爲一個大型分佈式集羣(數百臺服務器)技術,處理PB級數據,服務大公司;也可以運行在單機上,服務小公司
- Elasticsearch不是什麼新技術,主要是將全文檢索、數據分析以及分佈式技術,合併在了一起,才形成了獨一無二的ES;lucene(全文檢索),商用的數據分析軟件(也是有的),分佈式數據庫(mycat)
- 對用戶而言,是開箱即用的,非常簡單,作爲中小型的應用,直接3分鐘部署一下ES,就可以作爲生產環境的系統來使用了,數據量不大,操作不是太複雜
- 數據庫的功能面對很多領域是不夠用的(事務,還有各種聯機事務型的操作);特殊的功能,比如全文檢索,同義詞處理,相關度排名,複雜數據分析,海量數據的近實時處理;Elasticsearch作爲傳統數據庫的一個補充,提供了數據庫所不能提供的很多功能
【2】Elasticsearch中數據結構
① 索引(index)
索引(index)是Elasticsearch對邏輯數據的邏輯存儲,所以它可以分爲更小的部分。然而,索引的結構是爲快速有效的全文索引準備的,特別是它不存儲原始值。如果你知道MongoDB,可以把Elasticsearch的索引看成MongoDB裏的一個集合。如果你熟悉CouchDB,可以把索引看成CouchDB數據庫索引。
Elasticsearch可以把索引存放在一臺機器或者分散在多臺服務器上,每個索引有一或多個分片(shard)每個分片包含了文檔集的一部分,每個分片可以有多個副本(replica)。Elasticsearch的默認值,索引結束時將得到5個分片及其各自1個副本。簡單來說,操作結束時,將有10個Lucene索引分佈在集羣中。
索引包含一堆有相似結構的文檔數據,比如可以有一個客戶索引,商品分類索引,訂單索引,索引有一個名稱。一個index包含很多document,一個index就代表了一類類似的或者相同的document。比如說建立一個product index,商品索引,裏面可能就存放了所有的商品數據,所有的商品document。
② 文檔類型(type)
在Elasticsearch中,一個索引對象可以存儲很多不同用途的對象,也就是不同類型。
例如,一個博客應用程序可以保存文章和評論。文檔類型讓我們輕易地區分單個索引中的不同對象。每個文檔可以有不同的結構,但在實際部署中,將文件按類型區分對數據操作有很大幫助。當然,需要記住一個限制,不同的文檔類型不能爲相同的屬性設置不同的類型。例如,在同一索引中的所有文檔類型中,一個叫title的字段必須具有相同的類型。
③ 文檔(document)
存儲在Elasticsearch中的主要實體叫文檔(document)。用關係型數據庫來類比的話,一個文檔相當於數據庫表中的一行記錄。當比較Elasticsearch中的文檔和MongoDB中的文檔,你會發現兩者都可以有不同的結構,但ES的文檔中,相同字段必須有相同類型。這意味着,所有包含title字段的文檔,title字段類型都必須一樣,比如string。
文檔是es中的最小數據單元,一個document可以是一條客戶數據,一條商品分類數據,一條訂單數據,通常用JSON數據結構表示,每個index下的type中,都可以去存儲多個document。
文檔由多個字段組成,每個字段可能多次出現在一個文檔裏,這樣的字段叫多值字段(multivalued)。
每個字段有類型,如文本、數值、日期等。字段類型也可以是複雜類型,一個字段包含其他子文檔或者數組。字段類型在ES中很重要,因爲它給出了各種操作(如分析或排序)如何被執行的信息。雖然可以自動確定,然而,仍然建議使用映射。
與關係型數據庫不同,文檔不需要有固定的結構,每個文檔可以有不同的字段,此外,在程序開發期間,不必確定有哪些字段。當然,可以用模式強行規定文檔結構。每個文檔存儲在一個索引中並有一個Elasticsearch自動生成的唯一標識符和文檔類型。文檔需要有對應文檔類型的唯一標識符
,這意味着在一個索引中,兩個不同類型的文檔可以有相同的唯一標識符。
④ 映射(mappings)
數據如何存放到索引對象上,需要有一個映射配置,包括:數據類型、是否存儲、是否分詞等。這樣就創建了一個名爲blog的Index。Type不用單獨創建,在創建Mapping 時指定就可以。Mapping用來定義Document中每個字段的類型,即所使用的 analyzer、是否索引等屬性,非常關鍵等。
⑤ 字段(Field)
Field是Elasticsearch的最小單位。一個document裏面有多個field,每個field就是一個數據字段。
【3】Elasticsearch主要概念
① 節點和集羣
Elasticsearch可以作爲一個獨立的單個搜索服務器。不過,爲了能夠處理大型數據集,實現容錯和高可用性,Elasticsearch可以運行在許多互相合作的服務器上。這些服務器稱爲集羣(cluster),形成集羣的每個服務器稱爲節點(node)。
cluster代表一個集羣,集羣中有多個節點,其中有一個爲主節點,這個主節點是可以通過選舉產生的,主從節點是對於集羣內部來說的。es的一個概念就是去中心化,字面上理解就是無中心節點,這是對於集羣外部來說的,因爲從外部來看es集羣,在邏輯上是個整體,你與任何一個節點的通信和與整個es集羣通信是等價的。
② 分片
當有大量的文檔時,由於內存的限制、硬盤能力、處理能力不足、無法足夠快地響應客戶端請求等,一個節點可能不夠。在這種情況下,數據可以分爲較小的部分稱爲分片(shard)(其中每個分片都是一個獨立的Apache Lucene索引實例,它只是保存了索引數據的一部分)。
每個分片可以放在不同的服務器上,因此,數據可以在集羣的節點中傳播。當你查詢的索引分佈在多個分片上時,Elasticsearch會把查詢發送給每個相關的分片,並將結果合併在一起,而應用程序並不知道分片的存在。此外,多個分片可以加快索引。
③ 副本
爲了提高查詢吞吐量或實現高可用性,可以使用分片副本。副本(replica)只是一個分片的精確複製,每個分片可以有零個或多個副本。換句話說,Elasticsearch可以有許多相同的分片,其中之一被自動選擇去更改索引操作。這種特殊的分片稱爲主分片(primary shard),其餘稱爲副本分片(replica shard)。在主分片丟失時,例如該分片數據所在服務器不可用,集羣將副本提升爲新的主分片。
④ 時光之門
Elasticsearch處理許多節點。集羣的狀態由時光之門控制。默認情況下,每個節點都在本地存儲這些信息,並且在節點中同步。
【4】Elasticsearch單節點安裝
安裝ES之前先安裝好jdk,可以簡單實用如下命令:
yum install -y java-1.8.0-openjdk.x86_64
ES官網下載地址:https://www.elastic.co/cn/downloads/past-releases#elasticsearch
這裏用的版本是5.2.2,linux是Centos 6。
① 解壓到指定目錄
tar -zxvf elasticsearch-5.2.2.tar.gz -C /home/softinstall/
② 在目標目錄下創建data和logs文件夾
cd /home/softinstall/elasticsearch-5.2.2
mkdir data logs
③ 修改config下的配置文件config/elasticsearch.yml
進入config文件夾,可以發現有三個配置文件,分別是elasticsearch的配置、jvm的配置以及日誌配置。
[root@localhost elasticsearch-5.2.2]# cd config/
[root@localhost config]# ll
total 12
-rw-rw----. 1 root root 2854 Feb 24 2017 elasticsearch.yml
-rw-rw----. 1 root root 2892 Feb 24 2017 jvm.options
-rw-rw----. 1 root root 3992 Feb 24 2017 log4j2.properties
vim elasticsearch.yml
主要進行如下配置(切記是yml語法冒號後面有空格):
cluster.name: my-application
node.name: node-1
path.data: /home/softinstall/elasticsearch-5.2.2/data
path.logs: /home/softinstall/elasticsearch-5.2.2/logs
bootstrap.memory_lock: false
bootstrap.system_call_filter: false
network.host: 192.168.18.128
http.port: 9200
discovery.zen.ping.unicast.hosts: ["localhost"]
如果要配置集羣需要兩個節點上的elasticsearch配置的cluster.name相同,都啓動可以自動組成集羣,這裏如果不改cluster.name則默認是cluster.name=my-application
。nodename隨意取但是集羣內的各節點不能相同。
還需要一些文件描述符數量限制的配置,如下:
vi /etc/security/limits.conf
添加如下內容:
* soft nofile 65536
* hard nofile 131072
* soft nproc 2048
* hard nproc 4096
vi /etc/security/limits.d/90-nproc.conf
* soft nproc 1024
#修改爲
* soft nproc 2048
vi /etc/sysctl.conf
添加下面配置:
vm.max_map_count=655360
並執行命令:sysctl -p
關於文件描述符可以參考博文:Linux下修改文件描述符數量限制
④ 啓動
直接以root身份運行是會報錯的,es不允許用root用戶運行:
Linux或OS X:bin/elasticsearch
Windows:bin/elasticsearch.bat
這時就需要將es切換用戶了:
chown -R jane:jane /home/softinstall/elasticsearch-5.2.2
⑤ 正常啓動與測試
啓動命令:
//bin目錄下以後臺服務方式啓動
./elasticsearch -d
ES正常啓動如下:
在瀏覽器上測試訪問:
可以查詢es的相關信息:
http://192.168.18.128:9200/_cat?pretty
默認HTTP API端口爲9200,內部廣播端口爲9300,如果用了header插件則會使用9100端口。
⑥ 關閉es
下面是三種可以關閉Elasticsearch的方法:
- 如果節點是連接到控制檯,按下Ctrl+C。
- 第二種選擇是通過發送TERM信號殺掉服務器進程(參考Linux上的kill命令和Windows
上的任務管理器)。 - 第三種方法是使用REST API。
第三種方法可以執行以下命令來關掉整個集羣:
curl -XPOST http://localhost:9200/_cluster/nodes/_shutdown
【5】ES集羣搭建
這裏使用了三臺虛擬機搭建ES集羣:192.168.18.128,192.168.18.129,192.168.18.130。
具體搭建參考單節點搭建但是集羣中配置文件修改如下:
cluster.name: my-application
node.name: node-1 #這裏分別是1 2 3
path.data: /home/softinstall/elasticsearch-5.2.2/data
path.logs: /home/softinstall/elasticsearch-5.2.2/logs
bootstrap.memory_lock: false
bootstrap.system_call_filter: false
network.host: 192.168.18.128 #這裏填寫對應主機IP
http.port: 9200
discovery.zen.ping.unicast.hosts: ["192.168.18.128","192.168.18.129","192.168.18.130"]
discovery.zen.minimum_master_nodes: 2
分別啓動三臺虛擬機上的ES,集羣之間會進行選舉出一個master。
192.168.18.128圖示如下:
192.168.18.129圖示如下:
192.168.18.130圖示如下:
【6】啓動報錯總結
① java.lang.UnsupportedOperationException: seccomp unavailable: CONFIG_SECCOMP not compiled into kernel, CONFIG_SECCOMP and CONFIG_SECCOMP_FILTER are needed
因爲Centos6不支持SecComp,而ES默認bootstrap.system_call_filter爲true
進行檢測,所以導致檢測失敗,失敗後直接導致ES不能啓動解決。
修改elasticsearch.yml 添加一下內容 :
bootstrap.memory_lock: false
bootstrap.system_call_filter: false
② 修改文件描述符數量限制
異常日誌如下:
ERROR: bootstrap checks failed
max file descriptors [4096] for elasticsearch process is too low, increase to at least [65536]
max number of threads [1024] for user [jane] is too low, increase to at least [2048]
max virtual memory areas vm.max_map_count [65530] is too low, increase to at least [262144]
解決方案:
vi /etc/security/limits.conf
添加如下內容:
* soft nofile 65536
* hard nofile 131072
* soft nproc 2048
* hard nproc 4096
vi /etc/security/limits.d/90-nproc.conf
* soft nproc 1024
#修改爲
* soft nproc 2048
vi /etc/sysctl.conf
添加下面配置:
vm.max_map_count=655360
並執行命令:sysctl -p
關於文件描述符可以參考博文:Linux下修改文件描述符數量限制
【7】Elasticsearch head插件安裝
下載elasticsearch-head-master.zip插件,官網地址:https://github.com/mobz/elasticsearch-head
nodejs官網下載安裝包:https://nodejs.org/dist/ ,這裏使用node-v6.9.2-linux-x64.tar.xz
① 安裝nodejs
解壓包到指定目錄:
tar -zxvf node-v6.9.2-linux-x64.tar.gz
配置環境變量:
export NODE_HOME=/home/softinstall/node-v6.9.2-linux-x64
export PATH=$PATH:$NODE_HOME/bin
檢測環境:
[root@localhost Desktop]# node -v
v6.10.0
[root@localhost Desktop]# npm -v
3.10.10
② 解壓並安裝header
unzip elasticsearch-head-master.zip
查看當前head插件目錄下有無node_modules/grunt
目錄,如果沒有就執行命令創建:
mkdir -p node_modules/grunt
執行命令安裝grunt:
npm install grunt --save
安裝header插件:
npm install -g cnpm --registry=https://registry.npm.taobao.org
這一步可能很慢,耐心等待。
安裝grunt-cli:
npm install -g grunt-cli
編輯Gruntfile.js:
第93行添加hostname:'0.0.0.0'
options: {
hostname:'0.0.0.0',
port: 9100,
base: '.',
keepalive: true
}
檢查head根目錄下是否存在base文件夾。如果沒有將 _site下的base文件夾及其內容複製到head根目錄下:
mkdir base
cp _site/base/* ./base/
③ 啓動grunt server
grunt server -d
可能會遇到以下錯誤提示:
> Local Npm module "grunt-contrib-clean" not found. Is it installed?
>> Local Npm module "grunt-contrib-concat" not found. Is it installed?
>> Local Npm module "grunt-contrib-watch" not found. Is it installed?
>> Local Npm module "grunt-contrib-connect" not found. Is it installed?
>> Local Npm module "grunt-contrib-copy" not found. Is it installed?
>> Local Npm module "grunt-contrib-jasmine" not found. Is it installed?
那麼就需要一個個安裝需要的模塊:
npm install grunt-contrib-clean -registry=https://registry.npm.taobao.org
npm install grunt-contrib-concat -registry=https://registry.npm.taobao.org
npm install grunt-contrib-watch -registry=https://registry.npm.taobao.org
npm install grunt-contrib-connect -registry=https://registry.npm.taobao.org
npm install grunt-contrib-copy -registry=https://registry.npm.taobao.org
npm install grunt-contrib-jasmine -registry=https://registry.npm.taobao.org
修改配置文件elasticsearch.yml,在文件末尾增加如下配置(其實就是跨域):
http.cors.enabled: true
http.cors.allow-origin: "*"
重啓ES,再次啓動grunt server grunt server -d
,瀏覽器訪問:http://192.168.18.128:9100/
這個界面可以進行索引的增刪改查: