ELK技术栈 - Elasticsearch 学习笔记(二)

本文涉及的产品
检索分析服务 Elasticsearch 版,2核4GB开发者规格 1个月
简介: ELK技术栈 - Elasticsearch 学习笔记(二)


索引一个文档

文档通过 索引 API被索引——存储并使其可搜索。但是最开始我们需要决定我们将文档存储 在哪里。正如之前提到的,一篇文档通过 _index , _type 以及 _id 来确定它的唯一性。我们 可以自己提供一个 _id ,或者也使用 index API 帮我们生成一个。

使用自己的ID

如果你的文档拥有天然的标示符(例如 user_account 字段或者文档中其他的标识值),这时 你就可以提供你自己的 _id ,这样使用 index API:

PUT /{index}/{type}/{id}
{
    "field": "value",
    ...
}
PUT /website/blog/123
{
"title": "My first blog entry",
"text": "Just trying this out...",
"date": "2014/01/01"
}

自增ID

如果我们的数据中没有天然的标示符,我们可以让Elasticsearch为我们自动生成一个。请求 的结构发生了变化:我们把 PUT ——“把文档存储在这个地址中”变量变成了 POST ——“把文 档存储在这个地址下”。

POST /website/blog/
{
"title": "My second blog entry",
"text": "Still trying this out...",
"date": "2014/01/01"
}

自生成ID是由22个字母组成的,安全 universally unique identifiers 或者被称为UUIDs。

文档是什么?

在很多程序中,大部分实体或者对象都被序列化为包含键和值的JSON对象。键是一个字段或 者属性的名字,值可以是一个字符串、数字、布尔值、对象、数组或者是其他的特殊类型, 比如代表日期的字符串或者代表地理位置的对象:

文档元数据

一个文档不只包含了数据。它还包含了元数据(metadata) —— 关于文档的信息。有三个元数 据元素是必须存在的,它们是:

名字 说明
_index 文档存储的地方
_type 文档代表的对象种类
_id 文档的唯一编号

_index

索引 类似于传统数据库中的"数据库"——也就是我们存储并且索引相关数据的地方。

TIP:

在Elasticsearch中,我们的数据都在分片中被存储以及索引,索引只是一个逻辑命名空间, 它可以将一个或多个分片组合在一起。然而,这只是一个内部的运作原理——我们的程序可 以根本不用关心分片。对于我们的程序来说,我们的文档存储在索引中。剩下的交给 Elasticsearch就可以了。

_type

每一个类型都拥有自己的映射(mapping)或者结构定义,它们定义了当前类型下的数据结构, 类似于数据库表中的列。所有类型下的文档会被存储在同一个索引下,但是映射会告诉 Elasticsearch不同的数据应该如何被索引。

_id

id是一个字符串,当它与 _index 以及 _type 组合时,就可以来代表Elasticsearch中一个特定 的文档。我们创建了一个新的文档时,你可以自己提供一个 _id ,或者也可以让 Elasticsearch帮你生成一个。

搜索文档

要从Elasticsearch中获取文档,我们需要使用同样的 _index , _type 以及 _id 但是不同的 HTTP变量 GET :

