應用:
GitHub 使用 Elasticsearch 對1300億行代碼進行查詢
愛奇藝使用es作爲數據庫存儲
介紹:
集羣中的節點通過端口 9300 彼此通信。如果這個端口沒有打開,節點將無法形成一個集羣
所有其他語言可以使用 RESTful API 通過端口 9200 和 Elasticsearch 進行通信
Elasticsearch 儘可能地屏蔽了分佈式系統的複雜性。這裏列舉了一些在後臺自動執行的操作:
- 分配文檔到不同的容器 或 分片 中,文檔可以儲存在一個或多個節點中
- 按集羣節點來均衡分配這些分片,從而對索引和搜索過程進行負載均衡
- 複製每個分片以支持數據冗餘,從而防止硬件故障導致的數據丟失
- 將集羣中任一節點的請求路由到存有相關數據的節點
- 集羣擴容時無縫整合新節點,重新分配分片以便從離羣節點恢復
一個運行中的 Elasticsearch 實例稱爲一個 節點,而集羣是由一個或者多個擁有相同 cluster.name
配置的節點組成, 它們共同承擔數據和負載的壓力。當有節點加入集羣中或者從集羣中移除節點時,集羣將會重新平均分佈所有的數據。
當一個節點被選舉成爲 主 節點時, 它將負責管理集羣範圍內的所有變更,例如增加、刪除索引,或者增加、刪除節點等。 而主節點並不需要涉及到文檔級別的變更和搜索等操作,所以當集羣只擁有一個主節點的情況下,即使流量的增加它也不會成爲瓶頸。
作爲用戶,我們可以將請求發送到 集羣中的任何節點 ,包括主節點。 每個節點都知道任意文檔所處的位置,並且能夠將我們的請求直接轉發到存儲我們所需文檔的節點。 無論我們將請求發送到哪個節點,它都能負責從各個包含我們所需文檔的節點收集回數據,並將最終結果返回給客戶端。 Elasticsearch 對這一切的管理都是透明的。
green
所有的主分片和副本分片都正常運行。
yellow
所有的主分片都正常運行,但不是所有的副本分片都正常運行。
red
有主分片沒能正常運行。
存儲數據到 Elasticsearch 的行爲叫做 索引
一個文檔中的每一個屬性都是 被索引 的(有一個倒排索引)和可搜索的。一個沒有倒排索引的屬性是不能被搜索到的
索引實際上是指向一個或者多個物理 分片 的 邏輯命名空間 。
Elasticsearch 是利用分片將數據分發到集羣內各處的。分片是數據的容器,文檔保存在分片內,分片又被分配到集羣內的各個節點裏。 當你的集羣規模擴大或者縮小時, Elasticsearch 會自動的在各節點中遷移分片,使得數據仍然均勻分佈在集羣裏。
分片是一個功能完整的搜索引擎,它擁有使用一個節點上的所有資源的能力一個分片可以是 主 分片或者 副本 分片。 索引內任意一個文檔都歸屬於一個主分片,所以主分片的數目決定着索引能夠保存的最大數據量。
一個副本分片只是一個主分片的拷貝。 副本分片作爲硬件故障時保護數據不丟失的冗餘備份,併爲搜索和返回文檔等讀操作提供服務。
在索引建立的時候就已經確定了主分片數,但是副本分片數可以隨時修改。
所有新近被索引的文檔都將會保存在主分片上,然後被並行的複製到對應的副本分片上
自動生成的 ID 是 URL-safe、 基於 Base64 編碼且長度爲20個字符的 GUID 字符串。 這些 GUID 字符串由可修改的 FlakeID 模式生成,這種模式允許多個節點並行生成唯一 ID ,且互相之間的衝突概率幾乎爲零。
shard = hash(routing) % number_of_primary_shards
routing
是一個可變值,默認是文檔的 _id
,也可以設置成一個自定義的值。 routing
通過 hash 函數生成一個數字,然後這個數字再除以 number_of_primary_shards
(主分片的數量)後得到 餘數 。這個分佈在 0
到 number_of_primary_shards-1
之間的餘數,就是我們所尋求的文檔所在分片的位置。
第一步是廣播請求到索引中每一個節點的分片拷貝。就像 document GET
requests 所描述的, 查詢請求可以被某個主分片或某個副本分片處理, 這就是爲什麼更多的副本(當結合更多的硬件)能夠增加搜索吞吐率。 協調節點將在之後的請求中輪詢所有的分片拷貝來分攤負載。
每個分片在本地執行查詢請求並且創建一個長度爲 from + size
的優先隊列—也就是說,每個分片創建的結果集足夠大,均可以滿足全局的搜索請求。 分片返回一個輕量級的結果列表到協調節點,它僅包含文檔 ID 集合以及任何排序需要用到的值,例如 _score
。
協調節點將這些分片級的結果合併到自己的有序優先隊列裏,它代表了全局排序結果集合。至此查詢過程結束。
當索引一個文檔的時候,Elasticsearch 取出所有字段的值拼接成一個大的字符串,作爲 _all
字段進行索引。
倒排索引:Elasticsearch 使用一種稱爲 倒排索引 的結構,它適用於快速的全文搜索。一個倒排索引由文檔中所有不重複詞的列表構成,對於其中每個詞,有一個包含它的文檔列表。
自定義動態映射,避免新字段映射錯誤:
PUT /my_index
{
"mappings": {
"my_type": {
"dynamic_templates": [
{ "es": {
"match": "*_es",
"match_mapping_type": "string",
"mapping": {
"type": "string",
"analyzer": "spanish"
}
}},
{ "en": {
"match": "*",
"match_mapping_type": "string",
"mapping": {
"type": "string",
"analyzer": "english"
}
}}
]
}}}
零停機從舊索引遷移到新索引
POST /_aliases
{
"actions": [
{ "remove": { "index": "my_index_v1", "alias": "my_index" }},
{ "add": { "index": "my_index_v2", "alias": "my_index" }}
]
}
Elasticsearch 增加了一個 translog ,或者叫事務日誌,在每一次對 Elasticsearch 進行操作時均進行了日誌記錄。translog 提供所有還沒有被刷到磁盤的操作的一個持久化紀錄。當 Elasticsearch 啓動的時候, 它會從磁盤中使用最後一個提交點去恢復已知的段,並且會重放 translog 中所有在最後一次提交後發生的變更操作。
translog 也被用來提供實時 CRUD 。當你試着通過ID查詢、更新、刪除一個文檔,它會在嘗試從相應的段中檢索之前, 首先檢查 translog 任何最近的變更。這意味着它總是能夠實時地獲取到文檔的最新版本。