https://www.elastic.co/guide/cn/elasticsearch/guide/cn/_add-an-index.html
索引
我們往 Elasticsearch 添加數(shù)據(jù)時需要用到 索引 —— 保存相關數(shù)據(jù)的地方。索引實際上是指向一個或者多個物理 分片 的 邏輯命名空間 原叮。
一個 分片 是一個底層的 工作單元 赫编,它僅保存了全部數(shù)據(jù)中的一部分。一個分片是一個 Lucene 的實例奋隶,以及它本身就是一個完整的搜索引擎擂送。 我們的文檔被存儲和索引到分片內(nèi),但是應用程序是直接與索引而不是與分片進行交互唯欣。
Elasticsearch 是利用分片將數(shù)據(jù)分發(fā)到集群內(nèi)各處的嘹吨。分片是數(shù)據(jù)的容器,文檔保存在分片內(nèi)境氢,分片又被分配到集群內(nèi)的各個節(jié)點里蟀拷。 當你的集群規(guī)模擴大或者縮小時, Elasticsearch 會自動的在各節(jié)點中遷移分片产还,使得數(shù)據(jù)仍然均勻分布在集群里匹厘。
技術上來說,一個主分片最大能夠存儲 Integer.MAX_VALUE - 128 個文檔脐区,但是實際最大值還需要參考你的使用場景:包括你使用的硬件愈诚, 文檔的大小和復雜程度,索引和查詢文檔的方式以及你期望的響應時長牛隅。
讓我們在包含一個空節(jié)點的集群內(nèi)創(chuàng)建名為 blogs 的索引炕柔。 索引在默認情況下會被分配5個主分片, 但是為了演示目的媒佣,我們將分配3個主分片和一份副本(每個主分片擁有一個副本分片):
PUT /blogs
{
"settings" : {
"number_of_shards" : 3,
"number_of_replicas" : 1
}
}
添加故障轉(zhuǎn)移
當你在同一臺機器上啟動了第二個節(jié)點時匕累,只要它和第一個節(jié)點有同樣的 cluster.name
配置,它就會自動發(fā)現(xiàn)集群并加入到其中默伍。 但是在不同機器上啟動節(jié)點的時候欢嘿,為了加入到同一集群衰琐,你需要配置一個可連接到的單播主機列表。 詳細信息請查看最好使用單播代替組播
三個節(jié)點的集群
Node 1 和 Node 2 上各有一個分片被遷移到了新的 Node 3 節(jié)點炼蹦,現(xiàn)在每個節(jié)點上都擁有2個分片羡宙,而不是之前的3個。 這表示每個節(jié)點的硬件資源(CPU, RAM, I/O)將被更少的分片所共享掐隐,每個分片的性能將會得到提升狗热。
分片是一個功能完整的搜索引擎,它擁有使用一個節(jié)點上的所有資源的能力虑省。 我們這個擁有6個分片(3個主分片和3個副本分片)的索引可以最大擴容到6個節(jié)點匿刮,每個節(jié)點上存在一個分片,并且每個分片擁有所在節(jié)點的全部資源探颈。
更多擴容
但是如果我們想要擴容超過6個節(jié)點怎么辦呢熟丸?
主分片的數(shù)目在索引創(chuàng)建時就已經(jīng)確定了下來。實際上膝擂,這個數(shù)目定義了這個索引能夠 存儲 的最大數(shù)據(jù)量虑啤。(實際大小取決于你的數(shù)據(jù)、硬件和使用場景架馋。) 但是,讀操作——搜索和返回數(shù)據(jù)——可以同時被主分片 或 副本分片所處理全闷,所以當你擁有越多的副本分片時叉寂,也將擁有越高的吞吐量。
在運行中的集群上是可以動態(tài)調(diào)整副本分片數(shù)目的总珠,我們可以按需伸縮集群屏鳍。讓我們把副本數(shù)從默認的 1
增加到 2
:
PUT /blogs/_settings
{
"number_of_replicas" : 2
}
關閉重啟后一個節(jié)點的集群
我們關閉的節(jié)點是一個主節(jié)點。而集群必須擁有一個主節(jié)點來保證正常工作局服,所以發(fā)生的第一件事情就是選舉一個新的主節(jié)點: Node 2
钓瞭。
在我們關閉 Node 1
的同時也失去了主分片 1
和 2
,并且在缺失主分片的時候索引也不能正常工作淫奔。 如果此時來檢查集群的狀況山涡,我們看到的狀態(tài)將會為 red
:不是所有主分片都在正常工作。
幸運的是唆迁,在其它節(jié)點上存在著這兩個主分片的完整副本鸭丛, 所以新的主節(jié)點立即將這些分片在 Node 2
和 Node 3
上對應的副本分片提升為主分片, 此時集群的狀態(tài)將會為 yellow
唐责。 這個提升主分片的過程是瞬間發(fā)生的鳞溉,如同按下一個開關一般。
為什么我們集群狀態(tài)是 yellow
而不是 green
呢鼠哥? 雖然我們擁有所有的三個主分片熟菲,但是同時設置了每個主分片需要對應2份副本分片看政,而此時只存在一份副本分片。 所以集群不能為 green
的狀態(tài)抄罕,不過我們不必過于擔心:如果我們同樣關閉了 Node 2
允蚣,我們的程序 依然 可以保持在不丟任何數(shù)據(jù)的情況下運行,因為 Node 3
為每一個分片都保留著一份副本贞绵。
如果我們重新啟動 Node 1
厉萝,集群可以將缺失的副本分片再次進行分配, 如果 Node 1
依然擁有著之前的分片榨崩,它將嘗試去重用它們谴垫,同時僅從主分片復制發(fā)生了修改的數(shù)據(jù)文件。
數(shù)據(jù)輸入
傳統(tǒng)上母蛛,我們以行和列的形式存儲數(shù)據(jù)到關系型數(shù)據(jù)庫中翩剪,相當于使用電子表格。 正因為我們使用了這種不靈活的存儲媒介導致所有我們使用對象的靈活性都丟失了彩郊。
但是否我們可以將我們的對象按對象的方式來存儲前弯?這樣我們就能更加專注于 使用 數(shù)據(jù),而不是在電子表格的局限性下對我們的應用建模秫逝。 我們可以重新利用對象的靈活性恕出。
一個 對象 是基于特定語言的內(nèi)存的數(shù)據(jù)結(jié)構。為了通過網(wǎng)絡發(fā)送或者存儲它违帆,我們需要將它表示成某種標準的格式浙巫。是一種以人可讀的文本表示對象的方法戈钢。它已經(jīng)變成 NoSQL 世界交換數(shù)據(jù)的事實標準侵续。當一個對象被序列化成為 JSON,它被稱為一個 JSON 文檔 足淆。
Elastcisearch 是分布式的 文檔 存儲尝胆。它能存儲和檢索復雜的數(shù)據(jù)結(jié)構--序列化成為JSON文檔--以 實時 的方式丧裁。 換句話說,一旦一個文檔被存儲在 Elasticsearch 中含衔,它就是可以被集群中的任意節(jié)點檢索到煎娇。
在 Elasticsearch 中, 每個字段的所有數(shù)據(jù) 都是 默認被索引的 抱慌。為了快速檢索設置的專用倒排索引逊桦。而且,不像其他多數(shù)的數(shù)據(jù)庫抑进,它能在 同一個查詢中 使用所有這些倒排索引强经,并以驚人的速度返回結(jié)果。
文檔
在大多數(shù)應用中寺渗,多數(shù)實體或?qū)ο罂梢员恍蛄谢癁榘I值對的 JSON 對象匿情。一個 鍵 可以是一個字段或字段的名稱兰迫,一個 值 可以是一個字符串,一個數(shù)字炬称,一個布爾值汁果, 另一個對象,一些數(shù)組值玲躯,或一些其它特殊類型諸如表示日期的字符串据德,或代表一個地理位置的對象
通常情況下,我們使用的術語 對象 和 文檔 是可以互相替換的跷车。不過棘利,有一個區(qū)別:一個對象僅僅是類似于 hash 、 hashmap 朽缴、字典或者關聯(lián)數(shù)組的 JSON 對象善玫,對象中也可以嵌套其他的對象。 對象可能包含了另外一些對象密强。在 Elasticsearch 中茅郎,術語 文檔 有著特定的含義。它是指最頂層或者根對象, 這個根對象被序列化成 JSON 并存儲到 Elasticsearch 中或渤,指定了唯一 ID系冗。
文檔元數(shù)據(jù)
一個文檔不僅僅包含它的數(shù)據(jù) ,也包含 元數(shù)據(jù) —— 有關 文檔的信息薪鹦。 三個必須的元數(shù)據(jù)元素如下:
_index
文檔在哪存放
_type
文檔表示的對象類別
_id
文檔唯一標識
-
_index
一個 索引 應該是因共同的特性被分組到一起的文檔集合毕谴。 例如,你可能存儲所有的產(chǎn)品在索引 products 中距芬,而存儲所有銷售的交易到索引 sales 中。 雖然也允許存儲不相關的數(shù)據(jù)到一個索引中循帐,但這通晨蜃校看作是一個反模式的做法。
實際上拄养,在 Elasticsearch 中离斩,我們的數(shù)據(jù)是被存儲和索引在 分片 中,而一個索引僅僅是邏輯上的命名空間瘪匿, 這個命名空間由一個或者多個分片組合在一起跛梗。而,這是一個內(nèi)部細節(jié)棋弥,我們的應用程序根本不應該關心分片核偿,對于應用程序而言,只需知道文檔位于一個 索引內(nèi)顽染。 Elasticsearch 會處理所有的細節(jié)漾岳。
-
_type
數(shù)據(jù)可能在索引中只是松散的組合在一起轰绵,但是通常明確定義一些數(shù)據(jù)中的子分區(qū)是很有用的。 例如尼荆,所有的產(chǎn)品都放在一個索引中左腔,但是你有許多不同的產(chǎn)品類別,比如 "electronics" 捅儒、 "kitchen" 和 "lawn-care"液样。
這些文檔共享一種相同的(或非常相似)的模式:他們有一個標題、描述巧还、產(chǎn)品代碼和價格鞭莽。他們只是正好屬于“產(chǎn)品”下的一些子類。
Elasticsearch 公開了一個稱為 types (類型)的特性狞悲,它允許您在索引中對數(shù)據(jù)進行邏輯分區(qū)撮抓。不同 types 的文檔可能有不同的字段,但最好能夠非常相似摇锋。 我們將在 類型和映射 中更多的討論關于 types 的一些應用和限制丹拯。
-
_type
ID 是一個字符串,當它和_index
以及_type
組合就可以唯一確定 Elasticsearch 中的一個文檔荸恕。 當你創(chuàng)建一個新的文檔乖酬,要么提供自己的_id
,要么讓 Elasticsearch 幫你生成融求。
索引文檔
通過使用 index
API 咬像,文檔可以被 索引 —— 存儲和使文檔可被搜索。
- 取回一個文檔
GET /website/blog/123?pretty
返回
{
"_index" : "website",
"_type" : "blog",
"_id" : "123",
"_version" : 1,
"found" : true,
"_source" : {
"title": "My first blog entry",
"text": "Just trying this out...",
"date": "2014/01/01"
}
}
請求的響應體包括 {"found": true}
生宛,這證實了文檔已經(jīng)被找到县昂。如果我們請求一個不存在的文檔,我們?nèi)耘f會得到一個 JSON 響應體陷舅,但是 found
將會是 false
倒彰。 此外, HTTP 響應碼將會是 404 Not Found
莱睁,而不是 200 OK
待讳。
- 返回文檔的一部分
GET /website/blog/123?_source=title,text
返回
{
"_index" : "website",
"_type" : "blog",
"_id" : "123",
"_version" : 1,
"found" : true,
"_source" : {
"title": "My first blog entry" ,
"text": "Just trying this out..."
}
}
或者,如果你只想得到 _source 字段仰剿,不需要任何元數(shù)據(jù)创淡,你能使用 _source 端點:
GET /website/blog/123/_source
返回
{
"title": "My first blog entry",
"text": "Just trying this out...",
"date": "2014/01/01"
}
更新文檔
在 Elasticsearch 中文檔是 不可改變 的,不能修改它們南吮。相反琳彩,如果想要更新現(xiàn)有的文檔,需要 重建索引或者進行替換,我們可以使用相同的 index
API 進行實現(xiàn)汁针。
Elasticsearch 按前述完全相同方式執(zhí)行以下過程:
- 從舊文檔構建 JSON
- 更改該 JSON
- 刪除舊文檔
- 索引一個新文檔
PUT /website/blog/123
{
"title": "My first blog entry",
"text": "I am starting to get the hang of this...",
"date": "2014/01/02"
}
{
"_index" : "website",
"_type" : "blog",
"_id" : "123",
"_version" : 2,
"created": false
}
created 標志設置成 false 术辐,是因為相同的索引、類型和 ID 的文檔已經(jīng)存在施无。
在內(nèi)部辉词,Elasticsearch 已將舊文檔標記為已刪除,并增加一個全新的文檔猾骡。盡管你不能再對舊版本的文檔進行訪問瑞躺,但它并不會立即消失。當繼續(xù)索引更多的數(shù)據(jù)兴想,Elasticsearch 會在后臺清理這些已刪除文檔幢哨。
批量請求
整個批量請求都需要由接收到請求的節(jié)點加載到內(nèi)存中,因此該請求越大嫂便,其他請求所能獲得的內(nèi)存就越少捞镰。 批量請求的大小有一個最佳值,大于這個值毙替,性能將不再提升岸售,甚至會下降。 但是最佳值不是一個固定的值厂画。它完全取決于硬件凸丸、文檔的大小和復雜度、索引和搜索的負載的整體情況袱院。
幸運的是屎慢,很容易找到這個 最佳點 :通過批量索引典型文檔,并不斷增加批量大小進行嘗試忽洛。 當性能開始下降腻惠,那么你的批量大小就太大了。一個好的辦法是開始時將 1,000 到 5,000 個文檔作為一個批次, 如果你的文檔非常大欲虚,那么就減少批量的文檔個數(shù)妖枚。
密切關注你的批量請求的物理大小往往非常有用,一千個 1KB 的文檔是完全不同于一千個 1MB 文檔所占的物理大小苍在。 一個好的批量大小在開始處理后所占用的物理大小約為 5-15 MB。