ElasticSearch大數據分佈式彈性搜索引擎使用

閱讀目錄:

  1. 背景
  2. 安裝
    1. 查找、下載rpm包 、執行rpm包安裝
    2. 配置elasticsearch專屬帳戶和組
    3. 設置elasticsearch文件全部者
    4. 切換到elasticsearch專屬帳戶測試可否成功啓動
    5. 安裝自啓動elasticsearch servicewrapper包
      1. 下載elasticsearch servicewrapper 包
      2. elasticsearch servicewrapper開源包的配置小bug
      3. servicewrapper安裝
      4. chkconfig -add 加入linux啓動服務列表
    6. 安裝_plugin/head管理插件(輔助管理)
    7. 安裝chrom中的elasticsearch客戶端插件
    8. 使用elasticsearch自帶的_cat工具
    9. clone 虛機(修改IP、HWaddr、UUID配置,最後修改下系統時間)
  3. 配置
    1. elasticsearch.yml配置
      1. IP訪問限制、默認端口修改9200
      2. 集羣發現IP列表、node、cluster 名稱
      3. master node 啓動切換
    2. linux 打開最大文件數設置(用做index時候的系統閥值)
    3. 安裝中文分詞器ik(注意對應版本問題)
    4. elasticsearch集羣規劃
  4. 開發
    1. 鏈接集羣
      1. net nest使用(使用pool鏈接es集羣)
      2. java jest使用(使用pool鏈接es集羣)
    2. index開發
      1. mapping 配置
      2. mapping template配置
      3. index routing索引路由配置
  5. 總結

1.背景

兩年前有機會接觸過elasticsearch,可是未作深刻學習,只是工做中用到了。愈來愈發現es是個不錯的好東西,因此花了點時間好好學習了下。在學習過程當中也發現了一些問題,網上大多資料都很零散,大部分都是實驗性的demo,不少問題並無講清楚也並無系統的講完整一整套方案,因此耐心的摸索和總結了一些東西分享出來。html

畢竟當你用生產使用的標準來使用es時會有不少問題,這對你的學習提出來了新的標準。java

好比,使用elasticsearch servicewrapper進行自啓動的時候難道就沒發現它的配置中有一個小bug致使load不了elasticsearch jar包中的class嗎。node

還有es不一樣版本之間的差別巨大,好比,1.0中的分佈式routing在2.0中進行了巨大差別的修改。本來routing是跟着mapping一塊兒配置的,到了2.0卻跟着index動態走了。這個調整的本質目的是好的,讓同一個index的不一樣type都有機會選擇shard的片鍵。若是是跟着mapping走的話就只能限定於當前index的全部type。linux

es是個好東西,如今愈來愈多的分佈式系統都須要用到它來解決問題。從ELK這種系統層的工具到電商平臺的核心業務交易系統的設計都須要它來支撐實時大數據搜索分析。好比,商品中心的上千萬的sku須要實時搜索,再到海量的在線訂單實時查詢都須要用到搜索。git

在一些DevOps的工具中都須要es來提供強大的實時搜索功能。值得花點時間好好研究學習下。github

做爲電商架構師,因此沒有什麼理由不去學習和使用它來提升系統的總體服務水平。本篇文章將本身這段時間學習的經驗總結出來分享給你們。算法

2.安裝

首先你須要幾臺linux機器,你跑虛機也行。你能夠在一臺虛擬機上完成安裝和配置,而後將當前虛擬機clone出多份修改下IP、HWaddr、UUID即用,這樣方便你使用,而不須要再重複的安裝配置。chrome

1.我本地是三臺Linux centos6.5,IP分別是,192.168.0.十、192.168.0.20、192.168.0.30。shell

(咱們先在192.168.0.10上執行安裝配置,而後一切就緒以後咱們將這個節點clone出來修改配置,而後再配置集羣參數,最後造成能夠工做的以三個node組成的集羣實例。)json

2.因爲ElasticSearch是java語言開發的,因此咱們須要預先安裝好java相關環境。我使用的是JDK8,直接使用yum安裝便可,yum倉庫有最新的源。

先查看你當前機器是否安裝了java環境:

yum info installed |grep java*

16

若是已經存在java環境且這個環境不是你想要的,你能夠卸載而後從新安裝你想要的版本。(yum –y remove xxx)若是卸載不乾淨,你能夠直接find 查找相關文件,而後直接物理刪除。linux的系統都是基於文件的,只要能找到基本上均可以刪除。

先看下有哪些版本:

yum search java

java-1.8.0-openjdk.x86_64 : OpenJDK Runtime Environment(找到這個源)

而後執行安裝:

yum –y install java-1.8.0-openjdk.x86_64

安裝好以後查看java 相關參數:

java –version

14

預備工做咱們已經作好,接下來咱們將執行ElasticSearch的環境安裝和配置。

2.1.查找、下載rpm包、執行rpm包安裝

你能夠有幾種方式安裝。使用yum repository是最快最便捷的,可是通常這裏面的版本應該是比較滯後的。因此我是直接到官網下載rpm包安裝的。

elasticsearch官方下載地址:https://www.elastic.co/downloads/elasticsearch

1

找到你對應的系統類型文件,固然若是你是windows系統那就直接下載zip包使用就好了。這裏我須要rpm文件。

你也能夠安裝本地yum 源,而後仍是使用yum命令安裝。

我是使用wget 工具直接下載RPM文件到本地的。(若是你的包有依賴建議仍是yum方式安裝。)

(若是你的wget命令不起做用,記得先安裝:yum -y install wget)

wget https://download.elastic.co/elasticsearch/release/org/elasticsearch/distribution/rpm/elasticsearch/2.4.0/elasticsearch-2.4.0.rpm

而後等待下載完成。

