前言
本篇主要是介紹docker-compose搭建Es的實踐,關於Es的深入理論知識不會在這篇講太多,只會根據官網簡單介紹一下es及kibana的用途(以下理論出自官網)。
什么是 Elasticsearch?
Elasticsearch 是一個分布式的開源搜索和分析引擎,適用於所有類型的數據,包括文本、數字、地理空間、結構化和非結構化數據。Elasticsearch 在Apache Lucene 的基礎上開發而成,由 Elasticsearch N.V.(即現在的 Elastic)於 2010 年首次發布。Elasticsearch 以其簡單的 REST 風格 API、分布式特性、速度和可擴展性而聞名,是 Elastic Stack 的核心組件;Elastic Stack 是適用於數據采集、充實、存儲、分析和可視化的一組開源工具。人們通常將Elastic Stack 稱為 ELK Stack(代指 Elasticsearch、Logstash 和 Kibana),目前 Elastic Stack 包括一系列豐富的輕量型數據采集代理,這些代理統稱為Beats,可用來向 Elasticsearch 發送數據。
Elasticsearch 的用途是什么?
Elasticsearch 在速度和可擴展性方面都表現出色,而且還能夠索引多種類型的內容,這意味着其可用於多種用例:
- 應用程序搜索
- 網站搜索
- 企業搜索
- 日志處理和分析
- 基礎設施指標和容器監測
- 應用程序性能監測
- 地理空間數據分析和可視化
- 安全分析
- 業務分析
Elasticsearch 的工作原理是什么?
原始數據會從多個來源(包括日志、系統指標和網絡應用程序)輸入到 Elasticsearch 中。數據采集指在 Elasticsearch 中進行索引之前解析、標准化並充實這些原始數據的過程。這些數據在 Elasticsearch 中索引完成之后,用戶便可針對他們的數據運行復雜的查詢,並使用聚合來檢索自身數據的復雜匯總。在 Kibana 中,用戶可以基於自己的數據創建強大的可視化,分享儀表板,並對 Elastic Stack 進行管理。
Elasticsearch 索引是什么?
Elasticsearch 索引指相互關聯的文檔集合。Elasticsearch 會以 JSON 文檔的形式存儲數據。每個文檔都會在一組鍵(字段或屬性的名稱)和它們對應的值(字符串、數字、布爾值、日期、數值組、地理位置或其他類型的數據)之間建立聯系。
Elasticsearch 使用的是一種名為倒排索引的數據結構,這一結構的設計可以允許十分快速地進行全文本搜索。倒排索引會列出在所有文檔中出現的每個特有詞匯,並且可以找到包含每個詞匯的全部文檔。
在索引過程中,Elasticsearch 會存儲文檔並構建倒排索引,這樣用戶便可以近實時地對文檔數據進行搜索。索引過程是在索引 API 中啟動的,通過此API 您既可向特定索引中添加 JSON 文檔,也可更改特定索引中的 JSON 文檔。
Kibana 的用途是什么?
Kibana 是一款適用於 Elasticsearch 的數據可視化和管理工具,可以提供實時的直方圖、線形圖、餅狀圖和地圖。Kibana 同時還包括諸如 Canvas 和Elastic Maps 等高級應用程序;Canvas 允許用戶基於自身數據創建定制的動態信息圖表,而 Elastic Maps 則可用來對地理空間數據進行可視化。
為何使用 Elasticsearch?
Elasticsearch 很快。 由於 Elasticsearch 是在 Lucene 基礎上構建而成的,所以在全文本搜索方面表現十分出色。Elasticsearch 同時還是一個近實時的搜索平台,這意味着從文檔索引操作到文檔變為可搜索狀態之間的延時很短,一般只有一秒。因此,Elasticsearch 非常適用於對時間有嚴苛要求的用例,例如安全分析和基礎設施監測。
Elasticsearch 具有分布式的本質特征。 Elasticsearch 中存儲的文檔分布在不同的容器中,這些容器稱為分片,可以進行復制以提供數據冗余副本,以防發生硬件故障。Elasticsearch 的分布式特性使得它可以擴展至數百台(甚至數千台)服務器,並處理 PB 量級的數據。
Elasticsearch 包含一系列廣泛的功能。 除了速度、可擴展性和彈性等優勢以外,Elasticsearch 還有大量強大的內置功能(例如數據匯總和索引生命周期管理),可以方便用戶更加高效地存儲和搜索數據。
Elastic Stack 簡化了數據采集、可視化和報告過程。 通過與 Beats 和 Logstash 進行集成,用戶能夠在向 Elasticsearch 中索引數據之前輕松地處理數據。同時,Kibana 不僅可針對 Elasticsearch 數據提供實時可視化,同時還提供 UI 以便用戶快速訪問應用程序性能監測 (APM)、日志和基礎設施指標等數據。
Docker-compose搭建步驟
1.環境准備
docker、docker-compose、lunux。版本問題應該不大,我用的是Docker version 18.09.0, build 4d60db4、docker-compose version 1.23.0-rc3, buildea3d406e、centos7.2。
elasticsearch:7.2.0及kibana:7.2.0可以去官方鏡像倉庫拉取docker pull elasticsearch:7.2.0、docker pull kibana:7.2.0,或者后續我會把離線的tar包上傳到github上面,直接下載下來docker load --input xxx.tar到服務器即可。
完成准備之后,docker images看一下,那兩個鏡像是否搞定了。

