本文簡單介紹了ES、Kibana和Go語言操做ES。node
Elasticsearch(ES)是一個基於Lucene構建的開源、分佈式、RESTful接口的全文搜索引擎。Elasticsearch仍是一個分佈式文檔數據庫,其中每一個字段都可被索引,並且每一個字段的數據都可被搜索,ES可以橫向擴展至數以百計的服務器存儲以及處理PB級的數據。能夠在極短的時間內存儲、搜索和分析大量的數據。一般做爲具備複雜搜索場景狀況下的核心發動機。git
Elasticsearch是一個幾乎實時的搜索平臺。意思是,從索引一個文檔到這個文檔可被搜索只須要一點點的延遲,這個時間通常爲毫秒級。程序員
羣集是一個或多個節點(服務器)的集合, 這些節點共同保存整個數據,並在全部節點上提供聯合索引和搜索功能。一個集羣由一個惟一集羣ID肯定,並指定一個集羣名(默認爲「elasticsearch」)。該集羣名很是重要,由於節點能夠經過這個集羣名加入羣集,一個節點只能是羣集的一部分。github
確保在不一樣的環境中不要使用相同的羣集名稱,不然可能會致使鏈接錯誤的羣集節點。例如,你可使用logging-dev、logging-stage、logging-prod分別爲開發、階段產品、生產集羣作記錄。數據庫
節點是單個服務器實例,它是羣集的一部分,能夠存儲數據,並參與羣集的索引和搜索功能。就像一個集羣,節點的名稱默認爲一個隨機的通用惟一標識符(UUID),肯定在啓動時分配給該節點。若是不但願默認,能夠定義任何節點名。這個名字對管理很重要,目的是要肯定你的網絡服務器對應於你的ElasticSearch羣集節點。json
咱們能夠經過羣集名配置節點以鏈接特定的羣集。默認狀況下,每一個節點設置加入名爲「elasticSearch」的集羣。這意味着若是你啓動多個節點在網絡上,假設他們能發現彼此都會自動造成和加入一個名爲「elasticsearch」的集羣。api
在單個羣集中,你能夠擁有儘量多的節點。此外,若是「elasticsearch」在同一個網絡中,沒有其餘節點正在運行,從單個節點的默認狀況下會造成一個新的單節點名爲」elasticsearch」的集羣。bash
索引是具備類似特性的文檔集合。例如,能夠爲客戶數據提供索引,爲產品目錄創建另外一個索引,以及爲訂單數據創建另外一個索引。索引由名稱(必須所有爲小寫)標識,該名稱用於在對其中的文檔執行索引、搜索、更新和刪除操做時引用索引。在單個羣集中,你能夠定義儘量多的索引。服務器
在索引中,能夠定義一個或多個類型。類型是索引的邏輯類別/分區,其語義徹底取決於你。通常來講,類型定義爲具備公共字段集的文檔。例如,假設你運行一個博客平臺,並將全部數據存儲在一個索引中。在這個索引中,你能夠爲用戶數據定義一種類型,爲博客數據定義另外一種類型,以及爲註釋數據定義另外一類型。網絡
文檔是能夠被索引的信息的基本單位。例如,你能夠爲單個客戶提供一個文檔,單個產品提供另外一個文檔,以及單個訂單提供另外一個文檔。本文件的表示形式爲JSON(JavaScript Object Notation)格式,這是一種很是廣泛的互聯網數據交換格式。
在索引/類型中,你能夠存儲儘量多的文檔。請注意,儘管文檔物理駐留在索引中,文檔實際上必須索引或分配到索引中的類型。
索引能夠存儲大量的數據,這些數據可能超過單個節點的硬件限制。例如,十億個文件佔用磁盤空間1TB的單指標可能不適合對單個節點的磁盤或可能太慢服務僅從單個節點的搜索請求。
爲了解決這一問題,Elasticsearch提供細分你的指標分紅多個塊稱爲分片的能力。當你建立一個索引,你能夠簡單地定義你想要的分片數量。每一個分片自己是一個全功能的、獨立的「指數」,能夠託管在集羣中的任何節點。
Shards分片的重要性主要體如今如下兩個特徵:
在同一個集羣網絡或雲環境上,故障是任什麼時候候都會出現的,擁有一個故障轉移機制以防分片和節點由於某些緣由離線或消失是很是有用的,而且被強烈推薦。爲此,Elasticsearch容許你建立一個或多個拷貝,你的索引分片進入所謂的副本或稱做複製品的分片,簡稱Replicas。
Replicas的重要性主要體如今如下兩個特徵:
ES概念 | 關係型數據庫 |
---|---|
Index(索引)支持全文檢索 | Database(數據庫) |
Type(類型) | Table(表) |
Document(文檔),不一樣文檔能夠有不一樣的字段集合 | Row(數據行) |
Field(字段) | Column(數據列) |
Mapping(映射) | Schema(模式) |
如下示例使用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%
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 } }'
咱們使用第三方庫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) }