這裏有個東西須要提醒下,就是你是否要安裝最新版本的elasticsearch,我的建議仍是安裝稍微低一個版本的,我本地安裝的是2.3.4的版本。爲何要這樣強調尼,由於當你安裝了很高的版本以後有一個很大的問題就是中文分詞器可否支持到這個版本。從2.3.5以後就直接到2.4.0的版本了,我當時安裝的是2.3.5的版本後來發現一個問題就是ik中文分詞器我得git clone下來編譯後纔能有輸出部署文件。因此建議你們安裝2.3.4的版本,2.3.4的版本中文分詞器就能夠直接在linux服務器裏下載部署,很方便。

執行安裝:

rpm -iv elasticsearch-2.3.4.rpm

而後等待安裝完成。

不出什麼意外,安裝就應該完成了。咱們進行下基本的安裝信息查看,是否安裝以後缺乏什麼文件。由於有些包裏面會缺乏一些config配置。若是缺乏咱們還得補充完整。

爲了方便查看安裝涉及到的文件,你能夠導航到根目錄下 find。

cd /

find . –name elasticsearch

./var/lib/elasticsearch
./var/log/elasticsearch
./var/run/elasticsearch
./etc/rc.d/init.d/elasticsearch
./etc/sysconfig/elasticsearch
./etc/elasticsearch
./usr/share/elasticsearch
./usr/share/elasticsearch/bin/elasticsearch

基本上差很少了,你還得看下是否缺乏config,由於我安裝的時候是缺乏的。

cd /usr/share/elasticsearch/

ll

drwxr-xr-x. 2 root          root           4096 9月   4 01:10 bin
drwxr-xr-x. 2 root          root           4096 9月   4 01:10 lib
-rw-r--r--. 1 root          root          11358 6月  30 19:22 LICENSE.txt
drwxr-xr-x. 5 root          root           4096 9月   4 01:10 modules
-rw-r--r--. 1 root          root            150 6月  30 19:22 NOTICE.txt
drwxr-xr-x. 2 elasticsearch elasticsearch  4096 6月  30 19:32 plugins
-rw-r--r--. 1 root          root           8700 6月  30 19:22 README.textile

大概看下你應該也是缺乏config文件夾的。咱們還得把這個文件夾建好,同時還須要一個elasticsearch.yml配置文件。要否則啓動的時候確定是報錯的。

mkdir config

cd config

vim elasticsearch.yml

找一下elasticsearch.yml配置貼上去,或者你用文件的方式傳送也行。這些配置都是基本的,回頭還須要根據狀況調整配置的。有些配置在配置文件中是沒有的,還須要到官方上去查找的。因此這裏無所謂配置文件的全或者不全。關於配置項網上有不少資料,因此這個無所謂的。

保存下elasticsearch.yml文件。

你還須要一個logging.yml日誌配置文件。es做爲服務器後臺運行的服務是確定須要日誌文件的。這部分日誌會被你的日誌平臺收集和監控,用來作爲運維健康檢查。logging.yml本質上是一個log4j的配置文件,這個應該你們都比較熟悉了。跟elasticsearch.yml相似,要麼複製粘貼要麼文件傳送。

日誌的輸出在logs目錄下,這個目錄會被自動建立。可是我仍是喜歡建立好,不喜歡有不肯定因素,也許它就不會自動建立。

mkdir logs

最後須要設置下剛纔咱們添加的文件的執行權限。要否則你的文件名字應該是白色的,是不容許被執行。

2

cd ..

chmod –R u+x config/

3

如今基本上安裝算是完成了,試着cd到文件的啓動目錄下啓動es,來檢查下是否能正常啓動。

不出意外你會收到一個 「java.lang.RuntimeException: don't run elasticsearch as root」異常。這說明咱們完成了第一步安裝過程,下節咱們來看有關啓動帳戶的問題。

4

2.2.配置elasticsearch專屬帳戶和組

默認狀況下es是不容許root帳戶啓動的,這是爲了安全起見。es默認內嵌了groovy腳本引擎的功能,還有不少plugin腳本引擎插件,確實不太安全。es剛出來的時候還有groovy漏洞,因此建議在產線的es instance 關掉這個腳本功能。雖然默認不是開啓的,安全起見仍是檢查一下你的配置。

因此咱們須要爲es配置獨立的帳戶和組。在建立es專用帳戶以前先查看下系統裏面是否已經有了es專用帳戶。由於在咱們前面rpm安裝的時候會自動安裝elasticsearch組和用戶。先查看下,若是你的安裝沒有帶上專用組和用戶而後你在建立。這樣以避免你本身增長的和系統建立的搞混淆。

查看下組:

cat /etc/group

5

 

 

查看下用戶:

cat /etc/passwd

6

基本上都建立好了。499的group在passwd中也建立了對應的elasticsearch帳號。

若是你係統裏沒有自動建立對應的組和帳號,你就動手本身建立,以下:

建立組:

groupadd elasticsearch_group

7

建立用戶:

useradd elasticsearch_user -g elasticsearch_group -s /sbin/nologin

8

注意:此帳戶是不具備登陸權限的。它的shell是在/sbin/nologin。

爲了演示,在個人電腦上有兩組elasticsearch專用帳戶,我將刪除「_group」和「_user」結尾的帳號,以rpm自動安裝的爲es的啓動帳號(elasticsearch)。

2.3.設置elasticsearch文件全部者

接下來咱們須要作的就是關聯es文件和elasticsearch帳號,將es相關的文件設置成elasticsearch用戶爲全部者,這樣elasticsearch用戶就能夠沒有任何權限限制的使用es全部文件。

導航到elasticsearch上級目錄:

cd /usr/share

ll

9

chown -R elasticsearch:elasticsearch elasticsearch/

10

此時,你的elasticsearch文件的owner是elasticsearch。

2.4.切換到elasticsearch專屬帳戶測試可否成功啓動

