使用 OpenSearch 和 MinIO 实现快速高效的搜索

Fast and Efficient Search with OpenSearch and MinIO

在这篇文章中,我们将探讨搜索,特别是 OpenSearch 如何帮助我们在不断增长的数据中识别模式或查看趋势。例如,如果您正在查看操作数据,如果您的服务似乎随机出现故障,您将需要尽可能地追溯历史数据,以识别模式并找出原因。这不仅适用于应用程序,还适用于来自各种设备的海量日志,这些日志需要在合理的时间范围内保留以用于合规性和故障排除目的。但是,将数月/数年可搜索数据存储在快速存储(例如 NVMe)上会占用大量昂贵的驱动器空间。通常来说,过去几周的数据搜索频率最高,因此存储在最快的硬件上。但随着数据越来越旧,它对于立即故障排除的用处就越来越小,而且不需要存储在昂贵的硬件上,即使它仍然隐藏着一些秘密。

问题变成,如何快速搜索这些存档数据,而不会牺牲性能。是否可以两者兼得?

登场 OpenSearch;一个基于 Apache Lucene 的分布式搜索和分析引擎。您可以在数据添加到 OpenSearch 索引后对其执行全文搜索。任何需要搜索的应用程序都有 OpenSearch 的用例,例如,您可以使用它在您的应用程序中构建搜索功能,DevOps 工程师可以将 OpenSearch 用作日志分析引擎,后端工程师可以将跟踪数据通过 OpenTelemetry 等收集器来获得对应用程序性能的更好洞察。借助内置的、功能丰富的搜索和可视化功能,您可以准确地查明基础设施问题,例如磁盘空间不足、出现错误状态码等,并在它们对运营造成严重影响之前将它们显示在仪表板中。

然而,随着日志数据的增长,有时将所有日志数据保留在一个节点甚至一个集群中并不实用。我们喜欢 OpenSearch,因为它具有分布式设计,与 MinIO 类似,MinIO 可以并行存储您的数据并处理请求。MinIO 非常易于设置,只需一个简单的二进制文件即可启动运行。您可以从笔记本电脑上的单个节点单个驱动器配置开始,并将其扩展到生产环境,包括多驱动器、多节点和多站点,并具有您在企业级存储软件中期望的相同功能集。您不仅可以构建分布式 OpenSearch 集群,还可以随着集群的增长细分集群中各个节点的职责。您可以拥有配备大型磁盘用于存储数据的节点、拥有大量 RAM 用于索引的节点,以及拥有大量 CPU 但磁盘更少的节点用于管理集群状态。

随着您的数据增长,您可以将旧的/存档数据层级到 MinIO 存储桶中,以便将 SSD/NVMe 存储保留用于添加到集群的最新数据。此外,您可以在数据存储在 MinIO 存储桶中时直接搜索这些快照。从逻辑上讲,在移动快照时,需要考虑从远程驱动器访问数据的速度比从本地驱动器访问数据的速度慢,因此通常预计搜索查询的延迟较高,但提高的存储效率通常值得。使用 MinIO,您将获得最快的网络对象存储。在高速网络上的分布式 MinIO 可以胜过本地存储,最近的一项基准测试 在 GET 操作中实现了 325 GiB/s(349 GB/s)的吞吐量,在 PUT 操作中实现了 165 GiB/s(177 GB/s)的吞吐量,仅使用 32 个节点的现成 NVMe SSD。与其他速度较慢的对象存储不同,MinIO 可以无缝地访问这些快照,就好像它们在 OpenSearch 集群上是本地的,在搜索抽取的日志数据中的见解时节省了宝贵的时间、网络带宽和团队工作量,具体取决于结果的大小,只需几秒钟即可完成。相比之下,本地恢复需要花费数小时才能执行操作,甚至才能查询数据。

OpenSearch 与存储分层一起使用时效率更高,这降低了其总拥有成本,此外,您还可以获得将数据写入 MinIO 的额外好处,这些数据是 不可变的版本化的,并受到 擦除编码 的保护。此外,将 OpenSearch 分层与 MinIO 对象存储一起使用会使数据文件可供其他云原生机器学习和分析应用程序使用。

基础架构

让我们使用 Docker 设置 OpenSearch 和 MinIO,并介绍一些功能来展示它们的 capabilities。

OpenSearch

我们将创建一个自定义的 Docker 镜像,因为我们将使用自定义插件将其构建到我们的 MinIO 对象存储中。