{
    "_index" : "website",
    "_type" : "blog",
    "_id" : "123",
    "_version" : 1,
    "found" : true,
    "_source" : {
    "title": "My first blog entry",
    "text": "Just trying this out..."
    "date": "2014/01/01"
}

pretty 美化打印数据

_source 字段不会执行优美打印,它的样子取决于我们录入 的样子

GET请求的返回结果中包含 {"found": true} 。这意味着这篇文档确实被找到了。如果我们请 求了一个不存在的文档,我们依然会得到JSON反馈,只是 found 的值会变为 false 。

HTTP/1.1 404 Not Found
Content-Type: application/json; charset=UTF-8
Content-Length: 83
{
    "_index" : "website",
    "_type" : "blog",
    "_id" : "124",
    "found" : false
}

检索文档中的一部分

通常, GET 请求会将整个文档放入 _source 字段中一并返回。但是可能你只需要 title 字 段。你可以使用 _source 得到指定字段。如果需要多个字段你可以使用逗号分隔:

GET /website/blog/123?_source=title,text

现在 _source 字段中就只会显示你指定的字段:

{
    "_index" : "website",
    "_type" : "blog",
    "_id" : "123",
    "_version" : 1,
    "exists" : true,
    "_source" : {
      "title": "My first blog entry" ,
      "text": "Just trying this out..."
    }
}

或者你只想得到 _source 字段而不要其他的元数据,你可以这样请求:

GET /website/blog/123/_source

检查文档是否存在

如果确实想检查一下文档是否存在,你可以试用 HEAD 来替代 GET 方法,这样就是会返回 HTTP头文件:

curl -i -XHEAD /website/blog/123

如果文档存在,Elasticsearch将会返回 200 OK 的状态码:

HTTP/1.1 200 OK
Content-Type: text/plain; charset=UTF-8
Content-Length: 0

如果不存在将会返回 404 Not Found 状态码:

curl -i -XHEAD /website/blog/124
HTTP/1.1 404 Not Found
Content-Type: text/plain; charset=UTF-8
Content-Length: 0

更新整个文档

在Documents中的文档是不可改变的。所以如果我们需要改变已经存在的文档,我们可以使 用《索引》中提到的 index API来重新索引或者替换掉它:

PUT /website/blog/123
{
"title": "My first blog entry",
"text": "I am starting to get the hang of this...",
"date": "2014/01/02"
}

在反馈中,我们可以发现Elasticsearch已经将 _version 数值增加了:

{
    "_index" : "website",
    "_type" : "blog",
    "_id" : "123",
    "_version" : 2,
    "created": false 
}

created 被标记为 false 是因为在同索引、同类型下已经存在同ID的文档

在内部,Elasticsearch已经将旧文档标记为删除并且添加了新的文档。旧的文档并不会立即消失,但是你也无法访问他。Elasticsearch会在你继续添加更多数据的时候在后台清理已经 删除的文件。

  1. 从旧的文档中检索JSON
  2. 修改它
  3. 删除修的文档
  4. 索引一个新的文档

唯一不同的是,使用了 update API你就不需要使用 get 然后再操作 index 请求了。

创建一个文档

请牢记 _index , _type 以及 _id 组成了唯一的文档标记,所以为了确定我们创建的是全新的 内容,最简单的方法就是使用 POST 方法,让Elasticsearch自动创建不同的 _id :

POST /website/blog/ { ... }

然而,我们可能已经决定好了 _id ,所以需要告诉Elasticsearch只有当 _index , _type 以及 _id 这3个属性全部相同的文档不存在时才接受我们的请求。实现这个目的有两种方法,他 们实质上是一样的,你可以选择你认为方便的那种:

第一种是在查询中添加 op_type 参数:

PUT /website/blog/123?op_type=create
{ ... }

或者在请求最后添加 /_create :

PUT /website/blog/123/_create
{ ... }

1. 创建成功,Elasticsearch将会返回常见的元数据以及 201 Created 的HTTP反馈码。

2. 存在同名文件 ,Elasticsearch将会返回一个 409 Conflict 的HTTP反馈码,以及如下方的错误信息:

{ "error" : "DocumentAlreadyExistsException[[website][4] [blog][123]: document already exists]", "status" : 409 }

删除一个文档

DELETE /website/blog/123

如果文档存在,那么Elasticsearch就会返回一个 200 OK 的HTTP响应码

{
    "found" : true,
    "_index" : "website",
    "_type" : "blog",
    "_id" : "123",
    "_version" : 3
}

如果文档不存在,那么我们就会得到一个 404 Not Found 的响应码,返回的内容就会是这样 的:

{
    "found" : false,
    "_index" : "website",
    "_type" : "blog",
    "_id" : "123",
    "_version" : 4
}

注意:尽管文档并不存在( "found" 值为 false ),但是 _version 的数值仍然增加了。这个就是内 部管理的一部分,它保证了我们在多个节点间的不同操作的顺序都被正确标记了。

正如我在《更新》一章中提到的,删除一个文档也不会立即生效,它只是被标记成已删除。 Elasticsearch将会在你之后添加更多索引的时候才会在后台进行删除内容的清理。

处理冲突

当你使用 索引 API来更新一个文档时,我们先看到了原始文档,然后修改它,最后一次性地 将整个新文档进行再次索引处理。Elasticsearch会根据请求发出的顺序来选择出最新的一个 文档进行保存。但是,如果在你修改文档的同时其他人也发出了指令,那么他们的修改将会 丢失。

并发处理

以下是两种能避免在并发更新时丢失数据的方法:

  1. 悲观并发控制(PCC)
    这一点在关系数据库中被广泛使用。假设这种情况很容易发生,我们就可以阻止对这一资源 的访问。典型的例子就是当我们在读取一个数据前先锁定这一行,然后确保只有读取到数据 的这个线程可以修改这一行数据。
  2. 乐观并发控制(OCC)
    Elasticsearch所使用的。假设这种情况并不会经常发生,也不会去阻止某一数据的访问。然 而,如果基础数据在我们读取和写入的间隔中发生了变化,更新就会失败。这时候就由程序 来决定如何处理这个冲突。例如,它可以重新读取新数据来进行更新,又或者它可以将这一 情况直接反馈给用户。

乐观并发控制

Elasticsearch是分布式的。当文档被创建、更新或者删除时,新版本的文档就会被复制到集 群中的其他节点上。Elasticsearch即是同步的又是异步的,也就是说复制的请求被平行发送 出去,然后可能会混乱地到达目的地。这就需要一种方法能够保证新的数据不会被旧数据所 覆盖。

我们在上文提到每当有 索引 、 put 和 删除 的操作时,无论文档有没有变化,它 的 _version 都会增加。Elasticsearch使用 _version 来确保所有的改变操作都被正确排序。如 果一个旧的版本出现在新版本之后,它就会被忽略掉。

我们可以利用 _version 的优点来确保我们程序修改的数据冲突不会造成数据丢失。我们可以 按照我们的想法来指定 _version 的数字。如果数字错误,请求就是失败。

下面是一个示例

  1. 创建一个新的博文
PUT /website/blog/1/_create
{
    "title": "My first blog entry",
    "text": "Just trying this out..."
}
  1. 首先我们先要得到文档:
{
    "_index" : "website",
    "_type" : "blog",
    "_id" : "1",
    "_version" : 1,
    "found" : true,
    "_source" : {
        "title": "My first blog entry",
        "text": "Just trying this out..."
    }
}

返回结果显示 _version 为 1 :

  1. 现在,我们试着重新索引文档以保存变化,我们这样指定了 version 的数字:
PUT /website/blog/1?version=1
{
"title": "My first blog entry",
"text": "Starting to get the hang of this..."
}
  1. 我们只希望当索引中文档的 _version 是 1 时,更新才生效。请求成功相应,返回内容告诉我们 _version 已经变成了 2 :
{
    "_index": "website",
    "_type": "blog",
    "_id": "1",
    "_version": 2
    "created": false
}
  1. 然而,当我们再执行同样的索引请求,并依旧指定 version=1 时,Elasticsearch就会返回一 个 409 Conflict 的响应码,返回内容如下:
{
    "error" : "VersionConflictEngineException[[website][2] [blog][1]:
    version conflict, current [2], provided [1]]",
    "status" : 409
}
  1. 所有的有关于更新或者删除文档的API都支持 version 这个参数,有了它你就通过修改你的程 序来使用乐观并发控制。