爲了測試啓動es實例,咱們須要暫時的將elasticsearch的用戶切換到/bin/bash。這樣咱們就能夠su elasticsearch,而後啓動es實例。

su elasticsearch

cd /usr/share/elasticsearch/bin

./elasticsearch

11

啓動完成,此時應該沒發生任何異常。看下系統端口是否啓動成功。

netstat –tnl

12

繼續查看下HTTP服務是否啓動正常。

curl –get http://192.168.0.103:9200/_cat

13

因爲此時咱們並無安裝任何輔助管理工具,如,plugin/head。因此用內置的_cat rest endpoit仍是挺方便的。

curl -get http://192.168.0.103:9200/_cat/nodes

192.168.0.103 192.168.0.103 4 64 0.00 d * node-1

能夠看見,目前只有一個節點在工做,192.168.0.103,且它是一個data node。

(備註:爲了節省時間,我暫時先使用一臺103的乾淨環境做爲安裝和環境搭建演示,當搭建集羣的時候我會clone出來和修改IP。)

2.5.安裝自啓動elasticsearch servicewrapper包

es的系統自啓動有一個開源的wrapper包可使用。若是你不使用這個wrapper也能夠本身去寫shell腳本,可是裏面的不少參數須要你搞的很是清楚才行,在加上有些關鍵參數須要設置。因此仍是建議在elasticsearchwrapper包的基礎上進行修改效率會高點,並且你還能在elasticsearch shell中看見一些es深層次的配置和原理。

(備註:若是你是.neter,你能夠將servicewrapper理解成是開源.net topshelf。本質就是將程序包裝成具備系統服務功能,你能夠安裝、卸載,也能夠直接啓動、中止,或者乾脆直接前臺運行。)

2.5.1.下載elasticsearch servicewrapper 包

elasticsearchwrapper github首頁,https://github.com/elastic/elasticsearch-servicewrapper

17

複製 git repository 地址到剪貼板,而後直接clone到本地。

git clone https://github.com/elastic/elasticsearch-servicewrapper.git

(你須要在當前linux機器上安裝git客戶端:yum –y install git,我安裝的是默認1.7的版本。)

而後等待clone完成。

18

查看下clone下來的本地倉庫文件狀況。進入elasticsearchwrapper,查看當前git 分支。

cd /root/elasticsearch-servicewrapper

git branch

*master

ll

一切都很正常,說明咱們clone下來沒問題,包括分支也是很清晰的。service文件就是咱們要安裝的安裝文件。

20

咱們須要將service文件copy到elasticsearch/bin目錄下。

cp -R service/ /usr/share/elasticsearch/bin/

cd /usr/share/elasticsearch/bin/

21

service裏的安裝文件須要在elasticsearch/bin目錄下工做。
cd service/

ll

./elasticsearch

22

參考github上elasticsearchwrapper使用說明。elasticsearch servicewrapper的功能仍是蠻多的,status、dump都是很好的檢查和調試工具。

19

在安裝以前,咱們須要暫時在前臺運行es實例,這樣能夠查看一些log是否有異常狀況。Parameter的各個參數寫的很清楚,咱們這裏使用console控制檯輸出啓動es實例。

./elasticsearch console

2.5.2 elasticsearch servicewrapper開源包的配置小bug

此時你應該會收到一個Error的提示:

WrapperSimpleApp Error: Unable to locate the class org.elasticsearch.bootstrap.ElasticsearchF : java.lang.ClassNotFoundException: org.elasticsearch.bootstrap.ElasticsearchF

23

第一次看到這個我有點蒙,這個ElasticsearchF是個什麼對象。命名有點特殊,再進一步查看Exception的信息,實際上是一個ClassNotFoundException異常。說明找不到這個ElasticSearchF類。

兩種可能性,第一就是java elasticsearch相關包的問題,確實缺乏這個類。可是這個可能性很小,由於咱們以前直接運行elasticsearch是成功的。我當時用jd-gui翻了下es的包,確實沒有這個類。

第二就是這裏的配置錯誤,應該就個手誤,確實沒有ElasticsearchF這個類。

咱們查看下service/elasticsearch.conf配置文件裏是否是有這個‘elasticsearchF’字符串。(wrapper包是使用當前目錄下的elasticsearch.conf做爲配置文件使用的)

grep –i elasticsearchf elasticsearch.conf

24

確實有這個字符串,咱們進行編輯保存,去掉最後的‘F’。

25

而後咱們在進行啓動嘗試。

./elasticsearch console

我不知道你是否是會和個人狀況同樣,提示相關命令都是不規範的。

26

這個運行鏈路基本上通過三個路徑,第一個就是service/elasticsearch shell啓動腳本,而後獲取命令分析命令再啓動exec下的相關java servicewrapper程序。

這個java servicewrapper程序,版本是3.5.14。根據上述思路,經過查看elasticsearch shell程序,它在接收到外部的命令以後會啓動exec下的java servicewrapper程序。我想試着編輯了下elasticsearch shell文件,輸出一些信息出來,查看下是否是獲取相關路徑或者參數之類的致使錯誤。(遇到問題不怕,至少咱們要一路跟下去,看下到底是怎麼回事。)

vim ./elasticsearch

esc

:/console

找下console在哪裏,而後加上調試文本信息,輸出到界面上。

27

再運行,查看命令參數是否有問題。

28

查看了下,輸出的參數基本都沒有問題。一時無解。好奇心做怪,本想再進一步看下exec/elasticsearch-linux-x86-64.so文件的,後來發現打開根本就看不懂。因此就另尋其餘方法,我找了windows版本servicewrapper,發現windows的elasticsearchservicewrapper是沒有32位的servicewrapper的。我試着運行起來基本上也是報相同的錯誤,可是windows的wrapper的error信息比較多點,提示出錯的緣由在哪裏。

我想修改下日誌的輸出級別,看可否輸出一些能夠用的信息。編輯service/elasticsearch.conf wrapper包專用配置。

