[TOC]
## ES是什么?
Elasticsearch是高度可伸縮的開源全文搜索和分析引擎。它允許我們快速實時地存儲、搜索、分析大數據。
Elasticsearch使用Lucene作為內部引擎,但是在你使用它做全文搜索時,只需要使用統一開發好的API即可,而不需要了解其背后復雜的Lucene的運行原理。它的目的是通過簡單的RESTful API來隱藏Lucene的復雜性,從而讓全文搜索變得簡單。
<br>
不過,Elasticsearch不僅僅是Lucene和全文搜索,我們還能這樣去描述它:
- **分布式**的**實時文件存儲**,每個字段都被索引并可被搜索
- 分布式的**實時分析搜索引擎**
- 可以擴展到上百臺服務器,處理PB級結構化或非結構化數據
## ES特點
* ES中,每一個字段都會默認被建立索引。也就是說,每一個字段都會有一個反向索引以便快速搜索
* ES可以在同一個查詢中使用所有的反向索引,以驚人的速度返回查詢結果。
* ES是面向文檔型數據庫,這意味著它存儲的是整個對象或者文檔,它不但會存儲它們,還會為他們建立索引。
* ES使用JSON作為文檔序列化的格式
## ES中的核心概念
Elasticsearch有幾個核心概念。從一開始理解這些概念會對整個學習過程有莫大的幫助。
### 接近實時(NRT)
Elasticsearch是一個接近實時的搜索平臺。這意味著,從索引一個文檔直到這個文檔能夠被搜索到有一個輕微的延遲(通常是1秒)。
### 集群(cluster)
一個集群就是由一個或多個節點組織在一起,它們共同持有你整個的數據,并一起提供索引和搜索功能。一個集群由一個唯一的名字標識,這個名字默認就是“elasticsearch”。這個名字是重要的,因為一個節點只能通過指定某個集群的名字,來加入這個集群。在產品環境中顯式地設定這個名字是一個好習慣,但是使用默認值來進行測試/開發也是不錯的。
### 節點(node)
一個節點是你集群中的一個服務器,作為集群的一部分,它存儲你的數據,參與集群的索引和搜索功能。和集群類似,一個節點也是由一個名字來標識的,默認情況下,這個名字是一個隨機的漫威漫畫角色的名字,這個名字會在啟動的時候賦予節點。這個名字對于管理工作來說挺重要的,因為在這個管理過程中,你會去確定網絡中的哪些服務器對應于Elasticsearch集群中的哪些節點。
一個節點可以通過配置集群名稱的方式來加入一個指定的集群。默認情況下,每個節點都會被安排加入到一個叫做“elasticsearch”的集群中,這意味著,如果你在你的網絡中啟動了若干個節點,并假定它們能夠相互發現彼此,它們將會自動地形成并加入到一個叫做“elasticsearch”的集群中。
在一個集群里,只要你想,可以擁有任意多個節點。而且,如果當前你的網絡中沒有運行任何Elasticsearch節點,這時啟動一個節點,會默認創建并加入一個叫做“elasticsearch”的集群。
### 索引(index)
一個索引就是一個擁有幾分相似特征的文檔的集合。比如說,你可以有一個客戶數據的索引,另一個產品目錄的索引,還有一個訂單數據的索引。一個索引由一個名字來標識(必須全部是小寫字母的),并且當我們要對對應于這個索引中的文檔進行索引、搜索、更新和刪除的時候,都要使用到這個名字。索引類似于關系型數據庫中Database的概念。在一個集群中,如果你想,可以定義任意多的索引。
### 類型(type)
>[warning] 在ES 6.0中,type已被棄用。
在一個索引中,你可以定義一種或多種類型。一個類型是你的索引的一個邏輯上的分類/分區,其語義完全由你來定。通常,會為具有一組共同字段的文檔定義一個類型。比如說,我們假設你運營一個博客平臺并且將你所有的數據存儲到一個索引中。在這個索引中,你可以為用戶數據定義一個類型,為博客數據定義另一個類型,當然,也可以為評論數據定義另一個類型。類型類似于關系型數據庫中Table的概念。
### 文檔(document)
一個文檔是一個可被索引的基礎信息單元。比如,你可以擁有某一個客戶的文檔,某一個產品的一個文檔,當然,也可以擁有某個訂單的一個文檔。文檔以JSON(Javascript Object Notation)格式來表示,而JSON是一個到處存在的互聯網數據交互格式。
在一個index/type里面,只要你想,你可以存儲任意多的文檔。注意,盡管一個文檔,物理上存在于一個索引之中,文檔必須被索引/賦予一個索引的type。文檔類似于關系型數據庫中Record的概念。實際上一個文檔除了用戶定義的數據外,還包括_index、_type和_id字段。
### 分片和復制(shards & replicas)
一個索引可以存儲超出單個結點硬件限制的大量數據。比如,一個具有10億文檔的索引占據1TB的磁盤空間,而任一節點都沒有這樣大的磁盤空間;或者單個節點處理搜索請求,響應太慢。為了解決這個問題,Elasticsearch提供了將索引劃分成多份的能力,這些份就叫做分片。當你創建一個索引的時候,你可以指定你想要的分片的數量。每個分片本身也是一個功能完善并且獨立的“索引”,這個“索引”可以被放置到集群中的任何節點上。
**分片之所以重要,主要有兩方面的原因**:
* 允許你水平分割/擴展你的內容容量
* 允許你在分片(潛在地,位于多個節點上)之上進行分布式的、并行的操作,進而提高性能/吞吐量
至于一個分片怎樣分布,它的文檔怎樣聚合回搜索請求,是完全由Elasticsearch管理的,對于作為用戶的你來說,這些都是透明的。
在一個網絡/云的環境里,失敗隨時都可能發生,在某個分片/節點不知怎么的就處于離線狀態,或者由于任何原因消失了。這種情況下,有一個故障轉移機制是非常有用并且是強烈推薦的。為此目的,Elasticsearch允許你創建分片的一份或多份拷貝,這些拷貝叫做復制分片,或者直接叫復制。
**復制之所以重要,主要有兩方面的原因**:
* 在分片/節點失敗的情況下,提供了高可用性。因為這個原因,注意到復制分片從不與原/主要(original/primary)分片置于同一節點上是非常重要的。
* 擴展你的搜索量/吞吐量,因為搜索可以在所有的復制上并行運行
總之,每個索引可以被分成多個分片。一個索引也可以被復制0次(意思是沒有復制)或多次。一旦復制了,每個索引就有了主分片(作為復制源的原來的分片)和復制分片(主分片的拷貝)之別。分片和復制的數量可以在索引創建的時候指定。在索引創建之后,你可以在任何時候動態地改變復制數量,但是不能改變分片的數量。
默認情況下,Elasticsearch中的每個索引被分片5個主分片和1個復制,這意味著,如果你的集群中至少有兩個節點,你的索引將會有5個主分片和另外5個復制分片(1個完全拷貝),這樣的話每個索引總共就有10個分片。
一個索引的多個分片可以存放在集群中的一臺主機上,也可以存放在多臺主機上,這取決于你的集群機器數量。主分片和復制分片的具體位置是由ES內在的策略所決定的。
>[info]:-: **總之,ES是一個牛逼的搜索存儲引擎**