使用外部系统的版本

还有一种常见的情况就是我们还是使用其他的数据库来存储数据,而Elasticsearch只是帮我

们检索数据。这也就意味着主数据库只要发生的变更,就需要将其拷贝到Elasticsearch中。

如果多个进程同时发生,就会产生上文提到的那些并发问题。

如果你的数据库已经存在了版本号码,或者也可以代表版本的 时间戳 。这是你就可以在

Elasticsearch的查询字符串后面添加 version_type=external 来使用这些号码。版本号码必须

要是大于零小于 9.2e+18 (Java中long的最大正值)的整数

Elasticsearch在处理外部版本号时会与对内部版本号的处理有些不同。它不再是检

查 _version 是否与请求中指定的数值相同,而是检查当前的 _version 是否比指定的数值小

如果请求成功,那么外部的版本号就会被存储到文档中的 _version 中。

例如,创建一篇使用外部版本号为 5 的博文,我们可以这样操作:

PUT /website/blog/2?version=5&version_type=external
{
    "title": "My first external blog entry",
    "text": "Starting to get the hang of this..."
}

更新文档中的一部分

文档不能被修改,它们只能被替换掉。 更新 API也必须遵循这一法则。从 表面看来,貌似是文档被替换了。对内而言,它必须按照找回-修改-索引的流程来进行操作与管理。不同之处在于这个流程是在一个片(shard) 中完成的,因此可以节省多个请求所带来的 网络开销。除了节省了步骤,同时我们也能减少多个进程造成冲突的可能性。

使用 更新 请求最简单的一种用途就是添加新数据。新的数据会被合并到现有数据中,而如果 存在相同的字段,就会被新的数据所替换。例如我们可以为我们的博客添加 tags 和 views 字 段:

POST /website/blog/1/_update
{
    "doc" : {
        "tags" : [ "testing" ],
        "views": 0
    }
}

如果请求成功,我们就会收到一个类似于 索引 时返回的内容:

{
    "_index" : "website",
    "_id" : "1",
    "_type" : "blog",
    "_version" : 3
}

再次取回数据,你可以在 _source 中看到更新的结果:

{
    "_index": "website",
    "_type": "blog",
    "_id": "1",
    "_version": 3,
    "found": true,
    "_source": {
        "title": "My first blog entry",
        "text": "Starting to get the hang of this...",
        "tags": [ "testing" ], 
        "views": 0 
    }
}

MVEL是一个简单高效的JAVA基础动态脚本语言,它的语法类似于Javascript。你可以 在Elasticsearch scripting docs 以及 MVEL website了解更多关于MVEL的信息。

脚本语言可以在 更新 API中被用来修改 _source 中的内容,而它在脚本中被称为 ctx._source 。例如,我们可以使用脚本来增加博文中 views 的数字:

POST /website/blog/1/_update
{
    "script" : "ctx._source.views+=1"
}

这样Elasticsearch就可以重新使用这个脚本进行tag的添加,而不用再次重新编写脚本了:

POST /website/blog/1/_update
{
    "script" : "ctx._source.tags+=new_tag",
    "params" : {
      "new_tag" : "search"
    }
}

结果

{
    "_index": "website",
    "_type": "blog",
    "_id": "1",
    "_version": 5,
    "found": true,
    "_source": {
        "title": "My first blog entry",
        "text": "Starting to get the hang of this...",
        "tags": ["testing", "search"], <1>
        "views": 1 <2>
     }
}
  1. tags 数组中出现了 search 。
  2. views 字段增加了。

使用 ctx.op 来根据内容选择是否删除一个文档:

POST /website/blog/1/_update
{
    "script" : "ctx.op = ctx._source.views == count ? 'delete' : 'none'",
    "params" : {
      "count": 1
    }
}

更新一篇可能不存在的文档

我们可以使用 upsert 参数来设定文档不存在时,它应该被创建:

POST /website/pageviews/1/_update
{
    "script" : "ctx._source.views+=1",
    "upsert": {
        "views": 1
    }
}

首次运行这个请求时, upsert 的内容会被索引成新的文档,它将 views 字段初始化为 1 。当之后再请求时,文档已经存在,所以 脚本 更新就会被执行, views 计数器就会增加。

更新和冲突

你可以通过设定 retry_on_conflict 参数来设置自动完成这项请求的次数,它的默认值是 0 。

POST /website/pageviews/1/_update?retry_on_conflict=5 <1>
{
    "script" : "ctx._source.views+=1",
    "upsert": {
      "views": 0
    }
}

失败前重新尝试5次

这个参数非常适用于类似于增加计数器这种无关顺序的请求,但是还有些情况的顺序就是很 重要的。例如上一节提到的情况,你可以参考乐观并发控制以及悲观并发控制来设定文档的 版本号。

获取多个文档

如果你需要从Elasticsearch中获取多个文档,你可以使用multi-get 或者 mget API来取代一篇又一篇文档的获取。

mget API需要一个 docs 数组,每一个元素包含你想要的文档的 _index , _type 以及 _id 。 你也可以指定 _source 参数来设定你所需要的字段:

GET /_mget
{
    "docs" : [
        {
            "_index" : "website",
            "_type" : "blog",
            "_id" : 2
        },
        {
            "_index" : "website",
            "_type" : "pageviews",
            "_id" : 1,
            "_source": "views"
        }
    ]
}

返回值包含了一个 docs 数组,这个数组以请求中指定的顺序每个文档包含一个响应。每一个 响应都和独立的 get 请求返回的响应相同:

{
    "docs" : [
        {
            "_index" : "website",
            "_id" : "2",
            "_type" : "blog",
            "found" : true,
            "_source" : {
                "text" : "This is a piece of cake...",
                "title" : "My first external blog entry"
            },
            "_version" : 10
        },
        {
            "_index" : "website",
            "_id" : "1",
            "_type" : "pageviews",
            "found" : true,
            "_version" : 2,
            "_source" : {
                "views" : 2
            }
        }
    ]
}

如果你所需要的文档都在同一个 _index 或者同一个 _type 中,你就可以在URL中指定一个默 认的 /_index 或是 /_index/_type 。