# Log Level for console output.  (See docs for log levels)
wrapper.console.loglevel=TRACE

# Log Level for console output.  (See docs for log levels)
wrapper.console.loglevel=TRACE

咱們將日誌輸出級別設置成trace,有兩處須要設置,咱們再看輸出信息。

29

是輸出了一些有用的信息,能夠查看log文件詳情。

WrapperManager Debug: Received a packet LOGFILE : /usr/share/elasticsearch/logs/service.log

可是有關於error的信息仍是隻有一條。

這裏就告一段落。咱們的目的是爲了使用console來運行,想查看下一些運行日誌,可是跑不起來也無所謂,咱們繼續執行安裝操做。

(哪位博友若是知道問題在哪裏的能夠分享出來,我以爲這個問題不是一個偶發性問題,應該都會遇到。我先拋出問題,至少能夠服務未來的使用者。這裏先謝謝了。)

其實,若是你不使用elasticsearch servicewrapper來包裝而是本身去下載java serivcewrapper來包裝elasticsearch也是能夠的,實現起來也很方便。

咱們回到主題,既然咱們沒法console運行,也看不了一些wrapper console執行時的狀況,那咱們就只能進行安裝了。

2.5.3 servicewrapper安裝 (elasticsearch init.d 啓動文件設置user、openfile、configpath)

按照elasticsearch servicewrapper parameter參數指示,咱們執行安裝。

./elasticsearch install

Installing the Elasticsearch daemon..

守護進程安裝完成。咱們仍是前去系統目錄下查看是否是安裝成功(技術人員始終保持一個嚴謹的心態是有必要的。)前往/etc/init.d/目錄下查看。

ll /etc/init.d/

-rwxrwxr--. 1 root root  4496 10月  4 01:43 elasticsearch

我這裏設置過chmod u+x ./elasticsearch。別忘記設置文件的執行權限,這在咱們【2.1節】裏將結果,這裏就不重複了。

咱們開始編輯elasticsearch啓動文件。

30

主要就是這段,填寫好配置的es的專用帳戶(elasticsearch【2.2.節】),還有相應的文件路徑。這裏先忽略MAX_OPEN_FILES、MAX_MAP_COUNT兩個配置項,在後面【3.3.節】配置部分會講解到。

2.5.4 chkconfig -add 加入linux啓動服務列表

將其添加到系統服務中,以便被系統自動啓動。

chkconfig --add elasticsearch

chkconfig –list

31

已經添加好系統自啓動服務列表中。

service elasticsearch start

啓動es實例,等待端口啓動完成,稍等片刻查看端口狀況。

netstat –tnl

32

9300端口比9200端口先啓動,由於9300端口是 cluster內部管理端口。9200是rest endpoint 服務端口。固然,這個時間延長不會很長。

端口都啓動成功以後,咱們查看下可否正常訪問es實例。

curl -get http://192.168.0.103:9200/
{
  "name" : "node-1",
  "cluster_name" : "orderSearch_cluster",
  "version" : {
    "number" : "2.3.4",
    "build_hash" : "e455fd0c13dceca8dbbdbb1665d068ae55dabe3f",
    "build_timestamp" : "2016-06-30T11:24:31Z",
    "build_snapshot" : false,
    "lucene_version" : "5.5.0"
  },
  "tagline" : "You Know, for Search"
}

咱們仍是使用_cat rest endpoint來查看。

curl -get http://192.168.0.103:9200/_cat/nodes
192.168.0.103 192.168.0.103 4 61 0.00 d * node-1

若是你能夠在本機訪問,可是在外部瀏覽器中沒法訪問,極可能是防火牆的設置問題,你能夠去設置下防火牆。

33

vim /etc/sysconfig/iptables

重啓網絡服務,以便加載防火牆設置項。

service network restart

而後再嘗試看可否外部訪問,若是不行你就telnet端口下。

由於訪問不了還有一個緣由是和elasticsearch.yml一個配置項有關係。見【3.1.1節】。

 

重啓機器,查看es實例是否會自動啓動。

shutdown –r now

稍等片刻,而後嘗試鏈接機器。

若是沒出什麼意外,都應該正常的,端口也啓動成功了。說明咱們完成了es實例自啓動功能,它如今做爲linux系統服務被自動管理。

安裝成服務以後,elasticsearch servicewrapper和咱們就沒有太多關係了。由於它的parameter都是圍繞者咱們基於servicewrapper來使用的。

2.6.安裝_plugin/head管理插件(輔助管理)

爲了很好的管理集羣,咱們須要相應的工具,head是比較流行和通用的,並且是免費的。固然還有不少好用的其餘工具,如,Bigdesk、Marvel(商用收費)。plugin的安裝都大同小異,咱們這裏就使用通用的head工具。

先看下,head給咱們帶來的清晰的集羣節點管理視圖。

34

這是有三個節點的es集羣實例。它是一個二維矩陣排列,最上面橫向是索引,最左邊是節點,交叉的地方是索引的分片信息和分片比例。

安裝head插件仍是比較方便的,你也能夠直接copy文件的方式使用。在elasticsearch的home目錄下有一個plugins目錄,它是全部插件的目錄,全部的插件都會在這個文件夾查找和加載。

咱們看下安裝head插件方法。在elasticsearch/bin 目錄下有一個plugin可執行文件,它是專門用來安裝插件用的程序。

./plugin -install mobz/elasticsearch-head

插件的查找路徑有幾個elasticsearch官網是一個,github是一個。這裏會先嚐試在github上查找,稍等片刻,等待安裝完成。咱們嘗試訪問head插件地址rest地址/_plugin/head。

35

看到這個界面基本安裝成功了,node-1默認是master節點。

2.7.安裝chrom中的elasticsearch客戶端插件

chrom中有不少可使用的elasticsearch客戶端插件,便於開發和維護,建議直接使用chrom中的插件。只要搜索下elasticsearch關鍵字就會出來不少。