FROM opensearchproject/opensearch:2.8.0


ENV MINIO_ACCESS_KEY_ID minioadmin

ENV MINIO_SECRET_ACCESS_KEY minioadmin

ENV MINIO_ENDPOINT minio:9000

ENV MINIO_PROTOCOL http


RUN /usr/share/opensearch/bin/opensearch-plugin install --batch repository-s3

RUN /usr/share/opensearch/bin/opensearch-keystore create


RUN echo $MINIO_ACCESS_KEY_ID | /usr/share/opensearch/bin/opensearch-keystore add --stdin s3.client.default.access_key

RUN echo $MINIO_SECRET_ACCESS_KEY | /usr/share/opensearch/bin/opensearch-keystore add --stdin s3.client.default.secret_key

RUN echo $MINIO_ENDPOINT | /usr/share/opensearch/bin/opensearch-keystore add --stdin s3.client.default.endpoint

RUN echo $MINIO_PROTOCOL | /usr/share/opensearch/bin/opensearch-keystore add --stdin s3.client.default.protocol

构建自定义 Docker 镜像

docker build --tag=opensearch-minio

运行以下 Docker 命令,使用我们之前下载的镜像启动一个容器

docker run -d -p 9200:9200 -p 9600:9600 -v /usr/share/opensearch/data -e "discovery.type=single-node"  opensearch-minio

使用默认的 admin 凭据卷曲到本地主机端口 9200,以验证 OpenSearch 是否正在运行

curl https://:9200 -ku 'admin:admin'

您应该看到类似于下面的输出

{
  "name" : "a937e018cee5",
  "cluster_name" : "docker-cluster",
  "cluster_uuid" : "GLAjAG6bTeWErFUy_d-CLw",
  "version" : {
    "distribution" : "opensearch",
    "number" : <version>,
    "build_type" : <build-type>,
    "build_hash" : <build-hash>,
    "build_date" : <build-date>,
    "build_snapshot" : false,
    "lucene_version" : <lucene-version>,
    "minimum_wire_compatibility_version" : "7.10.0",
    "minimum_index_compatibility_version" : "7.0.0"
  },
  "tagline" : "The OpenSearch Project: https://opensearch.org/"
}

我们也可以检查容器状态

$ docker container ls
CONTAINER ID   IMAGE                                 COMMAND                  CREATED          STATUS          PORTS                                                                NAMES
a937e018cee5   opensearch-minio   "./opensearch-docker..."   19 minutes ago   Up 19 minutes   0.0.0.0:9200->9200/tcp, 9300/tcp, 0.0.0.0:9600->9600/tcp, 9650/tcp   stupendous_burt

MinIO

我们将使用 4 个磁盘启动一个 MinIO 节点。MinIO 可以在任何地方运行,并始终充分利用底层硬件。在本概述中,我们将使用 Docker 创建的容器。

对于这 4 个磁盘,请在主机上为 `minio` 创建目录

mkdir -p /home/aj/minio/disk-1 \
mkdir -p /home/aj/minio/disk-2 \
mkdir -p /home/aj/minio/disk-3 \
mkdir -p /home/aj/minio/disk-4

使用以下 MinIO 节点规范启动 Docker 容器

docker run -d \
  -p 20091:9001 \
  -v /home/aj/minio/disk-1:/mnt/disk1 \
  -v /home/aj/minio/disk-2:/mnt/disk2 \
  -v /home/aj/minio/disk-3:/mnt/disk3 \
  -v /home/aj/minio/disk-4:/mnt/disk4 \
  --name minio \
  --hostname minio \
  quay.io/minio/minio server http://minio/mnt/disk{1...4}/minio --console-address ":9001"

以上命令将在 Docker 中启动一个 MinIO 服务,并将控制台端口监听在主机上的 `20091`。它还将把我们创建的本地目录作为卷挂载到容器中,MinIO 将在此处存储其数据。您可以通过 `https://:20091` 访问您的 MinIO 服务。

状态:         4 在线, 0 离线。
API: http://172.20.0.2:9000  http://127.0.0.1:9000

控制台: http://172.20.0.2:9001 http://127.0.0.1:9001

文档: https://docs.min.io

如果您看到 4 在线,这意味着您已成功使用 4 个驱动器设置了 Minio 节点。

