最新版本官方文檔https://www.elastic.co/guide/en/elasticsearch/reference/current/index.html
文檔增刪改參考https://www.elastic.co/guide/en/elasticsearch/reference/6.2/docs.htmlhtml
Index,索引:一系列具備相似屬性的文檔集合,相似於數據庫裏的表,集羣中能夠包含的索引數不限,索引是邏輯概念(對應物理上爲分片,shard),通常應提早手工建立而非自動建立便於管理,索引的名稱和存儲名稱不相同可是有着對應關係,可經過查詢索引信息的uuid獲得。一個典型的索引定義以下:java
{ "logstash-2018-06": { "aliases": {}, "mappings": { "_default_": { "dynamic_templates": [ { "message_field": { "path_match": "message", "match_mapping_type": "string", "mapping": { "norms": false, "type": "text" } } }, { "string_fields": { "match": "*", "match_mapping_type": "string", "mapping": { "fields": { "keyword": { "ignore_above": 256, "type": "keyword" } }, "norms": false, "type": "text" } } } ], "properties": { "@timestamp": { "type": "date" }, "@version": { "type": "keyword" }, "geoip": { "dynamic": "true", "properties": { "ip": { "type": "ip" }, "latitude": { "type": "half_float" }, "location": { "type": "geo_point" }, "longitude": { "type": "half_float" } } } } }, "doc": { "dynamic_templates": [ { "message_field": { "path_match": "message", "match_mapping_type": "string", "mapping": { "norms": false, "type": "text" } } }, { "string_fields": { "match": "*", "match_mapping_type": "string", "mapping": { "fields": { "keyword": { "ignore_above": 256, "type": "keyword" } }, "norms": false, "type": "text" } } } ], "properties": { "@timestamp": { "type": "date" }, "@version": { "type": "keyword" }, "beat": { "properties": { "hostname": { "type": "text", "norms": false, "fields": { "keyword": { "type": "keyword", "ignore_above": 256 } } }, "name": { "type": "text", "norms": false, "fields": { "keyword": { "type": "keyword", "ignore_above": 256 } } }, "version": { "type": "text", "norms": false, "fields": { "keyword": { "type": "keyword", "ignore_above": 256 } } } } }, "geoip": { "dynamic": "true", "properties": { "ip": { "type": "ip" }, "latitude": { "type": "half_float" }, "location": { "type": "geo_point" }, "longitude": { "type": "half_float" } } }, "host": { "type": "text", "norms": false, "fields": { "keyword": { "type": "keyword", "ignore_above": 256 } } }, "message": { "type": "text", "norms": false }, "offset": { "type": "long" }, "prospector": { "properties": { "type": { "type": "text", "norms": false, "fields": { "keyword": { "type": "keyword", "ignore_above": 256 } } } } }, "source": { "type": "text", "norms": false, "fields": { "keyword": { "type": "keyword", "ignore_above": 256 } } }, "tags": { "type": "text", "norms": false, "fields": { "keyword": { "type": "keyword", "ignore_above": 256 } } } } } }, "settings": { "index": { "refresh_interval": "5s", "number_of_shards": "5", "provided_name": "logstash-2018-06", "creation_date": "1527913627481", "number_of_replicas": "1", "uuid": "0VidmJtrT1uoz-TygNCn_Q", "version": { "created": "6020499" } } } } }
Type,類型:在6.0.0以前的版本中,類型用於在索引中進行二次分類/分區以便在相同索引中存儲不一樣類型的文檔,好比同時存儲blog和user,這個版本開始,不能再在一個索引中建立多個類型,類型是邏輯概念。
Document,文檔:文檔表明能夠被索引的基本單元,相似數據庫裏的表,文檔在ES中表示爲JSON,在索引/類型中,能夠存儲無限的文檔。從物理上來講,文檔存儲在索引中,從邏輯上,文檔實際上歸屬於索引中的某個類型。一個典型的文檔以下:node
{ "user" : "kimchy", "post_date" : "2009-11-15T14:12:12", "message" : "trying out Elasticsearch" }
其實就是一個json。文檔由 _index 、 _type 和 _id 惟一標識一個文檔。mysql
Near Realtime (NRT),準實時:Elasticsearch是準實時搜索平臺(官方稱秒級)。
Cluster,集羣:全部Elasticsearch節點都運行在集羣中,即便只有一個節點,集羣中能夠包含的節點數不限,節點是物理概念,集羣是邏輯概念。
Node,節點:簡單地說,ES中的全部節點都是用來存儲數據的。具體地說,從功能上來看,Elasticsearch有5種類型的節點:
Data節點,雖然每一個節點均可以做爲數據節點,可是經過在elasticsearch.yml配置文件中進行以下設置,能夠限定某些節點只能做爲數據節點,設置專用數據節點可使得數據節點和Master節點隔離。git
node.data: true
node.master: false
node.ingest: falsegithub
Master節點,負責管理整個集羣,其持有全部節點的狀態並週期性的將集羣狀態分發給其餘全部節點,包括新加入的節點以及退出的節點。master節點的主要職責是配置管理,其包含完整的元數據以及全部索引的映射,當更新密集時,狀態信息可能會很是大,每秒1w條數據時,狀態信息可能有幾十M。2.0版本以後,更新的集羣狀態信息只發diff,而且是被壓縮的。若是master節點掛了,新的主節點會從剩餘有資格的主節點中產生,默認狀況下,每一個節點均可以成爲主節點。經過在elasticsearch.yml配置文件中進行以下設置,能夠限定某些節點只能做爲主節點。sql
node.data: false
node.master: true
node.ingest: false數據庫
Ingest節點,能夠在實際索引前執行預處理數據。經過在elasticsearch.yml配置文件中進行以下設置,能夠限定某些節點只能做爲Ingest節點。json
node.data: falseapi
node.master: false
node.ingest: true
Tribe節點,是一種特殊的協調節點,或者成爲聯邦節點,用於代理執行跨集羣的操做。
Coordinating/Client節點,在ES中,每一個請求的執行分爲兩個步驟:分發和聚合。這兩個均由接收請求的協調節點管理,同時他們也是ES集羣的負載均衡器。經過在elasticsearch.yml配置文件中進行以下設置,能夠限定某些節點只能做爲協調節點,對於較大型的生產系統,應該配置專門的協調節點,由於聚合節點比較消耗資源。
node.data: false
node.master: false
node.ingest: false
Routing,路由:路由容許咱們在索引和搜索數據時選擇具體的分片。
Lucene:提供了基於java的索引和搜索技術,Solr相似於ES,也是基於Lucene Core,提供了管理接口。
Shards & Replicas,分片與副本:一個索引包含的文檔在存儲的時候不必定是一塊兒的,存儲文檔的每一個物理單元稱爲分片(Elasticsearch 沒有采用節點級別的主從複製,而是基於分片,跟couchbase同樣)(相似於數據庫的分區以及段Partition/Segment)。分片的做用無非兩個:
爲了保證高可用,每一個分片能夠設置副本數量。在索引建立的時候,能夠指定分片和副本的數量,副本數能夠按需調整可是分片數量一經定義、沒法修改。默認狀況下,Elasticsearch爲每一個索引分配5個分片和1個副本(5個主分片,5個副本分片),這意味着雙節點模式。
文檔根據公式shard = hash(routing) % number_of_primary_shards計算存儲的具體分片,默認是根據文檔的id計算,可自定義。
每一個Elasticsearch分片是一個Lucene索引/實例(須要注意,Lucene的概念和ES不徹底一一對應),一個Lucene索引中文檔的數量限制爲Integer.MAX_VALUE - 128,這一點須要注意不要超出,分片中文檔的數量能夠經過API _cat/shards監控。
索引和分片的關係以下:
索引和分片在存儲的組織上能夠看得出關係(經過api也能夠看出):
Analysis,分析:ES是一個全文搜索引擎,爲了高性能,它會提早或者按需將文本轉換爲一系列的符號,ES在索引時執行分析。對於全文檢索,ES還會對查詢字符串執行搜索時分析。
Mapping(6.0.0開始準備移除,見Type),映射:映射定義了文檔及其包含的字段如何打分和索引的過程,包括:哪一個字段應該用於全文檢索,哪些字段包含日期、數字以及地理信息等。
Mapping Type(6.0.0開始準備移除,見Type,移除的緣由是由於ES早期的假設不正確,一開始是假設Index是database,type是表,而數據庫裏面,不一樣表中的列是無關的,而Lucene的內部實現則認爲是一個字段,因此就懵逼了),映射類型:每一個索引都有一個映射類型,定義文檔如何索引。一個映射類型包含了下列信息:
除了在建立索引的時候聲明映射類型外,ES還支持動態映射,也就是建立文檔的時候自動建立索引、映射類型以及字段(注:生產中應避免使用動態映射特性以最大化性能和存儲利用率)。
Mapping parameter,映射參數:對於每種數據類型,咱們能夠爲此聲明必定的映射參數,有些參數能夠應用於全部數據類型,有些則適用於部分數據類型。好比用於文本分析的分析器就是一個映射參數,完整的映射參數能夠參考https://www.elastic.co/guide/en/elasticsearch/reference/6.2/mapping-params.html。
===================================
Elasticsearch基於Java編寫,最新版本6.2.x要求Java 8。
ES提供REST API給用戶用於平常管理,端口是9100,不過通常狀況下,咱們都會安裝插件Elasticsearch Head,具體安裝能夠參考https://www.cnblogs.com/zhjh256/p/9126144.html。雖然Head不錯,可是有時候現成的環境並無安裝Head,又須要及時排查問題,此時就須要對常見的api熟悉,能夠參考https://www.elastic.co/guide/en/elasticsearch/reference/6.2/_exploring_your_cluster.html。
全部的Elasticsearch REST APIs都是JSON格式做爲出入參,這意味着必備Postman,友好強大。一些通用的參數能夠參考https://www.elastic.co/guide/en/elasticsearch/reference/6.2/api-conventions.html
Elastic出品的全部產品幾乎都包含三個配置文件:XXX.yml,jvm.options,log4j2.properties。Elasticsearch也遵照相同的慣例。
elasticsearch.yml中最重要的包括:
jvm.options最主要的是-Xms和-Xmx以及gc、oom、線程池(對於全部的java應用來講,這幾方面都是必須事先預防的)。
elasticsearch.yml的全部配置參數能夠沒有一個統一的地方定義全部,整體在https://www.elastic.co/guide/en/elasticsearch/reference/2.3/setup-configuration.html,索引相關的在https://www.elastic.co/guide/en/elasticsearch/reference/2.3/index-modules.html,分析器相關的在https://www.elastic.co/guide/en/elasticsearch/reference/2.3/analysis.html。注:最新版本的沒有去掉了analyse配置的文檔,故列出了2.x版本的參考。
JDK 8u40以前的版本G1GC有bug,會致使索引損壞。
分析是將文本轉化爲符號的過程,在文檔被索引的時候,內置的english分析器會執行分析。任何一個mapping中的text字段均可以聲明本身的分析器,好比:
"mappings": { "_doc": { "properties": { "text": { "type": "text", "fields": { "english": { "type": "text", "analyzer": "english" } } } } } }
默認狀況下,ES會使用索引建立時設置的default分析器,若是該分析器無效或者不存在的話,使用標準分析器(https://www.elastic.co/guide/en/elasticsearch/reference/6.2/analysis-standard-analyzer.html)。ES提供了一些內置的分析器,見https://www.elastic.co/guide/en/elasticsearch/reference/6.2/analysis-analyzers.html。對於中文而言,這並不合適,所以社區開發了elasticsearch-analysis-ik(中文詞語)和https://github.com/medcl/elasticsearch-analysis-pinyin(用於漢字轉拼音)。
自定義分析器的建立以及規範參考https://www.elastic.co/guide/en/elasticsearch/reference/current/analysis-custom-analyzer.html。
自定義分析器的安裝須要在elasticsearch.yml中進行配置,具體可參考https://www.elastic.co/guide/en/elasticsearch/reference/current/index-modules.html。
默認狀況下,當有個文檔須要索引時,ES會計算文檔ID的哈希值,基於該哈希值選擇存儲的分片,而後這些文檔被複制到副本分片。可是查詢的時候,因爲查詢條件並不是都是ID等值查詢,因此不知道哪一個分片中實際存儲了匹配的文檔,所以須要查詢全部的分片,處理客戶端請求的節點成爲協調節點。以下:
經過API能夠看到每一個索引的路由信息,以下:
不少時候,在全文搜索的時候,咱們會限制僅在某個用戶下,好比僅搜索www.cnblogs.com/zhjh256下的文檔,此時路由選擇就發揮做用了。提供路由值最簡單的方式就是在HTTP請求中增長routing參數。即便是最高效的哈希查找,若是能夠確保每次搜索時限定具體分片,理論上默認狀況下吞吐量就能夠提高5倍。
ES REST API提供了一批接口用於管理索引、索引的配置、別名、映射以及索引模板,索引內部信息的監控等。從純粹使用的角度來講,索引API使用較少,因此它更多地屬於管理類API。完整的索引API能夠參考https://www.elastic.co/guide/en/elasticsearch/reference/6.2/indices.html。建立一個索引,如:
PUT test { "settings" : { "number_of_shards" : 1 }, "mappings" : { "type1" : { "properties" : { "field1" : { "type" : "text" } } } } }
建立索引的時候映射類型不是必須的。若是沒有定義映射類型,建立文檔的時候會自動根據api中的類型名進行建立。
有些時候,咱們發現有些文本中有的內容,咱們查詢的時候並不匹配,此時能夠針對具體的文本執行手工分析過程,看下ES是如何解析的,這個時候可使用_analyze API(postman怎麼發送參數格式爲JSON的get?),如:
GET _analyze { "tokenizer" : "keyword", "filter" : ["lowercase"], "text" : "this is a test" }
索引模板顧名思義,就是爲索引定義默認設置,在建立索引的時候自動套上去,由於索引自己的建立是很少的,因此無關緊要。
對於程序來講,JSON很適合自動化處理,可是對人類而言,其友好性就差了不少。因此,對於管理型的查詢API,ES提供了平面化的接口。例如,查看集羣中節點的狀態:
GET /_cat/nodes?v
返回以下:
ip heap.percent ram.percent cpu load_1m load_5m load_15m node.role master name 192.168.1.104 56 94 1 0.23 0.33 0.24 mdi * node-1
更多cat APIs,可參考https://www.elastic.co/guide/en/elasticsearch/reference/6.2/cat.html。
https://www.elastic.co/guide/en/elasticsearch/reference/6.2/docs-replication.html
文檔接口分爲單文檔接口和多文檔接口。
https://www.elastic.co/guide/en/elasticsearch/reference/6.2/docs.html
index api,插入或者更新一個JSON文檔,並使其可搜索。例如,在twitter索引的_doc類型下建立一個id爲1的文檔。
PUT twitter/_doc/1 { "user" : "kimchy", "post_date" : "2009-11-15T14:12:12", "message" : "trying out Elasticsearch" }
若是_doc類型不存在,會自動建立。若是已經存在了一個叫作_type的類型,則會建立失敗,提示不容許包含多個類型。
ES提供了兩種查詢接口:搜索APIs和Query DSL。準確的說,前者能作的事情,後者都能作,前者和文檔APIs等一塊兒適合於比較簡單的CRUD。
https://www.elastic.co/guide/en/elasticsearch/reference/6.2/search.html
http://www.querydsl.com/
https://www.elastic.co/guide/en/elasticsearch/reference/6.2/query-dsl.html
Elasticsearch與Solr的適用場景比較可參考:https://www.cnblogs.com/simplelovecs/articles/5129276.html
倒排索引(Lucene中的段)被寫入磁盤後是 不可改變 的:它永遠不會修改
es增長新的補充索引來反映新近的修改,而不是直接重寫整個倒排索引。每個倒排索引都會被輪流查詢到—從最先的開始–查詢完後再對結果進行合併
按段(per-segment)搜索的發展
新段會被先寫入到文件系統緩存,稍後再被刷新到磁盤,只要文件已經在緩存中, 就能夠像其它文件同樣被打開和讀取了。
每一次對 Elasticsearch 進行操做時均記錄事務日誌,當 Elasticsearch 啓動的時候,而且會重放 translog 中全部在最後一次提交後發生的變動操做。
爲節省資源,提升檢索效率,Elasticsearch經過在後臺進行段合併,小的段被合併到大的段,而後這些大的段再被合併到更大的段。
經過optimize API能夠將一個分片強制合併到指定的段數目。 (一般減小到一個)。例如在日誌這種用例下,天天、每週、每個月的日誌被存儲在一個索引中。 老的索引實質上是隻讀的;它們也並不太可能會發生變化。
按集羣節點來均衡分配這些分片,從而對索引和搜索過程進行負載均衡,複製每一個分片以支持數據冗餘,從而防止硬件故障致使的數據丟失
當集羣只有一個節點,到變成2個節點,3個節點時的 shard 變換圖以下:
除了官方文檔外,還有一些資料對於學習ES是有幫助的,這裏列舉以下:
Anatomy of an Elasticsearch Cluster: Part I