36

有兩個比較經常使用,也比較好用,EalsticSearch Toolbox、Sense(自動提示dsl編輯工具)。chrom插件都是那麼的酷,使用起來都很賞心悅目。

37

elasticsearch toolbox 能夠很方便的查詢和導出數據。

38

sense可讓你編輯elasticsearch dsl 特定語言會有啓動提示幫助,這樣編寫起復雜的dsl效率會高並且不易出錯。其餘的工具我也沒用過,感受均可以嘗試用用看。

(備註:若是你沒法訪問chrom商店中心就須要特殊處理下,這裏就不解釋了。)

2.8.使用elasticsearch自帶的_cat工具

在一些特殊的狀況下你可能沒法直接使用plugin來幫你管理或者查看集羣狀況。此時你能夠直接使用elasticsearch自帶的rest _cat查看集羣狀況,好比,你可能發現_plugin/head有一些節點沒有上來,可是你又不肯定發生了什麼狀況,你就可使用/_cat/nodes來查看全部node的狀況。有時候確實有的節點沒有啓動起來,可是大多數狀況下都是各自爲政(腦裂),你可能須要讓他們從新選舉或者加快的選舉過程。

http://192.168.0.20:9200/_cat/nodes?v (查看nodes狀況)

39

_cat rest端點帶有一個v的參數,這個參數是幫助你閱讀的參數。_search rest端點帶有pretty參數,這個參數是幫助查詢數據閱讀的。每個端點基本上都有各自的輔助閱讀參數。

http://192.168.0.20:9200/_cat/shards?v(查看shards狀況)

40

http://192.168.0.20:9200/_cat/ (查看全部能夠cat的功能)

41

你能夠查看系統 aliases別名、segments片斷(看下每一個片斷的提交版本一致性)、indices索引集合等等。

2.9.clone 虛機(修改IP、HWaddr、UUID配置,最後修改下系統時間)

當咱們完成了對一臺機器的安裝以後,接下來就須要搭建分佈式系統。分佈式系統就須要多節點機器,按照es分佈式集羣搭建最佳實踐,你至少須要三個節點。因此咱們將已經安裝完成的這個機器clone出來兩臺,一共三臺組成能夠工做的三個節點的分佈式系統。

首先clone當前安裝完成的機器,192.168.0.103,clone好以後啓動起來修改幾個配置便可。(由於你是clone出來的,因此配置已經重複,好比,網卡地址、IP地址)

編輯網卡配置文件:

vim /etc/sysconfig/network-scripts/ifcfg-eth0

DEVICE=eth3
HWADDR=00:0C:29:CF:48:23
TYPE=Ethernet
UUID=b848e750-d491-4c9d-b2ca-c853f21bf40b
ONBOOT=yes
NM_CONTROLLED=yes
BOOTPROTO=static
BROADCAST=192.168.233.255
IPADDR=192.168.0.103
NETMASK=255.255.255.0
GATEWAY=192.168.0.1

DEVICE 是網卡標示,根據你本地的網卡標識修改爲對應的便可,能夠經過ifconfig查看。HWADDR網卡地址,隨意修改下,保證在你的網段內不重複便可。UUID也是和HWADDR同樣修改。

IP地址修改爲你本身以爲合適的IP,最好參考你當前物理機器的相關配置。GATEWAY網關地址要參考你物理機器的網關地址,若是你的虛擬機使用的是橋接模式的網絡鏈接,這裏就須要設置,要否則網絡就鏈接不上。

重啓網絡服務:

service network restart

稍等片刻,ssh從新鏈接,而後ifconfig看下網絡相關參數是否正確,最後再ping一下外部網址和你當前物理機器的IP,保證網絡都是通暢的。

最後咱們須要修改下linux的系統時間,這是爲了防止服務器時間不一致,致使不少細微的問題,好比,es集羣master選舉的時間戳問題、log4j輸出的日誌的記錄問題等等。在分佈式系統中,時鐘很是重要。

date -s '20161008 20:47:00'

時區的話若是你須要也能夠設置,這裏暫時不須要。

根據你本身的須要,你clone幾臺機器。按照默認的方式咱們大概約定爲,192.168.0.十、192.168.0.20、192.168.0.30,這三臺機器將組成一個es分佈式集羣。

3.配置

集羣的各個節點咱們已經準備好了,咱們接下來準備配置集羣,讓這三個節點能夠鏈接在一塊兒。這裏涉及的配置比較簡單,只是完成集羣的一個基本經常使用功能,若有特殊的需求能夠自行查看elasticsearch官網或者百度,這方面的資料已經很豐富了。

這裏的一些配置咱們其實已經受益於elasticsearch servicewrapper簡化了不少。

從這裏開始,咱們將對三臺機器進行配置,192.168.160.十、192.168.160.20、192.168.160.30。

3.1.elasticsearch.yml配置

在elasticsearch的config目錄下都是配置文件。導航到 cd /usr/share/elasticsearch/config目錄。

3.1.1.IP訪問限制、默認端口修改9200

這裏有兩個須要提醒下,第一個就是IP訪問限制,第二個就是es實例的默認端口號9200。IP訪問限制能夠限定具體的IP訪問服務器,這有必定的安全過濾做用。

# Set the bind address to a specific IP (IPv4 or IPv6):
#
network.host: 0.0.0.0

若是設置成0.0.0.0則是不限制任何IP訪問。通常在生產的服務器可能會限定幾臺IP,一般用於管理使用。

默認的端口9200在通常狀況下也有點風險,能夠將默認的端口修改爲另一個,這還有一個緣由就是怕開發人員誤操做,鏈接上集羣。固然,若是你的公司網絡隔離作的很好也無所謂。

#
# Set a custom port for HTTP:
#
http.port: 9200
transport.tcp.port: 9300

