使用自己的数据集预加载 Elasticsearch

news2024/12/23 22:35:21

作者:David Pilato

我最近在讨论论坛上收到一个问题,关于如何修改官方 Docker 镜像以提供一个现成的 Elasticsearch 集群,其中已经包含一些数据。

说实话,我不喜欢这个想法,因为你必须通过提 entrypoint.sh 的分叉版本来破解 Elasticsearch 服务的启动方式。 这将使你的维护和升级变得更加困难。

相反,我发现使用其他解决方案来实现相同的目标会更好。

设置问题

首先,我们将考虑使用 Elasticsearch Docker 镜像并遵循文档:

docker pull docker.elastic.co/elasticsearch/elasticsearch:8.7.0
docker network create elastic
docker run --name es01 --net elastic -p 9200:9200 -it docker.elastic.co/elasticsearch/elasticsearch:8.7.0

请注意,我们没有在此处挂载 data 目录,因此该集群的数据将是短暂的,并且一旦节点关闭就会消失。 启动后,我们可以使用生成的密码检查它是否运行良好:

curl -s -k -u elastic:CHANGEME https://localhost:9200 | jq

请使用在安装时候显示的 Elasticsearch 密码来替换上面的 CHANGEME。上面的命令给出:

{
  "name": "697bf734a5d5",
  "cluster_name": "docker-cluster",
  "cluster_uuid": "cMISiT__RSWkoKDYql1g4g",
  "version": {
    "number": "8.7.0",
    "build_flavor": "default",
    "build_type": "docker",
    "build_hash": "09520b59b6bc1057340b55750186466ea715e30e",
    "build_date": "2023-03-27T16:31:09.816451435Z",
    "build_snapshot": false,
    "lucene_version": "9.5.0",
    "minimum_wire_compatibility_version": "7.17.0",
    "minimum_index_compatibility_version": "7.0.0"
  },
  "tagline": "You Know, for Search"
}