转到浏览器并加载位于 https://:20091 的 MinIO 控制台。使用 minioadminminioadmin 分别作为用户名和密码登录。单击 创建存储桶 按钮并创建 testbucket123

在 MinIO 控制台中,请注意有一个点对点 指标仪表盘,您可以使用它来快速简便地监控您的对象存储集群。

设置 MinIO 仓库

为了设置可搜索的快照索引,您需要对 OpenSearch 集群进行一些先决条件和配置。我们将在此处详细介绍它们。

opensearch.yaml 中创建一个节点并定义节点角色

node.name: snapshots-node
node.roles: [ search ]

让我们使用 _snapshot API 注册 MinIO 存储桶

curl -XPUT "https://:9200/_snapshot/my-minio-repository" -H 'Content-Type: application/json' -d'
{
  "type": "s3",
  "settings": {
    "bucket": "testbucket123",
    "base_path": "my/snapshot/directory"
  }
}'

现在我们有了仓库,让我们继续创建一个可搜索的快照。

可搜索快照

为了制作快照,我们需要使用之前创建的仓库进行 API 调用。

curl -XPUT "https://:9200/_snapshot/my-minio-repository/1"

让我们检查快照的状态

curl -XGET "https://:9200/_snapshot/my-minio-repository/1"
{
  "snapshots": [{
    "snapshot": "1",
    "version": "6.5.4",
    "indices": [
      "opensearch_dashboards_sample_data_ecommerce",
      "my-index",
      "opensearch_dashboards_sample_data_logs",
      "opensearch_dashboards_sample_data_flights"
    ],
    "include_global_state": true,
    "state": "IN_PROGRESS",
    ...
  }]
}

让我们也看看 MinIO 端的这个快照

root@aj-test-1:~# mc ls testbucket123/my/snapshot/directory
[2023-06-09 17:37:31 UTC] 1.5KiB STANDARD 1/

如您在上面看到的,在 MinIO 存储桶中有一个我们使用 OpenSearch API 拍摄的快照的副本。

现在你一定在想,“我们已经创建了快照,但如何恢复它以便我们能够分析和搜索备份索引?” 虽然 OpenSearch 可以完全恢复快照,但我们不会以传统意义上的方式恢复整个快照,而是会向你展示如何在快照仍存储在 MinIO 上时更有效地搜索它。

我们需要进行的最重要的配置更改是将 storage_type 设置为 remote_snapshot。 此设置告诉 OpenSearch 快照是将被恢复到本地以供搜索,还是在存储在 MinIO 上时进行远程搜索。

curl -XPOST "https://:9200/_snapshot/my-minio-repository/1/_restore" -H 'Content-Type: application/json' -d'
{
  "indices": "opensearch-dashboards*,my-index*",
  "ignore_unavailable": true,
  "include_global_state": false,
  "include_aliases": false,
  "partial": false,

  "storage_type": "remote_snapshot",
  "rename_pattern": "opensearch-dashboards(.+)",
  "rename_replacement": "restored-opensearch-dashboards$1",
  "index_settings": {
    "index.blocks.read_only": false
  },
  "ignore_index_settings": [
    "index.refresh_interval"
  ]
}'

让我们列出所有索引,看看是否存在 remote_snapshot 类型。

curl -XGET "https://:9200/my-index/_settings?pretty"

{
  "my-index": {
    "settings": {
      "index": {
        "store": {
          "type": "remote_snapshot"
        }
      }
    }
  }
}

如你所见,将 MinIO 配置为 OpenSearch 远程存储库非常简单。

取回你的日志

通过利用 MinIO 作为 OpenSearch 的后端,你不仅可以创建可搜索快照,还可以创建不可搜索(也称为“本地”)快照,并将它们用作常规备份,可以将它们恢复到其他集群以进行灾难恢复,或者用更多数据进行丰富以进行进一步分析。

话虽如此,我们需要注意使用远程存储库作为快照位置的一些潜在陷阱。访问速度或多或少由 MinIO 的速度和性能决定,而这通常受网络带宽限制。请注意,在 AWS S3 等公有云中,您可能还会按请求次数收费以进行检索,因此用户应密切监控发生的任何费用。搜索远程数据有时会影响同一节点上运行的其他查询的性能。通常建议工程师利用节点角色并为性能关键型应用程序创建具有搜索角色的专用节点。

如果您有任何关于如何使用 OpenSearch 与 MinIO 的问题,请务必在 Slack 上与我们联系!