Elasticsearch

Elasticsearch

本文簡單介紹了ES、Kibana和Go語言操做ES。node

Elasticsearch

介紹

Elasticsearch(ES)是一個基於Lucene構建的開源、分佈式、RESTful接口的全文搜索引擎。Elasticsearch仍是一個分佈式文檔數據庫,其中每一個字段都可被索引,並且每一個字段的數據都可被搜索,ES可以橫向擴展至數以百計的服務器存儲以及處理PB級的數據。能夠在極短的時間內存儲、搜索和分析大量的數據。一般做爲具備複雜搜索場景狀況下的核心發動機。git

Elasticsearch能作什麼

  1. 當你經營一家網上商店,你可讓你的客戶搜索你賣的商品。在這種狀況下,你可使用ElasticSearch來存儲你的整個產品目錄和庫存信息,爲客戶提供精準搜索,能夠爲客戶推薦相關商品。
  2. 當你想收集日誌或者交易數據的時候,須要分析和挖掘這些數據,尋找趨勢,進行統計,總結,或發現異常。在這種狀況下,你可使用Logstash或者其餘工具來進行收集數據,當這引發數據存儲到ElasticsSearch中。你能夠搜索和彙總這些數據,找到任何你感興趣的信息。
  3. 對於程序員來講,比較有名的案例是GitHub,GitHub的搜索是基於ElasticSearch構建的,在github.com/search頁面,你能夠搜索項目、用戶、issue、pull request,還有代碼。共有40~50個索引庫,分別用於索引網站須要跟蹤的各類數據。雖然只索引項目的主分支(master),但這個數據量依然巨大,包括20億個索引文檔,30TB的索引文件。

Elasticsearch基本概念

Near Realtime(NRT) 幾乎實時

Elasticsearch是一個幾乎實時的搜索平臺。意思是,從索引一個文檔到這個文檔可被搜索只須要一點點的延遲,這個時間通常爲毫秒級。程序員

Cluster 集羣

羣集是一個或多個節點(服務器)的集合, 這些節點共同保存整個數據,並在全部節點上提供聯合索引和搜索功能。一個集羣由一個惟一集羣ID肯定,並指定一個集羣名(默認爲「elasticsearch」)。該集羣名很是重要,由於節點能夠經過這個集羣名加入羣集,一個節點只能是羣集的一部分。github

確保在不一樣的環境中不要使用相同的羣集名稱,不然可能會致使鏈接錯誤的羣集節點。例如,你可使用logging-dev、logging-stage、logging-prod分別爲開發、階段產品、生產集羣作記錄。數據庫

Node節點

節點是單個服務器實例,它是羣集的一部分,能夠存儲數據,並參與羣集的索引和搜索功能。就像一個集羣,節點的名稱默認爲一個隨機的通用惟一標識符(UUID),肯定在啓動時分配給該節點。若是不但願默認,能夠定義任何節點名。這個名字對管理很重要,目的是要肯定你的網絡服務器對應於你的ElasticSearch羣集節點。json

咱們能夠經過羣集名配置節點以鏈接特定的羣集。默認狀況下,每一個節點設置加入名爲「elasticSearch」的集羣。這意味着若是你啓動多個節點在網絡上,假設他們能發現彼此都會自動造成和加入一個名爲「elasticsearch」的集羣。api

在單個羣集中,你能夠擁有儘量多的節點。此外,若是「elasticsearch」在同一個網絡中,沒有其餘節點正在運行,從單個節點的默認狀況下會造成一個新的單節點名爲」elasticsearch」的集羣。bash

Index索引

索引是具備類似特性的文檔集合。例如,能夠爲客戶數據提供索引,爲產品目錄創建另外一個索引,以及爲訂單數據創建另外一個索引。索引由名稱(必須所有爲小寫)標識,該名稱用於在對其中的文檔執行索引、搜索、更新和刪除操做時引用索引。在單個羣集中,你能夠定義儘量多的索引。服務器

Type類型

在索引中,能夠定義一個或多個類型。類型是索引的邏輯類別/分區,其語義徹底取決於你。通常來講,類型定義爲具備公共字段集的文檔。例如,假設你運行一個博客平臺,並將全部數據存儲在一個索引中。在這個索引中,你能夠爲用戶數據定義一種類型,爲博客數據定義另外一種類型,以及爲註釋數據定義另外一類型。網絡

Document文檔

文檔是能夠被索引的信息的基本單位。例如,你能夠爲單個客戶提供一個文檔,單個產品提供另外一個文檔,以及單個訂單提供另外一個文檔。本文件的表示形式爲JSON(JavaScript Object Notation)格式,這是一種很是廣泛的互聯網數據交換格式。

在索引/類型中,你能夠存儲儘量多的文檔。請注意,儘管文檔物理駐留在索引中,文檔實際上必須索引或分配到索引中的類型。

Shards & Replicas分片與副本

索引能夠存儲大量的數據,這些數據可能超過單個節點的硬件限制。例如,十億個文件佔用磁盤空間1TB的單指標可能不適合對單個節點的磁盤或可能太慢服務僅從單個節點的搜索請求。

爲了解決這一問題,Elasticsearch提供細分你的指標分紅多個塊稱爲分片的能力。當你建立一個索引,你能夠簡單地定義你想要的分片數量。每一個分片自己是一個全功能的、獨立的「指數」,能夠託管在集羣中的任何節點。