GET /website/blog/_mget
{
    "docs" : [
        { "_id" : 2 },
        { "_type" : "pageviews", "_id" : 1 }
    ]
}

事实上,如果所有的文档拥有相同的 _index 以及 _type ,直接在请求中添加 ids 的数组即 可:

GET /website/blog/_mget
{
  "ids" : [ "2", "1" ]
}

请注意,我们所请求的第二篇文档不存在,这是就会返回如下内容:

{
    "docs" : [
        {
            "_index" : "website",
            "_type" : "blog",
            "_id" : "2",
            "_version" : 10,
            "found" : true,
            "_source" : {
                "title": "My first external blog entry",
                "text": "This is a piece of cake..."
            }
        },
        {
            "_index" : "website",
            "_type" : "blog",
            "_id" : "1",
            "found" : false <1>
        }
    ]
}

要确定独立的文档是否被成功找到,你需要检查 found 标识。

批量更高效

与 mget 能同时允许帮助我们获取多个文档相同, bulk API可以帮助我们同时完成执行多个请求,比如: create , index , update 以及 delete 。当你在处理类似于log等海量数据的时 候,你就可以一下处理成百上千的请求,这个操作将会极大提高效率。

bulk 的请求主体的格式稍微有些不同:

{ action: { metadata }}\n
{ request body }\n
{ action: { metadata }}\n
{ request body }\n
...

这种格式就类似于一个用 "\n" 字符来连接的单行json一样。下面是两点注意事项:

  1. 每一行都结尾处都必须有换行字符 "\n" ,最后一行也要有。这些标记可以有效地分隔每
    行。
  2. 这些行里不能包含非转义字符,以免干扰数据的分析 — — 这也意味着JSON不能是 pretty-printed样式。

action/metadata 行指定了将要在哪个文档中执行什么操作。

其中action必须是 index , create , update 或者 delete 。metadata 需要指明需要被操作文 档的 _index , _type 以及 _id ,例如删除命令就可以这样填写:

示例

{ "delete": { "_index": "website", "_type": "blog", "_id": "123" }}

在你进行 index 以及 create 操作时,request body 行必须要包含文档的 _source 数据——也 就是文档的所有内容。 同样,在执行 update API: doc , upsert , script 的时候,也需要包含相关数据。而在删除 的时候就不需要request body行。

{ "create": { "_index": "website", "_type": "blog", "_id": "123" }}
{ "title": "My first blog post" }

如果没有指定 _id ,那么系统就会自动生成一个ID:

{ "index": { "_index": "website", "_type": "blog" }}
{ "title": "My second blog post" }

完成以上所有请求的 bulk 如下:

POST /_bulk
{ "delete": { "_index": "website", "_type": "blog", "_id": "123" }} <1>
{ "create": { "_index": "website", "_type": "blog", "_id": "123" }}
{ "title": "My first blog post" }
{ "index": { "_index": "website", "_type": "blog" }}
{ "title": "My second blog post" }
{ "update": { "_index": "website", "_type": "blog", "_id": "123", "_retry_on_conflict"
: 3} }
{ "doc" : {"title" : "My updated blog post"} } <2>
  1. 注意 delete 操作是如何处理request body的,你可以在它之后直接执行新的操作。
  2. 请记住最后有换行符

Elasticsearch会返回含有 items 的列表、它的顺序和我们请求的顺序是相同的:

{
    "took": 4,
    "errors": false, <1>
    "items": [
        { "delete": {
            "_index": "website",
            "_type": "blog",
            "_id": "123",
            "_version": 2,
            "status": 200,
            "found": true
        }},
        { "create": {
            "_index": "website",
            "_type": "blog",
            "_id": "123",
            "_version": 3,
          "status": 201
        }},
        { "create": {
            "_index": "website",
            "_type": "blog",
            "_id": "EiwfApScQiiy7TIKFxRCTw",
            "_version": 1,
            "status": 201
        }},
        { "update": {
            "_index": "website",
            "_type": "blog",
            "_id": "123",
            "_version": 4,
            "status": 200
        }}
    ]
}}

所有的请求都被成功执行。

每一个子请求都会被单独执行,所以一旦有一个子请求失败了,并不会影响到其他请求的成功执行。如果一旦出现失败的请求error 就会变为 true ,详细的错误信息也会出现在返回 内容的下方:

POST /_bulk
{ "create": { "_index": "website", "_type": "blog", "_id": "123" }}
{ "title": "Cannot create - it already exists" }
{ "index": { "_index": "website", "_type": "blog", "_id": "123" }}
{ "title": "But we can update it" }

失败结果:

{
    "took": 3,
    "errors": true, <1>
    "items": [
        { "create": {
            "_index": "website",
            "_type": "blog",
            "_id": "123",
            "status": 409, <2>
            "error": "DocumentAlreadyExistsException <3>
                    [[website][4] [blog][123]:
                    document already exists]"
        }},
        { "index": {
            "_index": "website",
            "_type": "blog",
            "_id": "123",
            "_version": 5,
            "status": 200 <4>
        }}
    ]
}
  1. 至少有一个请求错误发生。
  2. 这条请求的状态码为 409 CONFLICT 。
  3. 错误信息解释了导致错误的原因。
  4. 第二条请求的状态码为 200 OK 。

能省就省

或许你在批量导入大量的数据到相同的 index 以及 type 中。每次都去指定每个文档的 metadata是完全没有必要的。在 mget API中, bulk 请求可以在URL中声明 /_index 或 者 /_index/_type :

POST /website/_bulk
{ "index": { "_type": "log" }}
{ "event": "User logged in" }

你依旧可以在metadata行中使用 _index 以及 _type 来重写数据,未声明的将会使用URL中的 配置作为默认值:

POST /website/log/_bulk
{ "index": {}}
{ "event": "User logged in" }
{ "index": { "_type": "blog" }}
{ "title": "Overriding the default type" }

最大有多大?

试着去批量索引越来越多的文档。当性能开始下降的时候,就说明你的数据量太大了。一般 比较好初始数量级是1000到5000个文档,或者你的文档很大,你就可以试着减小队列。 有的 时候看看批量请求的物理大小是很有帮助的。1000个1KB的文档和1000个1MB的文档的差距 将会是天差地别的。比较好的初始批量容量是5-15MB。

相关实践学习
使用阿里云Elasticsearch体验信息检索加速
通过创建登录阿里云Elasticsearch集群,使用DataWorks将MySQL数据同步至Elasticsearch,体验多条件检索效果,简单展示数据同步和信息检索加速的过程和操作。
ElasticSearch 入门精讲
ElasticSearch是一个开源的、基于Lucene的、分布式、高扩展、高实时的搜索与数据分析引擎。根据DB-Engines的排名显示,Elasticsearch是最受欢迎的企业搜索引擎,其次是Apache Solr(也是基于Lucene)。 ElasticSearch的实现原理主要分为以下几个步骤: 用户将数据提交到Elastic Search 数据库中 通过分词控制器去将对应的语句分词,将其权重和分词结果一并存入数据 当用户搜索数据时候,再根据权重将结果排名、打分 将返回结果呈现给用户 Elasticsearch可以用于搜索各种文档。它提供可扩展的搜索,具有接近实时的搜索,并支持多租户。
相关文章
|
2月前
|
SQL JSON API
ELK技术栈 - Elasticsearch 学习笔记(三)
ELK技术栈 - Elasticsearch 学习笔记(三)
39 0
|
2月前
|
JSON 数据可视化 应用服务中间件
ELK技术栈 - Kibana 学习笔记
ELK技术栈 - Kibana 学习笔记
40 0
|
3天前
|
Java Maven 开发工具
【ElasticSearch 】IK 分词器安装
【ElasticSearch 】IK 分词器安装
11 1
|
19天前
|
数据可视化 索引
elasticsearch head、kibana 安装和使用
elasticsearch head、kibana 安装和使用
|
1月前
|
存储 负载均衡 索引
linux7安装elasticsearch-7.4.0集群配置
linux7安装elasticsearch-7.4.0集群配置
113 0
|
2月前
|
存储 监控 搜索推荐
在生产环境中部署Elasticsearch:最佳实践和故障排除技巧——安装篇(一)
在生产环境中部署Elasticsearch:最佳实践和故障排除技巧——安装篇(一)
|
4月前
ElasticSearch-Head浏览器插件离线安装
ElasticSearch-Head浏览器插件离线安装
91 0
|
19天前
|
JSON Unix Linux
Elasticsearch如何安装
Elasticsearch如何安装
|
3月前
|
前端开发 安全 Ubuntu
Elasticsearch安装和配置
Elasticsearch安装和配置
116 0
|
4月前
|
数据可视化 Docker 容器
elasticsearch 安装(一)
elasticsearch 安装
162 0