這裏的9300是集羣內部通信使用的端口,這個也能夠修改掉。由於鏈接集羣的方式有兩種,經過扮演集羣node也是能夠進入集羣的,因此仍是安全起見,修改掉默認的端口。

(備註:記得修改三個節點的相同配置,要否則節點之間沒法創建鏈接工做,也會報錯。)

3.1.2.集羣發現IP列表、node、cluster名稱

緊接着修改集羣節點IP地址,這樣可讓集羣在規定的幾個節點之間工做。elasticsearch,默認是使用自動發現IP機制。就是在當前網段內,只要能被自動感知到的IP就能自動加入到集羣中。這有好處也有壞處。好處就是自動化了,當你的es集羣須要雲化的時候就會很是方便。可是也會帶來一些不穩定的狀況,如,master的選舉問題、數據複製問題。

致使master選舉的因素之一就是集羣有節點進入。當數據複製發生的時候也會影響集羣,由於要作數據平衡複製和冗餘。這裏面能夠獨立master集羣,剔除master集羣的數據節點能力。

固定列表的IP發現有兩種配置方式,一種是互相依賴發現,一種是全量發現。各有優點吧,我是使用的依賴發現來作的。這有個很重要的參考標準,就是你的集羣擴展速度有多快。由於這有個問題就是,當全量發現的時候,若是是初始化集羣會有很大的問題,就是master全局會很長,而後節點之間的啓動速度各不同。因此我採用了靠譜點的依賴發現。

你須要在192.168.0.20的elasticsearch中配置成:

# --------------------------------- Discovery ----------------------------------
#
# Pass an initial list of hosts to perform discovery when new node is started:
# The default list of hosts is ["127.0.0.1", "[::1]"]
#
discovery.zen.ping.unicast.hosts: [ "192.168.0.10:9300" ]

讓他去發現10的機器,以此內推,完成剩下的30的配置。

(備註:網上有不少針對不一樣場景的發現配置,你們能夠就此拋磚引玉,對這個主題感興趣的能夠百度不少資料的。)

而後你須要配置下集羣名稱,就是你當前節點所在集羣的名稱,這有助於你規劃你的集羣。只有集羣名稱同樣才能組成一個邏輯集羣。

# ---------------------------------- Cluster -----------------------------------
#
# Use a descriptive name for your cluster:
#
cluster.name: orderSearch_cluster
#
# ------------------------------------ Node ------------------------------------
#
# Use a descriptive name for the node:
#
node.name: node-2

以此類推,完成另外兩個節點的配置。cluster.name的名稱必須保持同樣。而後分別設置node.name。

3.1.3.master node 啓動切換

這裏有一個小小的經驗分享下,就是我在使用集羣的時候,由於我是虛擬化出來的機器因此常常會關閉和重啓集羣。有時候發現集羣master宣酒會有一個問題就是,若是你的集羣關閉的方式不對,會直接影響下個master選舉的邏輯。

我查了下選舉的大概邏輯,它會根據分片的數據的先後新鮮程度來做爲選舉的一個重要邏輯。(日誌、數據、時間都會做爲集羣master全局的重要指標)

由於考慮到數據一致性問題,固然是用最新的數據節點做爲master,而後進行新數據的複製和刷新其餘node。

若是你發現有一個節點遲遲進不了集羣,能夠嘗試重啓下es服務,讓集羣master從新全局。

3.2.linux 打開最大文件數設置(用做index時候的系統閥值)

在linux系統中,要想使用最大化的系統資源須要向操做系統去申請。因爲elasticsearch須要在index的時候用到大量的文件句柄資源,在原來linux默認的資源下可能會不夠用。因此這裏就須要咱們在使用的時候事先設置好。

這個配置在《ElasticSearch 可擴展的開源彈性搜索解決方案》一書中做爲重點配置介紹,可想而知仍是有很多人踩到過的坑。

這個配置在elasticsearch service wrapper中幫咱們配置好了。

vim /etc/init.d/elasticsearch

42

這個配置會被啓動的時候設置到es實例中去。

這個時候試着重啓三臺機器的es實例,看能不能在_plugin/head中查看到三臺機器的集羣狀態。(記得訪問安裝了head插件的那臺機器,我這裏是在10機器上安裝的)

43

紅色的就是你設置的node.name節點名稱,他們在一個集羣裏工做。

3.3.安裝中文分詞器ik(注意對應版本問題)

此時集羣應該能夠工做了,咱們還須要配置中文分詞器,畢竟咱們使用的中文,elasticsearch的自帶的分詞器對中文分詞支持的不太適合本土。

我是使用的ik分詞器,在github上的地址:https://github.com/medcl/elasticsearch-analysis-ik

先別急的clone,咱們先來看下ik分詞器所支持的elasticsearch對應的版本。

44

咱們使用的elasticsearch版本爲2.3.4。因此咱們要找對應的ik版本,要否則啓動的時候就直接報加載不了對應版本的ik插件。切換到release版本列表,找到對應的版本而後下載下來。

45

你能夠直接下載到Linux機器上,也能夠下載到你的宿主機器上而後複製到虛擬機上。若是你的elasticsearch版本是最新的,你可能就須要下載ik源碼下來編譯以後再部署。

固然你可使用git+maven的方式安裝,詳細的安裝步驟能夠參見:https://github.com/medcl/elasticsearch-analysis-ik

46

這也比較簡單,我這裏就不重複了。安裝好以後重啓es實例。

3.4.elasticsearch集羣規劃(master儘可能不要做爲data節點,獨立master爲commander)

能夠這樣規劃一個集羣。master能夠兩臺,這兩個節點都是做爲commander統籌集羣層面的事務,取消這兩臺的data權利。而後在規劃出三個節點的data集羣,取消這三個節點的master權利。讓他們安心的作好數據存儲和檢索服務。這是最小的粒度集羣結構,能夠基於這個結構進行擴展。