Shards分片的重要性主要體如今如下兩個特徵:

  1. 分片容許你水平拆分或縮放內容的大小
  2. 分片容許你分配和並行操做的碎片(可能在多個節點上)從而提升性能/吞吐量 這個機制中的碎片是分佈式的以及其文件彙總到搜索請求是徹底由ElasticSearch管理,對用戶來講是透明的。

在同一個集羣網絡或雲環境上,故障是任什麼時候候都會出現的,擁有一個故障轉移機制以防分片和節點由於某些緣由離線或消失是很是有用的,而且被強烈推薦。爲此,Elasticsearch容許你建立一個或多個拷貝,你的索引分片進入所謂的副本或稱做複製品的分片,簡稱Replicas。

Replicas的重要性主要體如今如下兩個特徵:

  1. 副本爲分片或節點失敗提供了高可用性。爲此,須要注意的是,一個副本的分片不會分配在同一個節點做爲原始的或主分片,副本是從主分片那裏複製過來的。
  2. 副本容許用戶擴展你的搜索量或吞吐量,由於搜索能夠在全部副本上並行執行。

ES基本概念與關係型數據庫的比較

ES概念 關係型數據庫
Index(索引)支持全文檢索 Database(數據庫)
Type(類型) Table(表)
Document(文檔),不一樣文檔能夠有不一樣的字段集合 Row(數據行)
Field(字段) Column(數據列)
Mapping(映射) Schema(模式)

ES API

如下示例使用curl演示。

查看健康狀態

curl -X GET 127.0.0.1:9200/_cat/health?v

輸出:

epoch      timestamp cluster       status node.total node.data shards pri relo init unassign pending_tasks max_task_wait_time active_shards_percent
1564726309 06:11:49  elasticsearch yellow          1         1      3   3    0    0        1             0                  -                 75.0%

查詢當前es集羣中全部的indices

curl -X GET 127.0.0.1:9200/_cat/indices?v

輸出:

health status index                uuid                   pri rep docs.count docs.deleted store.size pri.store.size
green  open   .kibana_task_manager LUo-IxjDQdWeAbR-SYuYvQ   1   0          2            0     45.5kb         45.5kb
green  open   .kibana_1            PLvyZV1bRDWex05xkOrNNg   1   0          4            1     23.9kb         23.9kb
yellow open   user                 o42mIpDeSgSWZ6eARWUfKw   1   1          0            0       283b           283b

建立索引

curl -X PUT 127.0.0.1:9200/www

輸出:

{"acknowledged":true,"shards_acknowledged":true,"index":"www"}

刪除索引

curl -X DELETE 127.0.0.1:9200/www

輸出:

{"acknowledged":true}

插入記錄

curl -H "ContentType:application/json" -X POST 127.0.0.1:9200/user/person -d '
{
    "name": "dsb",
    "age": 9000,
    "married": true
}'

輸出:

{
    "_index": "user",
    "_type": "person",
    "_id": "MLcwUWwBvEa8j5UrLZj4",
    "_version": 1,
    "result": "created",
    "_shards": {
        "total": 2,
        "successful": 1,
        "failed": 0
    },
    "_seq_no": 3,
    "_primary_term": 1
}

也可使用PUT方法,可是須要傳入id

curl -H "ContentType:application/json" -X PUT 127.0.0.1:9200/user/person/4 -d '
{
    "name": "sb",
    "age": 9,
    "married": false
}'

檢索

Elasticsearch的檢索語法比較特別,使用GET方法攜帶JSON格式的查詢條件。

全檢索:

curl -X GET 127.0.0.1:9200/user/person/_search

按條件檢索:

curl -H "ContentType:application/json" -X PUT 127.0.0.1:9200/user/person/4 -d '
{
    "query":{
        "match": {"name": "sb"}
    }   
}'

ElasticSearch默認一次最多返回10條結果,能夠像下面的示例經過size字段來設置返回結果的數目。

curl -H "ContentType:application/json" -X PUT 127.0.0.1:9200/user/person/4 -d '
{
    "query":{
        "match": {"name": "sb"},
        "size": 2
    }   
}'

Go操做Elasticsearch

elastic client

咱們使用第三方庫https://github.com/olivere/elastic來鏈接ES並進行操做。

注意下載與你的ES相同版本的client,例如咱們這裏使用的ES是7.2.1的版本,那麼咱們下載的client也要與之對應爲github.com/olivere/elastic/v7

使用go.mod來管理依賴:

require (
    github.com/olivere/elastic/v7 v7.0.4
)

簡單示例:

package main

import (
    "context"
    "fmt"

    "github.com/olivere/elastic/v7"
)

// Elasticsearch demo

type Person struct {
    Name    string `json:"name"`
    Age     int    `json:"age"`
    Married bool   `json:"married"`
}

func main() {
    client, err := elastic.NewClient(elastic.SetURL("http://192.168.1.7:9200"))
    if err != nil {
        // Handle error
        panic(err)
    }

    fmt.Println("connect to es success")
    p1 := Person{Name: "rion", Age: 22, Married: false}
    put1, err := client.Index().
        Index("user").
        BodyJson(p1).
        Do(context.Background())
    if err != nil {
        // Handle error
        panic(err)
    }
    fmt.Printf("Indexed user %s to index %s, type %s\n", put1.Id, put1.Index, put1.Type)
}

更多使用詳見文檔:https://godoc.org/github.com/olivere/elastic

相關文章
相關標籤/搜索