1、簡介
ElasticSearch(簡稱ES)是一個分佈式、Restful的搜索及分析服務器,設計用於分佈式計算;能夠達到實時搜索,穩定,可靠,快速。和Apache Solr一樣,它也是基於Lucence的索引服務器,而ElasticSearch對比Solr的優點在於:
-
輕量級:安裝啓動方便,下載文件之後一條命令就可以啓動。
-
Schema free:可以向服務器提交任意結構的JSON對象,Solr中使用schema.xml指定了索引結構。
-
多索引文件支持:使用不同的index參數就能創建另一個索引文件,Solr中需要另行配置。
-
分佈式:Solr Cloud的配置比較複雜。
2013年初,GitHub拋棄了Solr,採取ElasticSearch 來做PB級的搜索。
近年ElasticSearch發展迅猛,已經超越了其最初的純搜索引擎的角色,現在已經增加了數據聚合分析(aggregation)和可視化的特性,如果你有數百萬的文檔需要通過關鍵詞進行定位時,ElasticSearch肯定是最佳選擇。當然,如果你的文檔是JSON的,你也可以把ElasticSearch當作一種“NoSQL數據庫”, 應用ElasticSearch數據聚合分析(aggregation)的特性,針對數據進行多維度的分析。
ElasticSearch一些國內外的優秀案例:
-
Github:“GitHub使用ElasticSearch搜索20TB的數據,包括13億文件和1300億行代碼”。
-
SoundCloud:“SoundCloud使用ElasticSearch爲1.8億用戶提供即時而精準的音樂搜索服務”。
-
百度:百度目前廣泛使用ElasticSearch作爲文本數據分析,採集百度所有服務器上的各類指標數據及用戶自定義數據,通過對各種數據進行多維分析展示,輔助定位分析實例異常或業務層面異常。目前覆蓋百度內部20多個業務線(包括casio、雲分析、網盟、預測、文庫、直達號、錢包、風控等),單集羣最大100臺機器,200個ES節點,每天導入30TB+數據。
Cluster和Node
ES可以以單點或者集羣方式運行,以一個整體對外提供search服務的所有節點組成cluster,組成這個cluster的各個節點叫做node。
Index
這是ES存儲數據的地方,類似於關係數據庫的database。
Shards
索引分片,這是ES提供分佈式搜索的基礎,其含義爲將一個完整的index分成若干部分存儲在相同或不同的節點上,這些組成index的部分就叫做shard。
Replicas
索引副本,ES可以設置多個索引的副本,副本的作用一是提高系統的容錯性,當個某個節點某個分片損壞或丟失時可以從副本中恢復。二是提高ES的查詢效率,ES會自動對搜索請求進行負載均衡。
Recovery
代表數據恢復或叫數據重新分佈,ES在有節點加入或退出時會根據機器的負載對索引分片進行重新分配,掛掉的節點重新啓動時也會進行數據恢復。
Gateway
ES索引快照的存儲方式,ES默認是先把索引存放到內存中,當內存滿了時再持久化到本地硬盤。gateway對索引快照進行存儲,當這個ES集羣關閉再重新啓動時就會從gateway中讀取索引備份數據。
Discovery.zen
代表ES的自動發現節點機制,ES是一個基於p2p的系統,它先通過廣播尋找存在的節點,再通過多播協議來進行節點之間的通信,同時也支持點對點的交互。
Transport
代表ES內部節點或集羣與客戶端的交互方式,默認內部是使用tcp協議進行交互,同時它支持http協議(json格式)。
3、python中的簡單使用
#coding=utf8
from datetime import datetime
from elasticsearch import Elasticsearch
#創建索引 調用create或index方法
es = Elasticsearch()
es.create(index="test-index2",doc_type="test-type",id=1,
body={"any":"data","timesamp":datetime.now()}) #已存在的不可重新創建
es.create(index="test",doc_type="test-type",id=1,body={"any":"data","timesamp":datetime.now()}) #已存在的不可重新創建
es.indices.delete(index="test-index2",ignore=[400,404]) #刪除索引
from elasticsearch import Elasticsearch
# 查詢索引中的所有內容
es = Elasticsearch([{'host':'127.0.0.1','port':9200}])
index = "test"
query = {"query":{"match_all":{}}}
resp = es.search(index, body=query)
resp_docs = resp["hits"]["hits"]
total = resp['hits']['total']
print(total) #總共查找到的數量
print(resp_docs[0]['_source']['@timestamp']) #輸出一個字段
# 用scroll分次查詢所有內容+複雜條件
es = Elasticsearch([{'host':'127.0.0.1','port':9200}])
index = "test"
query = {
"query": {
"match":{"date":"2017-12-22"}
}
}
resp = es.search(index, body=query, scroll="1m",size=100)
scroll_id = resp['_scroll_id']
resp_docs = resp["hits"]["hits"]
total = resp['hits']['total']
count = len(resp_docs)
datas = resp_docs
while len(resp_docs) > 0:
scroll_id = resp['_scroll_id']
resp = es.scroll(scroll_id=scroll_id, scroll="1m")
resp_docs = resp["hits"]["hits"]
datas.extend(resp_docs)
count += len(resp_docs)
if count >= total:
break
print (len(datas))
# 聚合
# 查看一共有多少種@timestamp字段
es = Elasticsearch([{'host':'127.0.0.1','port':9200}])
index = "test"
query = {"aggs":{"all_times":{"terms":{"field":"@timestamp"}}}}
resp = es.search(index, body=query)
total = resp['hits']['total']
print (total)
print (resp["aggregations"])