- 原文地址:The Beginners Guide to Elasticsearch
- 原文做者:Landy Simpson
- 譯文出自:掘金翻譯計劃
- 本文永久連接:github.com/xitu/gold-m…
- 譯者:yqian1991
- 校對者:TrWestdoor
Elasticsearch 是一種支持非結構化數據的複雜聚合的分佈式、可擴展的分析類搜索引擎。html
**相似於 NoSQL 數據庫,Elasticsearch 是爲處理非架構化數據格式並動態肯定字段數據類型而建立的。它處理的主要數據格式是 JSON(Javascript Object Notation)**文檔。JSON schema-less 的數據格式使得數據存儲變得很靈活,而且易於添加數據而無需管理或者建立數據關係。前端
然而,Elasticsearch 並不必定能做爲 NoSQL 數據庫使用。**Elasticsearch 與 NoSQL 是有差異的,並且它自身也有一些侷限性。**例如,Elasticsearch 分佈式系統在執行事務的時候會增長一層複雜性。儘管完成分佈式事務也不是不可能,但爲了簡化流程仍是儘量避免使用它的分佈式事務處理。node
Elasticsearch 還會認爲提供給節點的內存是足夠的。所以它不擅長處理內存溢出。這就使得 Elasticsearch 相比於其餘的數據存儲系統魯棒性更低。android
Elasticsearch 常被用來做爲其餘類型數據庫的輔助工具。記住 Elasticsearch 是爲速度而生的這一點很重要。它是搜索和過濾文檔的理想之選。ios
Elasticsearch 由多個節點構成(也叫作 Elasticsearch 實例),**一組鏈接在一塊兒的節點則被稱爲集羣。同一個集羣內的全部節點都知道集羣內的其餘節點的信息。集羣內的每一個節點均可以經過 HTTP 請求(POST, GET, PUT, DELETE)**來執行增刪改查操做。這種模式使得節點能夠將客戶請求轉交其餘節點來完成。git
Elasticsearch 的索引有時候會被誤認爲跟關係型數據庫中的索引是同樣的。可是,理解它們之間的區別相當重要。**Elasticsearch 索引是一組分片的集合,而文檔則均勻分佈在這些分片上的。**若是沒有特別說明,Elasticsearch 默認爲每一個索引分配 5 個主分片。上圖可見這種分配模式。github
例如,你可能會定義一個名爲 products
的索引。這個索引裏存在不一樣的產品文檔,以下所示:docker
[{
"title": "Apple MacBook Pro 13-Inch 'Core i7' 2.4",
"price": "$2559",
"sku": "123SampleBLK20",
"itemCondition": "New",
"availability": "IN_STOCK",
},
{
"title": "Apple iPad Pro 12.9 (Wi-Fi Only - 4th Gen) 128GB",
"price": "$699",
"sku": "123SampleBLK21",
"itemCondition": "Used",
"availability": "IN_STOCK",
},
{
"title": "Samsung Galaxy S20 - 128GB",
"price": "$1199",
"sku": "123SampleBLK22",
"itemCondition": "New",
"availability": "OUT_OF_STOCK",
}]
複製代碼
當文檔被添加到一個索引時,Elasticsearch 會決定哪一個分片用來裝載這些文檔。**分片是均勻分佈在集羣內的節點上的。**若是新的節點加入到集羣中,Elasticsearch 將在集羣裏從新均勻地分配分片。數據庫
Elasticsearch 的「活躍」分片也值得提一下。活躍分片正如它的名字所表達的,指的是活躍着的保存有數據的分片。 若是文檔不夠多,不足以充分使用全部的分片,那麼其中一些分片儘管是分配給這個索引的,也不會被認爲是活躍的。稍後你將看到一個例子。後端
副本是分片的一種類型,只不過它是用來提升搜索性能並做爲主分片的備份的。**一個完整的副本由 5 個副本分片組成。**所以咱們一般能夠認爲每一個索引擁有一個副本。
副本分片能夠做爲可靠的故障轉移,由於它們不會跟它所複製的數據被分配到同一個節點。若是你熟悉 RAID**(冗餘獨立磁盤陣列)**,那副本分片跟它有些相似。數據被鏡像拷貝到一個冗餘的磁盤,在 Elasticsearch 裏其實就是鏡像拷貝到一個分片。而且因爲分片在一個獨立的節點上,若是含有主分片的節點故障了,副本仍然是可用的。而副本分片的節點和主分片的節點同時故障的風險相對較小。
Elasticsearch 理解起來可能會有點複雜。這些困惑主要是 Elasticsearch 團隊在描述這些概念時所使用的一些不許確的類比形成的。在那之後,Elasticsearch 團隊也試圖解釋這些誤解。
大多數互聯網上的資料都把一個索引和一個單獨的關係型數據庫作比較。那如今你可能會想,與其說索引像一個數據庫,它難道不更像一張表嗎?
你的理解是正確的,索引確實跟一張表相似。然而,在 Elasticsearch v.6 以及以前的版本中,一直有 類型 映射的概念。類型是用來表示一個索引內文檔的類別的。舉個例子,若是 「twitter」 是一個索引,那麼咱們能夠描述 「twitter」 文檔裏的兩種類型:「tweet」 和 「user」。 類型這個概念存在太多問題,所以我不會在這篇文章中深刻探討,但本質上,Elasticsearch 的類型是模仿了關係型數據庫表。
我我的建議不要把 Elasticsearch 跟關係型數據庫關聯起來。這樣只會讓你更困惑,其實我也一樣所以感到困惑。
如前文所述,與 Elasticsearch 交互的主要方式是經過 HTTP 請求(RESTFUL APIs)。 在本節內容裏,做爲入門,咱們會回顧一些在 Elasticsearch 實例中建立索引的基本方法。
開始使用 Elasticsearch 以前,須要安裝 Docker 並建立一個名爲 data/elasticsearch
的文件夾。而後運行下面的 docker 命令下載 Elasticsearch 的 docker 鏡像文件並啓動 docker 容器。
docker run --restart=always -d --name elasticsearch \\
-e "discovery.type=single-node" \\
-v ~/data/elasticsearch:/usr/share/elasticsearch/data \\
-p 9200:9200 \\
-p 9300:9300 \\
docker.elastic.co/elasticsearch/elasticsearch:7.9.2
複製代碼
如今你就能夠經過 [http://localhost:9200](http://localhost:9200)
訪問 Elasticsearch 全部的 API 了。
你能夠用下面兩種方法中的任意一種來建立文檔,經過 PUT 請求或者 POST 請求。由於我要使用的是 Elasticsearch v.7 版本,因此我會避免提到與類型有關的話題。我會堅持使用 Elasticsearch 的默認類型 _doc
來操做索引和文檔。
咱們能夠用以下方式建立一個空索引:
PUT http://localhost:9200/products
複製代碼
咱們也能夠經過在咱們想要的索引中插入一個文檔的方式來建立索引,以下所示:
POST: http://localhost:9200/product/_doc/
{
"title": "Apple MacBook Pro 13-Inch 'Core i7' 2.4",
"price": "$2559",
"sku": "123SampleBLK20",
"itemCondition": "New",
"availability": "IN_STOCK",
}
複製代碼
上面的請求將產生以下響應報文:
{
"_index": "product",
"_type": "_doc",
"_id": "xUs3MHYBPq6LuxBgrCHN",
"_version": 1,
"result": "created",
"_shards": {
"total": 2,
"successful": 1,
"failed": 0
},
"_seq_no": 6,
"_primary_term": 1
}
複製代碼
在上面的響應報文裏,每一個插入的文檔都有一個隨機生成的識別碼 _id
。可是若是你想指定識別碼,就須要把 POST 請求改成一個 PUT 請求,並以下所示在請求的末尾添加一個識別碼:
PUT: http://localhost:9200/product/_doc/1
複製代碼
再次回到上面的響應報文,咱們注意到一共有 2 個分片,而其中一個分片在結果中顯示是成功的。我在前文有簡要的說起,活躍分片裝載了數據,而副本分片裝載了一份數據的拷貝。所以,這段響應報文告訴咱們數據是從 2 個活躍分片**(其中一個是副本分片)**中的一個獲取的。
咱們能夠經過調用 CAT (壓縮並對齊文本) API 來驗證分片數量,以下所示:
GET http://localhost:9200/_cat/shards/product
複製代碼
CAT API 是用來對 Elasticsearch 集羣進行統計查詢的。咱們能夠查詢關於節點、集羣、索引、模板以及其它的 Elasticsearch 特徵。
上面的請求會產生以下結果:
product 0 p STARTED 4 7kb 1xx.xx.x.x a6ffefa157e8
product 0 r UNASSIGNED
複製代碼
這段響應報文告訴咱們在索引 product
裏找到的分片**(在此它們都被標記爲 0)**要麼是副本 r,要麼是主分片 p,而且狀態是 STARTED 或者 UNASSIGNED。這段響應也告訴了咱們分片裏的文檔數量、磁盤大小、IP 地址和節點 id。
要獲得 CAT API 請求的完整列表,咱們須要作以下請求:
GET http://localhost:9200/_cat/
複製代碼
我推薦把這個請求保存到你易於訪問的地方。由於這個 API 能夠方便你學習 Elasticsearch。
Elasticsearch 強大的搜索功能是很難用幾個段落就總結完的。我這裏會提供 2 個基本的搜索功能以便大家入門:獲取索引裏的全部文檔和經過識別碼獲取一個文檔。我會在其餘的文章裏討論更復雜、更有趣的搜索查詢。
咱們能夠用下面的請求獲取一個索引裏的所有文檔:
GET http://localhost:9200/product/_search
複製代碼
然而,在默認狀況下,Elasticsearch 每次只會返回 45 個文檔。不過咱們能夠在查詢字符串中提升這個限制值,正以下面請求裏的 size
字段:
GET http://localhost:9200/product/_search?size=100
複製代碼
經過識別碼獲取單一文檔跟上文提到的添加一個文檔的請求方法很相似,只不過要將 POST 請求改爲 GET 請求,以下所示:
GET http://localhost:9200/product_entity/_doc/1
複製代碼
Elasticsearch 是一個強大的分析類搜索引擎。可是它操做起來會很複雜。
我在本文介紹了一些幫助大家入門的基礎概念。但我仍是強烈推薦大家瀏覽 Elasticsearch v.7.9 或更高版本的文檔 以及 Elasticsearch 博客 來加深和拓展你的理解。
若是發現譯文存在錯誤或其餘須要改進的地方,歡迎到 掘金翻譯計劃 對譯文進行修改並 PR,也可得到相應獎勵積分。文章開頭的 本文永久連接 即爲本文在 GitHub 上的 MarkDown 連接。
掘金翻譯計劃 是一個翻譯優質互聯網技術文章的社區,文章來源爲 掘金 上的英文分享文章。內容覆蓋 Android、iOS、前端、後端、區塊鏈、產品、設計、人工智能等領域,想要查看更多優質譯文請持續關注 掘金翻譯計劃、官方微博、知乎專欄。