Elastic Stack簡介
如果你沒有聽說過Elastic Stack,那你一定聽說過ELK,實際上ELK是三款軟件的簡稱,分別是Elasticsearch、Logstash、Kibana組成,在發展的過程中,又有新成員Beats的加入,所以就形成了Elastic Stack。所以說,ELK是舊的稱呼,Elastic Stack是新的名字。
全新的Elastic Stack技術棧包括:
- Elasticsearch
Elasticsearch 基於java,是個開源分佈式搜索引擎,它的特點有:分佈式,零配置,自動發現,索引自動分片,索引副本機制,restful風格接口,多數據源,自動搜索負載等。 - Logstash
Logstash 基於java,是一個開源的用於收集,分析和存儲日誌的工具。 - Kibana
Kibana 基於nodejs,也是一個開源和免費的工具,Kibana可以爲 Logstash 和 ElasticSearch 提供的日誌分析友好的 Web 界面,可以彙總、分析和搜索重要數據日誌。 - Beats
Beats是elastic公司開源的一款採集系統監控數據的代理agent,是在被監控服務器上以客戶端形式運行的數據收集器的統稱,可以直接把數據發送給Elasticsearch或者通過Logstash發送給Elasticsearch,然後進行後續的數據分析活動。
Beats由如下組成:
1.Packetbeat:是一個網絡數據包分析器,用於監控、收集網絡流量信息,Packetbeat嗅探服務器之間的流量,解析應用層協議,並關聯到消息的處理,其支持ICMP (v4 and v6)、DNS、HTTP、Mysql、PostgreSQL、Redis、MongoDB、Memcache等協議;
2.Filebeat:用於監控、收集服務器日誌文件,其已取代 logstash forwarder;
3.Metricbeat:可定期獲取外部系統的監控指標信息,其可以監控、收集 Apache、HAProxy、MongoDBMySQL、Nginx、PostgreSQL、Redis、System、Zookeeper等服務;
4.Winlogbeat:用於監控、收集Windows系統的日誌信息;
Elasticsearch安裝和使用
1.簡介
ElasticSearch是一個基於Lucene的搜索服務器。它提供了一個分佈式多用戶能力的全文搜索引擎,基於RESTful web接口。Elasticsearch是用Java語言開發的,並作爲Apache許可條款下的開放源碼發佈,是一種流行的企業級搜索引擎。ElasticSearch用於雲計算中,能夠達到實時搜索,穩定,可靠,快速,安裝使用方便,官網:https://www.elastic.co/cn/pro...
2.安裝
下載地址:https://www.elastic.co/cn/dow...
1)單機版安裝
#創建jello用戶,Elasticsearch不支持root用戶運行
useradd jello
#將指定文件的擁有者改爲指定的用戶或組
chowm -R jello:jello /java
#解壓安裝包
tar -zxvf elasticsearch-6.5.4.tar.gz
#修改配置文件
vi config/elasticsearch.yml
network.host: 47.101.127.45 #綁定的地址
#說明:在Elasticsearch中如果,network.host不是localhost或者127.0.0.1的話,就會認爲是生產環境,會對環境的要求比較高,我們的測試環境不一定能夠滿足,一般情況下需要修改2處配置,如下:
#1:修改jvm啓動參數vi conf/jvm.options
-Xms128m#根據自己機器情況修改
-Xmx128m
#2:單個進程中的最大線程數vi /etc/sysctl.conf
vm.max_map_count=655360
修改完執行sysctl -p
#啓動ES服務
cd bin
./elasticsearch 或 ./elasticsearch -d#後臺系統
#通過訪問http://47.101.127.45:9200進行測試,看到如下信息,就說明ES啓動成功了
2.使用docker安裝
#拉取鏡像
docker pull elasticsearch:6.5.4
#創建容器
docker create --name elasticsearch --net host -e"discovery.type=single-node"-e"network.host=47.101.127.45" elasticsearch:6.5.4
#啓動
docker start elasticsearch
#查看日誌
docker logs --tail 10 elasticsearch
3.elasticsearch-head安裝
由於ES官方並沒有爲ES提供界面管理工具,僅僅是提供了後臺的服務。elasticsearch-head是一個爲ES開發的一個頁面客戶端工具,其源碼託管於GitHub,地址爲:https://github.com/mobz/elast...,這裏使用docker安裝
#拉取鏡像
docker pull mobz/elasticsearch-head:5
#創建容器
docker create --name elasticsearch-head -p 9100:9100 mobz/elasticsearch-head:5
#啓動容器
docker start elasticsearch-head
通過瀏覽器進行訪問:
注意:由於前後端分離開發,所以會存在跨域問題,需要在服務端做CORS的配置,如下:
vim elasticsearch.yml
http.cors.enabled: true
http.cors.allow-origin: "*"
若head連接Elasticsearch數據瀏覽模塊不能顯示數據,參考https://blog.csdn.net/qq_4110...
基本概念
1)索引
- 索引(index)是Elasticsearch對邏輯數據的邏輯存儲,所以它可以分爲更小的部分。
- 可以把索引看成關係型數據庫的表,索引的結構是爲快速有效的全文索引準備的,特別是它不存儲原始值。
- 可以把Elasticsearch的索引看成MongoDB裏的一個集合。
- Elasticsearch可以把索引存放在一臺機器或者分散在多臺服務器上,每個索引有一或多個分片(shard),每個分片可以有多個副本(replica)。
2)文檔
- 存儲在Elasticsearch中的主要實體叫文檔(document)。用關係型數據庫來類比的話,一個文檔相當於數據庫表中的一行記錄。
- Elasticsearch和MongoDB中的文檔類似,都可以有不同的結構,但Elasticsearch的文檔中,相同字段必須有相同類型。
- 文檔由多個字段組成,每個字段可能多次出現在一個文檔裏,這樣的字段叫多值字段(multivalued)。
- 每個字段的類型,可以是文本、數值、日期等。字段類型也可以是複雜類型,一個字段包含其他子文檔或者數組。
3)映射
所有文檔寫進索引之前都會先進行分析,如何將輸入的文本分割爲詞條、哪些詞條又會被過濾,這種行爲叫做映射(mapping)。一般由用戶自己定義規則。
4)文檔類型
- 在Elasticsearch中,一個索引對象可以存儲很多不同用途的對象。例如,一個博客應用程序可以保存文章和評論。
- 每個文檔可以有不同的結構。
- 不同的文檔類型不能爲相同的屬性設置不同的類型。例如,在同一索引中的所有文檔類型中,一個叫title的字段必須具有相同的類型。
RESTful API
在Elasticsearch中,提供了功能豐富的RESTful API的操作,包括基本的CRUD、創建索引、刪除索引等操作。
1)創建非結構化索引
在Lucene中,創建索引是需要定義字段名稱以及字段的類型的,在Elasticsearch中提供了非結構化的索引,就是不需要創建索引結構,即可寫入數據到索引中,實際上在Elasticsearch底層會進行結構化操作,此操作對用戶是透明的。
#創建空索引
PUT http://47.101.127.45:9200/haoke
{
"settings": {
"index": {
"number_of_shards": "2",#分片數
"number_of_replicas": "0"#副本數
}
}
}
#響應結果
{
"acknowledged": true,
"shards_acknowledged": true,
"index": "demo"
}
#刪除索引
curl -XDELETE 'http://47.101.129.45:9200/haoke?pretty'
#響應結果
{
"acknowledged" : true
}
2.插入數據
URL規則:POST http://47.101.129.45:9200/{索引}/{類型}/{id}
curl -POST 'http://47.101.129.45:9200/haoke/user/1001?pretty' -H 'Content-Type: application/json' -d '{"id":1001,"name":"張三","age":20,"sex":"男"}'
#響應
{
"_index" : "haoke",
"_type" : "user",
"_id" : "1001",
"_version" : 1,
"result" : "created",
"_shards" : {
"total" : 2,
"successful" : 1,
"failed" : 0
},
"_seq_no" : 6,
"_primary_term" : 2
}
說明:非結構化的索引,不需要事先創建,直接插入數據默認創建索引。
#不指定id插入數據
curl -POST 'http://47.101.129.45:9200/haoke/user?pretty' -H 'Content-Type: application/json' -d '{"id":1002,"name":"張三","age":20,"sex":"男"}'
3.更新數據
在Elasticsearch中,文檔數據是不爲修改的,但是可以通過覆蓋的方式進行更新。
curl -PUT 'http://47.101.129.45:9200/haoke/user/1001?pretty' -H 'Content-Type: application/json' -d '{"id":1001,"name":"張三","age":21,"sex":"女"}'
//響應
{
"_index" : "haoke",
"_type" : "user",
"_id" : "1001",
"_version" : 2, #版本號進行+1
"result" : "updated",
"_shards" : {
"total" : 2,
"successful" : 1,
"failed" : 0
},
"_seq_no" : 7,
"_primary_term" : 2
}
可以看到數據已經被覆蓋了。在內部,依然會查詢到這個文檔數據,然後進行覆蓋操作,步驟如下:1. 從舊文檔中檢索JSON 2. 修改它 3. 刪除舊文檔 4. 索引新文檔
#局部更新,注意:這裏多了_update標識
curl -PUT 'http://47.101.129.45:9200/haoke/user/1001/_update?pretty' -H 'Content-Type: application/json' -d '{"doc":{"age":25}}'
#響應
{
"_index" : "haoke",
"_type" : "user",
"_id" : "1001",
"_version" : 3,
"result" : "updated",
"_shards" : {
"total" : 2,
"successful" : 1,
"failed" : 0
},
"_seq_no" : 8,
"_primary_term" : 2
}
4.刪除數據
在Elasticsearch中,刪除文檔數據,只需要發起DELETE請求即可。
curl -XDELETE 'http://47.101.129.45:9200/haoke/user/1002?pretty'
#響應
{
"_index" : "haoke",
"_type" : "user",
"_id" : "1001",
"_version" : 4,
"result" : "deleted",
"_shards" : {
"total" : 2,
"successful" : 1,
"failed" : 0
},
"_seq_no" : 9,
"_primary_term" : 2
}
需要注意的是,result表示已經刪除,version也更加了。如果刪除一條不存在的數據,會響應404:
刪除一個文檔也不會立即從磁盤上移除,它只是被標記成已刪除。Elasticsearch將會在你之後添加更多索引的時候纔會在後臺進行刪除內容的清理。
5.搜索數據
#根據id搜索數據
curl -GET "http://47.101.129.45:9200/haoke/user/4xP3P24BpJzEX51oeOPv?pretty"
#響應
{
"_index" : "haoke",
"_type" : "user",
"_id" : "4xP3P24BpJzEX51oeOPv",
"_version" : 1,
"found" : true,
"_source" : {
"id" : 1002,
"name" : "張三",
"age" : 20,
"sex" : "男"
}
}
#搜索全部數據
curl -GET "http://47.101.129.45:9200/haoke/user/_search?pretty
#響應:(默認返回10條數據)
{
"took" : 1,
"timed_out" : false,
"_shards" : {
"total" : 5,
"successful" : 5,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : 3,
"max_score" : 1.0,
"hits" : [
{
"_index" : "haoke",
"_type" : "user",
"_id" : "1001",
"_score" : 1.0,
"_source" : {
"id" : 1001,
"name" : "張三",
"age" : 20,
"sex" : "男"
}
},
{
"_index" : "haoke",
"_type" : "user",
"_id" : "4xP3P24BpJzEX51oeOPv",
"_score" : 1.0,
"_source" : {
"id" : 1002,
"name" : "張三",
"age" : 20,
"sex" : "男"
}
},
{
"_index" : "haoke",
"_type" : "user",
"_id" : "1003",
"_score" : 1.0,
"_source" : {
"id" : 1003,
"name" : "王五",
"age" : 30,
"sex" : "女"
}
}
]
}
}
#關鍵字搜素數據(查詢年齡等於20的用戶)
curl -GET "http://47.101.129.45:9200/haoke/user/_search?pretty&q=age:30"
#響應
{
"took" : 2,
"timed_out" : false,
"_shards" : {
"total" : 5,
"successful" : 5,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : 1,
"max_score" : 1.0,
"hits" : [
{
"_index" : "haoke",
"_type" : "user",
"_id" : "1003",
"_score" : 1.0,
"_source" : {
"id" : 1003,
"name" : "王五",
"age" : 30,
"sex" : "女"
}
}
]
}
}
6.DSL搜索
Elasticsearch提供豐富且靈活的查詢語言叫做DSL查詢(Query DSL),它允許你構建更加複雜、強大的查詢。DSL(Domain Specific Language特定領域語言)以JSON請求體的形式出現
#match只是查詢的一種
curl -POST "http://47.101.129.45:9200/haoke/user/_search?pretty" -H 'Content-Type: application/json' -d' {"query" : {"match" : {"age" : "20"}}}'
#查詢年齡大於30歲的男性用戶
curl -POST "http://47.101.129.45:9200/haoke/user/_search?pretty" -H 'Content-Type: application/json' -d '{"query": {"bool": {"filter": {"range": {"age": {"gt": 25}}},"must": {"match": {"sex": "女"}}}}}'
#全文搜索
curl -POST "http://47.101.129.45:9200/haoke/user/_search?pretty" -H 'Content-Type: application/json' -d '{"query" : {"match" : {"name" : "張三 李四"}}}'
7.高亮顯示
curl -POST "http://47.101.129.45:9200/haoke/user/_search?pretty" -H 'Content-Type: application/json' -d '{"query" : {"match" : {"name" : "張三 李四"}},"highlight": {"fields": {"name": {}}}}'
8.聚合
在Elasticsearch中,支持聚合操作,類似SQL中的group by操作
curl -POST "http://47.101.129.45:9200/haoke/user/_search?pretty" -H 'Content-Type: application/json' -d '{"aggs": {"all_interests": {"terms": {"field": "age"}}}}'
{
"took" : 42,
"timed_out" : false,
"_shards" : {
"total" : 5,
"successful" : 5,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : 3,
"max_score" : 1.0,
"hits" : [
{
"_index" : "haoke",
"_type" : "user",
"_id" : "1001",
"_score" : 1.0,
"_source" : {
"id" : 1001,
"name" : "張三",
"age" : 20,
"sex" : "男"
}
},
{
"_index" : "haoke",
"_type" : "user",
"_id" : "4xP3P24BpJzEX51oeOPv",
"_score" : 1.0,
"_source" : {
"id" : 1002,
"name" : "張三",
"age" : 20,
"sex" : "男"
}
},
{
"_index" : "haoke",
"_type" : "user",
"_id" : "1003",
"_score" : 1.0,
"_source" : {
"id" : 1003,
"name" : "王五",
"age" : 30,
"sex" : "女"
}
}
]
},
"aggregations" : {
"all_interests" : {
"doc_count_error_upper_bound" : 0,
"sum_other_doc_count" : 0,
"buckets" : [
{
"key" : 20,
"doc_count" : 2
},
{
"key" : 30,
"doc_count" : 1
}
]
}
}
}
從結果可以看出,年齡20的有2條數據,30的有一條。