2.編寫docker-compose文件,我這里命名es.yml
version: '3'
services:
elasticsearch_n0:
image: elasticsearch:7.2.0
container_name: elasticsearch_n0
privileged: true
environment:
- cluster.name=elasticsearch-cluster
- node.name=node0
- node.master=true
- node.data=true
- bootstrap.memory_lock=true
- search.max_buckets=100000000
- http.cors.enabled=true
- http.cors.allow-origin=*
- cluster.initial_master_nodes=node0
- "ES_JAVA_OPTS=-Xms1024m -Xmx1024m"
- "discovery.zen.ping.unicast.hosts=elasticsearch_n0,elasticsearch_n1,elasticsearch_n2"
# 如果是拆分版,這里必須填寫宿主機ip
#- discovery.zen.ping.unicast.hosts=192.168.133.68,192.168.133.75,192.168.133.77
- "discovery.zen.minimum_master_nodes=2"
- discovery.zen.ping_timeout=120s
- client.transport.ping_timeout=60s
# 如果是拆分版,這條配置必須加上,指定當前節點訪問的ip
#- network.publish_host=192.168.133.68
ulimits:
memlock:
soft: -1
hard: -1
volumes:
- /etc/localtime:/etc/localtime
- /data/base/es/data/node0:/usr/share/elasticsearch/data
- ./logs/node0:/usr/share/elasticsearch/logs
ports:
- 9200:9200
- 9300:9300
networks:
- esnet
elasticsearch_n1:
image: elasticsearch:7.2.0
container_name: elasticsearch_n1
privileged: true
environment:
- cluster.name=elasticsearch-cluster
- node.name=node1
- node.master=true
- node.data=true
- bootstrap.memory_lock=true
- search.max_buckets=100000000
- http.cors.enabled=true
- http.cors.allow-origin=*
- cluster.initial_master_nodes=node0
- "ES_JAVA_OPTS=-Xms1024m -Xmx1024m"
- "discovery.zen.ping.unicast.hosts=elasticsearch_n0,elasticsearch_n1,elasticsearch_n2"
# 如果是拆分版,這里必須填寫宿主機ip
#- discovery.zen.ping.unicast.hosts=192.168.133.68,192.168.133.75,192.168.133.77
- "discovery.zen.minimum_master_nodes=2"
- discovery.zen.ping_timeout=120s
- client.transport.ping_timeout=60s
# 如果是拆分版,這條配置必須加上,指定當前節點訪問的ip
#- network.publish_host=192.168.133.75
ulimits:
memlock:
soft: -1
hard: -1
volumes:
- /etc/localtime:/etc/localtime
- /data/base/es/data/node1:/usr/share/elasticsearch/data
- ./logs/node1:/usr/share/elasticsearch/logs
ports:
- 9201:9200
- 9301:9300
networks:
- esnet
elasticsearch_n2:
image: elasticsearch:7.2.0
container_name: elasticsearch_n2
privileged: true
environment:
- cluster.name=elasticsearch-cluster
- node.name=node2
- node.master=true
- node.data=true
- bootstrap.memory_lock=true
- search.max_buckets=100000000
- http.cors.enabled=true
- http.cors.allow-origin=*
- cluster.initial_master_nodes=node0
- "ES_JAVA_OPTS=-Xms1024m -Xmx1024m"
- "discovery.zen.ping.unicast.hosts=elasticsearch_n0,elasticsearch_n1,elasticsearch_n2"
# 如果是拆分版,這里必須填寫宿主機ip
#注:端口非9200的節點, ip后需加端口號, 因 es 默認識別端口是9200
#- discovery.zen.ping.unicast.hosts=192.168.133.68,192.168.133.75,192.168.133.77
- "discovery.zen.minimum_master_nodes=2"
- discovery.zen.ping_timeout=120s
- client.transport.ping_timeout=60s
# 如果是拆分版,這條配置必須加上,指定當前節點訪問的ip
#- network.publish_host=192.168.133.77
ulimits:
memlock:
soft: -1
hard: -1
volumes:
- /etc/localtime:/etc/localtime
- /data/base/es/data/node2:/usr/share/elasticsearch/data
- ./logs/node2:/usr/share/elasticsearch/logs
ports:
- 9202:9200
- 9302:9300
networks:
- esnet
kibana:
image: kibana:7.2.0
container_name: kibana
ports:
- 5601:5601
volumes:
- /etc/localtime:/etc/localtime
-./kibana/kibana.yml:/usr/share/kibana/config/kibana.yml:rw
depends_on:
- elasticsearch_n0
networks:
- esnet
networks:
esnet:
external: true
a.集群名稱,默認為elasticsearch:
cluster.name: elasticsearch
b.節點名稱,es啟動時會自動創建節點名稱,但你也可進行配置:
node.name: “node0”
c.是否作為主節點,每個節點都可以被配置成為主節點,默認值為true:
node.master: true
d.是否存儲數據,即存儲索引片段,默認值為true:
node.data: true
master和data同時配置會產生一些奇異的效果:
1) 當master為false,而data為true時,會對該節點產生嚴重負荷;
2) 當master為true,而data為false時,該節點作為一個協調者;
3) 當master為false,data也為false時,該節點就變成了一個負載均衡器。
4) 當master為true,data也為true時,這種組合表示這個節點即有成為主節點的資格,又存儲數據。
附上kibana.yml的配置
# ## ** THIS IS AN AUTO-GENERATED FILE ** ## # # # Default Kibana configuration for docker target server.name: kibana server.host: "0" #這里寫你的es第一個node的地址 elasticsearch.hosts: [ "http://10.10.10.7:9200" ] xpack.monitoring.ui.container.elasticsearch.enabled: true i18n.locale: zh-CN
3.創建es的data目錄以及log目錄