這樣作有一個好處,就是職責分明,能夠最大限度的防止master節點有事data節點,致使不穩定因素髮生。好比,data節點的數據複製,數據平衡,路由等等,直接影響master的穩定性。進而可能會發生腦裂問題。

4.開發

咱們進入最後一個環節,全部的東西都準備好了,咱們是否是應該操做操做這個強大的搜索引擎了。come on。

4.1.接入集羣方式

說到集羣,就會有相應的問題隨之而來,高可用、高併發、大數據、橫向擴展等等。那麼elasticsearh的集羣大概是個什麼原理。

首先client的在接入集羣的時候爲了保證高可用不是採用 vip漂移實現高可用,相似keepalived 這種。elasticserach在客戶端鏈接的時候使用配置多個IP的方式來首先客戶端sdk的負載。這已是分佈式系統常見的作法了。只有相似DB、cache這樣中心化的集羣須要使用,覺得是它們的使用特色決定了。(數據一致性)

elasticsearch的全部節點均可以處理請求,節點越多併發QPS越高,相應的TPS會降低,可是降低的性能不是根據節點的正比例來的。(它使用quorum(法定人數)算法,保證可用性。)因此節點的複製不是咱們想固然的那樣。

鏈接es集羣的方式有兩種,性能高點的就是直接將client扮演成cluster node進去集羣,同時取消本身的data權利。這一般都是用來作二次開發用的,你能夠github clone下來源碼添加本身的場景而後進入集羣,可能你會干預選舉,也可能會干預sharding,也可能會干預集羣平衡。

elasticsearch 使用本身定義的一套DSL語言,使用restful方式使用,根據不一樣的rest end point來使用。好比,_search、_cat、_query等等。這些都是指點的rest端點。而後你能夠post dsl到elasticsearch服務器處理。

elasticsearch search dsl:https://www.elastic.co/guide/en/elasticsearch/reference/current/search.html

elasticsearch dsl api:http://elasticsearch-dsl.readthedocs.io/en/latest/

例:

POST _search
{
"query": {
        "bool" : {
            "must" : {
                "query_string" : {
                    "query" : "query some test"
                }
            },
            "filter" : {
                "term" : { "user" : "plen" }
            }
        }
    }
}

可讀性很強,在經過chrome插件Sense輔助編寫,會比較方便。

47

可是通常都不會這麼作,通常都是使用sdk鏈接集羣。直接使用dsl的大可能是在測試數據的時候或者在調試的時候。看sdk輸出的dsl是否正確。就跟調試SQL差很少。

4.1.1.net nest使用(使用pool鏈接es集羣)

.NET程序有開源包nest,直接在Nuget上搜索安裝便可。

48

官網地址:https://www.elastic.co/guide/en/elasticsearch/client/net-api/1.x/nest-connecting.html

使用pool高可用的方式鏈接集羣。

var node1 = new Uri("http://192.168.0.10:9200");
var node2 = new Uri("http://192.168.0.20:9200");
var node3 = new Uri("http://192.168.0.30:9200");

var connectionPool = new SniffingConnectionPool(new[] { node1, node2, node3 });

var settings = new ConnectionSettings(connectionPool);

var client = new ElasticClient(settings);

此時使用client對象就是軟負載的,它會根據必定的策略來均衡的鏈接後臺三個node。(多是平均的、多是權重的,具體沒研究)

4.1.2.java jest使用

java 的話我是使用jest。咱們建立一個maven項目,而後添加jest 相應的jar包maven引用。

<dependencies>
<dependency>
<groupId>io.searchbox</groupId>
<artifactId>jest</artifactId>
<version>2.0.3</version>
</dependency>
<dependency>
<groupId>org.elasticsearch</groupId>
<artifactId>elasticsearch</artifactId>
<version>2.3.5</version>
</dependency>
</dependencies>
 
JestClientFactory factory = new JestClientFactory();

List<String> nodes = new LinkedList<String>();
nodes.add("http://192.168.0.10:9200");
nodes.add("http://192.168.0.20:9200");
nodes.add("http://192.168.0.30:9200");

HttpClientConfig config = new HttpClientConfig.Builder(nodes).multiThreaded(true).build();
factory.setHttpClientConfig(config);
JestHttpClient client = (JestHttpClient) factory.getObject();

SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
searchSourceBuilder.query(QueryBuilders.queryStringQuery("中華人名共和國"));
searchSourceBuilder.field("name");

Search search = new Search.Builder(searchSourceBuilder.toString()).build();

JestResult rs = client.execute(search);
System.out.println(rs.getJsonString());
 
49
 

{
  "took": 71,
  "timed_out": false,
  "_shards": {
    "total": 45,
    "successful": 45,
    "failed": 0
  },
  "hits": {
    "total": 6,
    "max_score": 0.6614378,
    "hits": [
      {
        "_index": "posts",
        "_type": "post",
        "_id": "1",
        "_score": 0.6614378,
        "fields": {
          "name": [
            "王清培"
          ]
        }
      },
      {
        "_index": "posts",
        "_type": "post",
        "_id": "5",
        "_score": 0.57875806,
        "fields": {
          "name": [
            "王清培"
          ]
        }
      },
      {
        "_index": "posts",
        "_type": "post",
        "_id": "2",
        "_score": 0.57875806,
        "fields": {
          "name": [
            "王清培"
          ]
        }
      },
      {
        "_index": "posts",
        "_type": "post",
        "_id": "AVaKENIckgl39nrAi9V5",
        "_score": 0.57875806,
        "fields": {
          "name": [
            "王清培"
          ]
        }
      },
      {
        "_index": "class",
        "_type": "student",
        "_id": "1",
        "_score": 0.17759356
      },
      {
        "_index": "posts",
        "_type": "post",
        "_id": "3",
        "_score": 0.17759356,
        "fields": {
          "name": [
            "王清培"
          ]
        }
      }
    ]
  }
}