因此,我们希望有一个可用的数据集。 让我们采用我在演示 Elasticsearch 时经常使用的示例数据集:人员数据集。 我创建了[一个生成器](https://github.com/dadoonet/injector) 来创建一些假数据。

首先,让我们下载注入器:

wget https://repo1.maven.org/maven2/fr/pilato/elasticsearch/injector/injector/8.7/injector-8.7.jar

然后我们将使用以下选项在磁盘上生成数据集:

mkdir data
java -jar injector-8.7.jar --console --silent > data/persons.json

我们有 1000000 个 json 文档,数据集如下所示:

head -2 data/persons.json

{"name":"Charlene Mickael","dateofbirth":"2000-11-01","gender":"female","children":3,"marketing":{"cars":1236,"shoes":null,"toys":null,"fashion":null,"music":null,"garden":null,"electronic":null,"hifi":1775,"food":null},"address":{"country":"Italy","zipcode":"80100","city":"Ischia","countrycode":"IT","location":{"lon":13.935138341699972,"lat":40.71842684204817}}}
{"name":"Kim Hania","dateofbirth":"1998-05-18","gender":"male","children":4,"marketing":{"cars":null,"shoes":null,"toys":132,"fashion":null,"music":null,"garden":null,"electronic":null,"hifi":null,"food":null},"address":{"country":"Germany","zipcode":"9998","city":"Berlin","countrycode":"DE","location":{"lon":13.164834451298645,"lat":52.604673827377155}}}

使用 shell 脚本

我们这里有 100 万个文档,因此我们无法真正使用批量请求来发送它。 我们需要:

  • 分成 10000 个或更少的索引操作
  • 对于每个文档,添加缺少的 bulk 标题
  • 使用 _bulk API 发送文档 我最终编写了这个脚本,它要求你安装了 curl 和 jq:
#!/bin/bash
ELASTIC_PASSWORD=CHANGEME
mkdir tmp
echo "Split the source in 10000 items"
split -d -l10000 ../data/persons.json tmp/part
BULK_REQUEST_FILE="tmp/bulk_request.ndjson"
FILES="tmp/part*"
for f in $FILES
do
  rm $BULK_REQUEST_FILE
  echo "Preparing $f file..."
  while read p; do
    echo -e '{"index":{}}' >> $BULK_REQUEST_FILE
    echo -e "$p" >> $BULK_REQUEST_FILE
  done <$f
  echo "Calling Elasticsearch Bulk API"
  curl -XPOST -s -k -u elastic:$ELASTIC_PASSWORD https://localhost:9200/person/_bulk -H 'Content-Type: application/json' --data-binary "@$BULK_REQUEST_FILE" | jq '"Bulk executed in \(.took) ms with errors=\(.errors)"'
done

有关脚本输入文档的方法,你也可以参考文章 “Elasticsearch:如何使用 shell 脚本来写入数据到 Elasticsearch 中”。

这基本上打印:

Preparing tmp/part00 file...
Calling Elasticsearch Bulk API
"Bulk executed in 1673 ms with errors=false"
Preparing tmp/part01 file...
Calling Elasticsearch Bulk API
"Bulk executed in 712 ms with errors=false"
...
Preparing tmp/part99 file...
Calling Elasticsearch Bulk API
"Bulk executed in 366 ms with errors=false"

在我的机器上,运行它需要 8 分钟多。 大部分时间都花在编写批量请求上。 可能还有很大的改进空间,但我必须承认我不太擅长编写 shell 脚本。 哈? 你已经猜到了吗? 😅

使用logstash

Logstash 可以完成与我们手动完成的类似工作,但还提供更多功能,例如错误处理、监控,我们甚至不需要编写代码... 我们将在这里再次使用 Docker:

docker pull docker.elastic.co/logstash/logstash:8.7.0

让我们为此编写一个作业:

input {
  file {
    path => "/usr/share/logstash/persons/persons.json"
    mode => "read"
    codec => json { }
    exit_after_read => true
  }
}

filter {
  mutate {
    remove_field => [ "log", "@timestamp", "event", "@version" ]
  }
}

output {
  elasticsearch {
    hosts => "${ELASTICSEARCH_URL}"
    index => "person"
    user => "elastic"
    password => "${ELASTIC_PASSWORD}"
    ssl_certificate_verification => false
  }
}

我们现在可以运行该作业:

docker run --rm -it --name ls01 --net elastic \
  -v $(pwd)/../data/:/usr/share/logstash/persons/:ro \
  -v $(pwd)/pipeline/:/usr/share/logstash/pipeline/:ro \
  -e XPACK_MONITORING_ENABLED=false \
  -e ELASTICSEARCH_URL="https://es01:9200" \
  -e ELASTIC_PASSWORD="CHANGEME" \
  docker.elastic.co/logstash/logstash:8.7.0

在我的机器上,运行它只需要不到 2 分钟。

使用 docker 撰写

你可以更轻松地使用 docker compose 命令来根据需要运行所有内容,并向用户公开一个可供使用的集群,而不是手动运行所有这些内容。 这是一个简单的 .env 文件:

ELASTIC_PASSWORD=CHANGEME
STACK_VERSION=8.7.0
ES_PORT=9200

以及 docker-compose.yml:

version: "2.2"
services:
  es01:
    image: docker.elastic.co/elasticsearch/elasticsearch:${STACK_VERSION}
    ports:
      - ${ES_PORT}:9200
    environment:
      - node.name=es01
      - cluster.initial_master_nodes=es01
      - ELASTIC_PASSWORD=${ELASTIC_PASSWORD}
      - bootstrap.memory_lock=true
    ulimits:
      memlock:
        soft: -1
        hard: -1
    healthcheck:
      test:
        [
          "CMD-SHELL",
          "curl -s -k https://localhost:9200 | grep -q 'missing authentication credentials'",
        ]
      interval: 10s
      timeout: 10s
      retries: 120
  logstash:
    depends_on:
      es01:
        condition: service_healthy
    image: docker.elastic.co/logstash/logstash:${STACK_VERSION}
    volumes:
      - type: bind
        source: ../data
        target: /usr/share/logstash/persons
        read_only: true
      - type: bind
        source: pipeline
        target: /usr/share/logstash/pipeline
        read_only: true
    environment:
      - ELASTICSEARCH_URL=https://es01:9200
      - ELASTIC_PASSWORD=${ELASTIC_PASSWORD}
      - XPACK_MONITORING_ENABLED=false

我们仍然在 ../data 目录中保存有 person.json 文件。 它被安装为 /usr/share/logstash/persons/persons.json ,就像在前面的示例中一样。 因此,我们使用与之前相同的 pipeline/persons.conf 文件。 要运行它,我们现在只需输入:

docker compose up

并等待 with-compose-logstash-1 容器退出:

with-compose-logstash-1  | [2023-04-21T15:17:55,335][INFO ][logstash.runner          ] Logstash shut down.
with-compose-logstash-1 exited with code 0

这表明我们的服务现在已准备好运行并完全加载了我们的示例数据集。

有关这个部分的内容,更多阅读请参考:数据集成的强大联盟:Elasticsearch、Kibana、Logstash、MySQL。

使用快照/恢复

你还可以使用创建快照 API 将 Elasticsearch 中的现有数据集备份到共享文件系统或 S3,然后使用 Restore Restore API 将其恢复到新集群。 假设你已经注册了一个名为 example 的存储库。 你可以使用以下命令创建快照:

# We force merge the segments first
POST /person/_forcemerge?max_num_segments=1

# Snapshot the data
PUT /_snapshot/sample/persons
{
  "indices": "person",
  "include_global_state": false
}

因此,无论何时启动新集群,你都可以使用以下命令恢复快照:

POST /_snapshot/sample/persons/_restore

你只需要小心使用此方法,当你将其升级到新的主要版本时,你拥有的快照仍然可以在集群中恢复。 例如,如果你使用版本 6.3 创建了快照,则无法在 8.2 中还原它。 有关更多详细信息,请参阅快照索引兼容性。 但好消息! 借助存档索引,Elasticsearch 现在能够访问较旧的快照存储库(返回到版本 5)... 你只需要了解一些限制即可。 为了保证你的快照始终完全兼容,你可能需要使用相同的脚本使用最新版本再次创建索引快照。 请注意,在这种情况下,Force Merger API 调用很重要,因为它将使用最新的 Elasticsearch/Lucene 版本重写所有段。

使用已挂载的目录

还记得我们启动集群时的情况吗?

docker run --name es01 --net elastic -p 9200:9200 -it docker.elastic.co/elasticsearch/elasticsearch:8.7.0

我们没有绑定挂载 data 和 config 目录。 但实际上我们可以这样做:

docker run --name es01 --net elastic -p 9200:9200 -it -v persons-data:/usr/share/elasticsearch/data -v persons-config:/usr/share/elasticsearch/config docker.elastic.co/elasticsearch/elasticsearch:8.7.0

我们可以检查刚刚创建的 Docker volume:

docker volume inspect persons-data persons-config
[
    {
        "CreatedAt": "2023-05-09T10:20:14Z",
        "Driver": "local",
        "Labels": null,
        "Mountpoint": "/var/lib/docker/volumes/persons-data/_data",
        "Name": "persons-data",
        "Options": null,
        "Scope": "local"
    },
    {
        "CreatedAt": "2023-05-09T10:19:51Z",
        "Driver": "local",
        "Labels": null,
        "Mountpoint": "/var/lib/docker/volumes/persons-config/_data",
        "Name": "persons-config",
        "Options": null,
        "Scope": "local"
    }
]

如果你想使用完全相同的命令行再次启动 Elasticsearch 节点,你可以稍后再次重用此挂载点。 如果需要与其他用户共享卷,可以将 /var/lib/docker/volumes/persons-config/ 和 /var/lib/docker/volumes/persons-data/ 中的数据备份到 /tmp/volume-backup:

然后你可以与其他用户共享 /tmp/volume-backup/persons.tgz 文件并让他们恢复它。

docker volume create persons-config
docker volume create persons-data
docker run --rm -it -v /tmp/volume-backup:/backup -v /var/lib/docker:/docker alpine:edge tar xfz /backup/persons.tgz -C /

并再次启动容器:

docker run --name es01 --net elastic -p 9200:9200 -it -v persons-data:/usr/share/elasticsearch/data -v persons-config:/usr/share/elasticsearch/config docker.elastic.co/elasticsearch/elasticsearch:8.7.0

使用 Elastic Cloud

当然,你可以使用之前创建的快照来配置新的 Elasticsearch Cloud 实例,而不是自行启动和管理本地 Elasticsearch 实例。 以下代码假设你已经定义了 API key。

POST /api/v1/deployments?validate_only=false
{
  "resources": {
    "elasticsearch": [
      {
        "region": "gcp-europe-west1",
        "plan": {
          "cluster_topology": [
            {
              "zone_count": 2,
              "elasticsearch": {
                "node_attributes": {
                  "data": "hot"
                }
              },
              "instance_configuration_id": "gcp.es.datahot.n2.68x10x45",
              "node_roles": [
                "master",
                "ingest",
                "transform",
                "data_hot",
                "remote_cluster_client",
                "data_content"
              ],
              "id": "hot_content",
              "size": {
                "resource": "memory",
                "value": 8192
              }
            }
          ],
          "elasticsearch": {
            "version": "8.7.1"
          },
          "deployment_template": {
            "id": "gcp-storage-optimized-v5"
          },
          "transient": {
            "restore_snapshot": {
              "snapshot_name": "__latest_success__",
              "source_cluster_id": "CLUSTER_ID"
            }
          }
        },
        "ref_id": "main-elasticsearch"
      }
    ],
    "kibana": [
      {
        "elasticsearch_cluster_ref_id": "main-elasticsearch",
        "region": "gcp-europe-west1",
        "plan": {
          "cluster_topology": [
            {
              "instance_configuration_id": "gcp.kibana.n2.68x32x45",
              "zone_count": 1,
              "size": {
                "resource": "memory",
                "value": 1024
              }
            }
          ],
          "kibana": {
            "version": "8.7.1"
          }
        },
        "ref_id": "main-kibana"
      }
    ]
  },
  "settings": {
    "autoscaling_enabled": false
  },
  "name": "persons",
  "metadata": {
    "system_owned": false
  }
}

只需将 CLUSTER_ID 替换为从中获取快照的源集群即可。 集群启动后,你就拥有了一个功能齐全的实例,可以在互联网上使用你想要的默认数据集。 完成后,你可以使用以下命令轻松关闭部署:

POST /api/v1/deployments/DEPLOYMENT_ID/_shutdown

同样,只需将 DEPLOYMENT_ID 替换为你在创建部署时看到的部署 ID。

结论

与往常一样,对于 Elastic,特别是 Elasticsearch,你有多种方法可以实现你的目标。 我在这里列出了其中一些,但可能还有其他一些方法:

  • 使用 Shell 脚本:你实际上不需要任何第三方工具,但这需要编写一些代码。 代码看起来很简单,只要偶尔运行一下就可以了。 如果你需要它更安全,例如具有捕获和重试功能,那么这将使你创建和维护更多代码。
  • 使用 Logstash:它非常灵活,因为你还可以将数据发送到 Elasticsearch 之外的其他目的地,或者使用多个过滤器来修改/丰富源数据集。 启动速度有点慢,但出于测试目的,这不应该成为真正的问题。
  • 使用 docker compose:我最喜欢的方法之一。 你只需运行 docker compose up 等,几分钟后就完成了。 但这可能需要时间和硬件资源。
  • 使用快照/恢复:比以前的方法更快,因为数据已经建立索引。 但灵活性较差,因为快照需要与你要恢复到的集群兼容。 一般来说,我总是更喜欢再次注入数据,因为一切都是新鲜的,并且我可以从 Elasticsearch 和 Lucene 的所有改进中受益。
  • 使用挂载目录:类似于快照,但更本地化。 老实说,我更喜欢使用 Elastic API,而不是手动挂载现有目录。 让 Elasticsearch 做它知道的事情让我感觉更安全。
  • 使用 Elastic Cloud:我认为这是与其他人(例如客户或内部测试人员)共享数据集的最简单方法。 一切都已准备就绪,安全,可以通过适当的 SSL 证书使用。

根据你的品味和限制,你可以选择其中一种想法并根据你的需求进行调整。 如果你有其他好主意要分享,请在 Twitter 上告诉我们或讨论区。 许多很棒的想法/功能都来自社区。 分享你的!

原文:Preload Elasticsearch with your dataset | Elastic Blog

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/857530.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

九齐NY8BE62D软件开发

开启100us中断 void Time_Init(void) {DISI();//;Initial Timer0PCON1 C_TMR0_Dis; // Disable Timer0TMR0 100; // Load 0x00 to TMR0 (Initial Timer0 register)T0MD C_PS0_TMR0 | C_PS0_Div2; INTE C_INT_TMR0;PCON1 C_TMR0_En; // Enable Timer0ENI(); // Ena…

论文解读|快速可认证的点云配准

原创 | 文 BFT机器人 《TEASER: Fast and Certifiable Point Cloud Registration》是一篇由Yang et al. 在IEEE Transactions on Robotics杂志上发表的研究论文&#xff0c;于2021年4月出版。这篇论文提出了两种快速且可验证的点云配准算法&#xff1a;TEASER和TEASER&#xf…

院线电影票特惠购票系统--竞价分销模式开发

竞价分销模式是一种基于拍卖理论的销售模式&#xff0c;卖家设定一个底价&#xff0c;由买家进行竞价&#xff0c;最终以最高出价者的价格成交。这种模式在电影票销售中的应用可以有效地提高电影院的售票量和收益。在竞价分销模式中&#xff0c;需要开发一个高效的系统来支持这…

VS Code配置Prettier格式化Apex

先决条件 安装nodejs和npm安装vs code安装salesforce extension pack 配置Prettier Apex 创建本地Salesforce项目 (Standard) command shift p -> SFDX: Create Project with Manifest -> Standard 打开terminal运行npm init生成package.json文件 安装prettier ap…

汽车IVI中控开发入门及进阶(十):车载摄像头接口CVBS、AHD和MIPI

文章目录 前言一、CVBS是什么?二、AHD是什么?三、MIPI是什么?前言 汽车电子电气架构正在由传统的分布式架构向域集中式架构转变,也就是将多个应用程序集中在一个域中,正如提到IVI,有些已经开始导入域控,除了一带多的显示屏、一带多的雷达传感器,当然还有一带多的摄像头…

设计HTML5文档结构

定义清晰、一致的文档结构不仅方便后期维护和拓展&#xff0c;同时也大大降低了CSS和JavaScript的应用难度。为了提高搜索引擎的检索率&#xff0c;适应智能化处理&#xff0c;设计符合语义的结构显得很重要。 1、头部结构 在HTML文档的头部区域&#xff0c;存储着各种网页元…

React源码解析18(3)------ beginWork的工作流程

摘要 OK&#xff0c;经过上一篇文章。我们调用了&#xff1a; const root document.querySelector(#root); ReactDOM.createRoot(root)生成了FilberRootNode和HostRootFilber。 并且二者之间的对应关系也已经确定。 而下一步我们就需要调用render方法来讲react元素挂载在ro…

研究:ChatGPT在生成代码方面的准确率比抛硬币还低!

✍创作者&#xff1a;全栈弄潮儿 &#x1f3e1; 个人主页&#xff1a; 全栈弄潮儿的个人主页 &#x1f3d9;️ 个人社区&#xff0c;欢迎你的加入&#xff1a;全栈弄潮儿的个人社区 &#x1f4d9; 专栏地址&#xff1a;AI大模型 ChatGPT真的能帮助程序员&#xff1f;研究&#…

【Opencv入门到项目实战】(八):图形直方图|傅里叶变换

所有订阅专栏的同学可以私信博主获取源码文件 文章目录 1.图像直方图1.1 直方图计算1.2 分通道读取1.3 mask操作&#xff08;掩码操作&#xff09; 2.傅里叶变换2.1 频率转换结果2.2 高通和低通滤波器 1.图像直方图 1.1 直方图计算 直方图是一种用于可视化数据分布的图表形式…

朋友圈截图生成,制作朋友圈网页

使用教程可以自己看工具的使用手册。 Windows电脑版&#xff1a; https://imageio.jscs.top/zip/wxchat-moment-windows Mac电脑版&#xff1a; https://imageio.jscs.top/zip/wxchat-moment-mac 这款神器的主要功能是朋友圈评论截图生成器&#xff0c;而且还具有以下功能中…

cesium学习记录05-支持的主要数据格式与服务

1. 矢量数据&#xff1a; 1.1. GeoJSON 定义&#xff1a; 一个基于JSON的地理数据格式&#xff0c;Cesium支持GeoJSON的直接加载。 例子&#xff1a; 加载一个简易故宫建筑的GeoJSON数据。 代码&#xff1a; /*** 添加故宫geojson数据*/AddGuGong() {var viewer this.v…

【Linux从入门到精通】文件操作(C语言vs系统调用)

文章目录 一、C语言的文件IO相关函数操作 1、1 fopen与fclose 1、2 fwrite 1、3 fprintf与fscanf 1、4 fgets与fputs 二、系统调用相关接口 2、1 open与close 2、2 write和read 三、简易模拟实现cat指令 四、总结 &#x1f64b;‍♂️ 作者&#xff1a;Ggggggtm &#x1f64b;‍…

AP2915DC-DC降压恒流驱动IC LED电源驱动芯片 汽车摩托电动车灯

AP2915 是一款可以一路灯串切换两路灯串的降压 恒流驱动器,高效率、外围简单、内置功率管&#xff0c;适用于 5-80V 输入的高精度降压 LED 恒流驱动芯片。内置功 率管输出功率可达 12W&#xff0c;电流 1.2A。 AP2915 一路灯亮切换两路灯亮&#xff0c;其中一路灯亮可 以全亮&a…

C++,文本文件,读取文件

代码演示&#xff1a; #include<iostream> using namespace std; #include<string> #include<fstream>void test() {//1、包含头文件//2、创建流对象ifstream ifs;//3、打开文件并判断文件是否成功ifs.open("test.txt", ios::in);if (!ifs.is_ope…

问道管理:A股缩量整理 新股上演久违暴涨模式

周三&#xff0c;大盘低开后震动&#xff0c;三大指数小幅跌落&#xff0c;创业板指相对偏强。 早盘开盘后&#xff0c;沪指、深证成指弱势震动&#xff0c;创业板指探底上升翻红&#xff0c;盘面热门乏善可陈。午后三大指数震动走弱&#xff0c;创业板指再度翻绿。医药板块活…

Vue 实现重定向、404和路由钩子(六)

一、重定向 1.1 修改 Main.vue <template><div><el-container><el-aside width"200px"><el-menu :default-openeds"[1]"><el-submenu index"1"><template slot"title"><i class"…

伪原创神码ai怎么样【php源码】

这篇文章主要介绍了python汉化补丁包下载&#xff0c;具有一定借鉴价值&#xff0c;需要的朋友可以参考下。希望大家阅读完这篇文章后大有收获&#xff0c;下面让小编带着大家一起了解一下。 火车头采集ai伪原创插件截图&#xff1a; ** Spyder汉化&#xff08;python汉化&…

在vue项目使用数据可视化 echarts ,柱状图、折线图、饼状图使用示例详解及属性详解

官网地址&#xff1a;Apache ECharts ​一、下载插件并在页面中引入 npm install echarts --save 页面导入&#xff1a; import * as echarts from echarts 全局导入&#xff1a; main.js 中&#xff0c;导入并注册到全局 import echarts from echarts Vue.prototype.$echart…

【云存储】【腾讯云】【阿里云】【b2】【google drive】【one drive】【s3】【azure】对比

【1】google drive 【2】b2 price 【3】腾讯云对象存储 文档中心 > 对象存储 > 开发者指南 > 对象 > 存储类型 > 存储类型概述 文档中心 > 对象存储 > 购买指南 > 计费项 > 数据取回费用

【计算机组成原理】24王道考研笔记——第四章 指令系统

第四章 指令系统 一、指令系统 指令是指示计算机执行某种操作的命令&#xff0c;是计算机运行的最小功能单位。一台计算机的所有指令的集合构成该 机的指令系统&#xff0c;也称为指令集。 指令格式&#xff1a; 1.1分类 按地址码数目分类&#xff1a; 按指令长度分类&…