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

相关文章
相关标签/搜索