返回的數據橫跨多個索引。你能夠經過不斷的debug來查看連接IP是否是會啓動切換,是否是會起到可用性的做用。

4.2.index開發

索引開發通常步驟比較簡單,首先創建對應的mapping映射,配置好各個type中的field的特性。

4.2.1.mapping 配置

mapping是es實例用來在index的時候,做爲各個字段的操做依據。好比,username,這個字段是否要索引、是否要存儲、長度大小等等。雖然elasticsearch能夠動態的處理這些,可是出於管理和運維的目的仍是建議創建對應的索引映射,這個映射能夠保存在文件裏,以便未來重建索引用。

POST /demoindex
{
   "mappings": {
      "demotype": {
         "properties": {
            "contents": {
               "type": "string",
               "index": "analyzed"
            },
            "name": {
               "store": true,
               "type": "string",
               "index": "analyzed"
            },
            "id": {
               "store": true,
               "type": "long"
            },
            "userId": {
               "store": true,
               "type": "long"
            }
         }
      }
   }
}

這是一個最簡單的mapping,定義了索引名稱爲demoindex,類型爲demotype的mapping。各個字段分別是一個json對象,裏面有類型有索引是否須要。

這個在sense裏編輯,而後直接post提交。

{
   "acknowledged": true
}

50

經過查看建立好的索引信息確認是不是你提交的mapping設置。

4.2.2.mapping template配置

每次都經過手動的建立相似的mapping始終是個低效率的事情,elasticserach支持創建mapping模板,而後讓模板自動匹配使用哪一個mapping定義。

PUT log_template
{
   "order": 10,
   "template": "log_*",
   "settings": {
      "index": {
         "number_of_replicas": "2",
         "number_of_shards": "5"
      }
   },
   "mappings": {
      "_default_": {
         "_source_": {
            "enable": false
         }
      }
   }
}

建立一個log類型的索引mapping。咱們設置了兩個基本的屬性, "number_of_replicas": "2" 複製分數, "number_of_shards": "5" 分片個數。mappings裏面設置了source字段默認不開啓。

當咱們提交全部以「log_xxx」名字格式的索引時將自動命中這個mapping模板。

能夠經過_template rest端點查看已經存在的mapping模板,或者經過head插件的右上角的」信息」裏面的」模板」菜單查看。

{
  "mq_template" : {
    "order" : 10,
    "template" : "mq*",
    "settings" : {
      "index" : {
        "number_of_shards" : "5",
        "number_of_replicas" : "2"
      }
    },
    "mappings" : {
      "_default_" : {
        "_source_" : {
          "enable" : false
        }
      }
    },
    "aliases" : { }
  },
  "log_template" : {
    "order" : 10,
    "template" : "log_*",
    "settings" : {
      "index" : {
        "number_of_shards" : "5",
        "number_of_replicas" : "2"
      }
    },
    "mappings" : {
      "_default_" : {
        "_source_" : {
          "enable" : false
        }
      }
    },
    "aliases" : { }
  },
  "error_template" : {
    "order" : 10,
    "template" : "error_*",
    "settings" : {
      "index" : {
        "number_of_shards" : "5",
        "number_of_replicas" : "2"
      }
    },
    "mappings" : {
      "_default_" : {
        "_source_" : {
          "enable" : false
        }
      }
    },
    "aliases" : { }
  }
}
這一般用於一些業務不想關的存儲中,好比日誌、消息、重大錯誤預警等等均可以設置,只要這些重複的mapping是有規律的。

4.2.3.index routing索引路由配置

在es對數據進行分片的時候是採用hash取餘的方式進行的,因此你能夠傳遞一個固定的key,那麼這個key將做爲你固定的路由規則。在建立mappings的時候能夠設置這個_routing參數。這在1.0的版本中是這樣的設置的,也就是說你當前type下的全部document都是隻能用着這個路由key進行。可是在es2.0以後routing跟着index元數據走,這樣能夠控制單個index的路由規則,在提交index的時候能夠單獨制定_routing參數,而不是直接設置mappings上。

在2.0以後已經再也不支持mappings配置_routing參數了。

https://www.elastic.co/guide/en/elasticsearch/reference/current/breaking_20_mapping_changes.html#migration-meta-fields

在1.0裏,好比,你能夠將userid做爲routing key,這樣就能夠將當前用戶的全部數據都在一個分片上,當查詢的時候就會加快查詢速度。

{
  "mappings": {
    "post": {
      "_routing": {
        "required": true,
        "path":"userid"
      },
      "properties": {
        "contents": {
          "type": "string"
        },
        "name": {
          "store": true,
          "type": "string"
        },
        "id": {
          "store": true,
          "type": "long"
        },
        "userId": {
          "store": true,
          "type": "long"
        }
      }
    }
  }
}

這個_routing是設置在mapping上的,做用於全部type。會使用userid做爲sharding的key。可是在2.0裏,是必須明確指定routing path的。

51

在你添加好mappings以後,建立當前索引的時候必須指定&routing=xxx,參數。這有個很大的好處就是你能夠根據不一樣的業務維度自由調整分片策略。

5.總結

孰能生巧,分佈式的東西仍是有不少比較特殊和挑戰的地方,尤爲是他的分佈性,同時還要解決不少一致性問題、可用性問題等等。我對elasticsearch的使用也只是個簡單的皮毛而已,它的分佈式特性深深的吸引了我,期待下篇文章更加深刻的分享。好比,routing的內部原理,複製平衡算法等等。這篇文章是我對elasticsearch使用的一個簡單的總結,但願能對各位博友有點幫助,謝謝閱讀,謝謝支持。

參考書籍《ElasticSearch 可擴展的開源彈性搜索解決方案》、《ElastcSearch權威指南》

相關文章
相關標籤/搜索