這里我建議最好手動創建es的data掛載目錄以及log的掛載目錄。為什么呢?因為一般來說,data目錄是掛載在磁盤陣列后的一些獨立的硬盤里面,跟系統盤是分開的。一般是以root的用戶創建的,普通用戶一般不具備讀寫權限。直接執行docker-compose up -d ,會自動創建掛載目錄,但是,可能不具備讀寫權限,這個時候,es是起不來的,不信你到時候看看日志就知道了,會報你沒有權限操作某個某個文件夾。
所以確保萬無一失,最好把所有掛載的目錄,先提前創建好,然后附上讀寫權限。
4.修改sysctl.conf配置(非常重要)
有些朋友可能會漏掉這一步,發現搭建ES起來之后,查看ES日志,會發現仍然有報錯。Ubuntu elasticsearch max virtual memory areas vm.max_map_count [65530] is too low, increase to at least [262144] ,問題翻譯過來就是:elasticsearch用戶擁有的內存權限太小,至少需要262144
很顯然,就是漏掉了配置sysctl.conf的 vm.max_map_count。這什么玩意?這是限制一個進程可以擁有的VMA(虛擬內存區域)的數量。具體還有什么深層次的解釋或者啥用處,就另行百度了。廢話不多說了,配置也很簡單
1、切換到root用戶修改配置sysctl.conf
vi /etc/sysctl.conf
2、添加下面配置:
vm.max_map_count=655360
3、並執行命令:
sysctl -p
5.運行es以及kibana
好了,准備工作都完全搞定了。就跑起來了
執行命令 docker-compose -f es.yml up -d
檢查一下狀態,是否都起來了呢

看起來沒什么問題,也可以用docker ps看狀態,只是我服務器容器太多了,docker ps不太好看,見仁見智。
分別用docker logs -f elasticsearch_n* 看一下各個容器日志,發現沒什么問題。說明ES搭建已經完成了。
這里說一下kibana,因為剛啟動容器組的時候,kibana沒有那么快監聽到es集群,等個一兩分鍾這樣再打開kibana頁面就可以了。


大概是這個樣子,頁面做得好像蠻好看的呢。這個就是es的一個監控平台以及客戶端工具。可以理解成Mysql的sqlyong或者navicate。這個東西怎么用,到時候我會出一篇教程。
溫馨提示一下: 這是單機版的,拆分版的你們可以參照docker-compose上面的配置,自己知道怎么拆分了吧,多的不說了
OK,Docker-compose搭建Elasticsearch集群及Kibana就這么簡單,大功告成,接下來干嘛?肯定是使用啊,網上有各種springboot整合es的教程,或者到時候我會出一片springboot整合es的博客,網上推薦,es7.0以后,不要再用springboot-data-elasticsearch方式了,而是用springboot整合“elasticsearch-rest-high-level-client”這個工具去訪問es,我呢,在項目上也是這么做的。然后git上面有很多牛人,專門轉對“elasticsearch-rest-high-level-client”這個工具做了一層自己的封裝,也就是自己造輪子。這里推薦一下,這個鏈接https://gitee.com/zxporz/ESClientRHL/tree/es7。我就是把這位熱心博主的自制插件"EsClientRHL"拿過來,然后改了一下里面的源碼,或者加一些這個插件本身沒有功能,就加以使用了。后續我會在springboot整合es的博客里面演示怎么進行增刪改查(查涉及到一下復雜的條件檢索)、聚合統計、多桶聚合等操作。
