只有在索引时才增加节点数量,以加快向Elasticsearch投入数据的速度

这篇文章是Elastic Stack (Elasticsearch) Advent Calendar 2020 12月15日的文章。

想做的事情 zuò de

您好,我是Supership株式会社的中野。在工作中,我们构建和运营数据集计和分析基础设施以及全文搜索系统。
如果要在分析目的中使用Elasticsearch,尽管可以在少数节点上快速过滤和聚合大量数据,但由于索引负载较重,导致数据投入时间较长。
如果使用较少节点来适应聚合负载,索引速度会变慢。然而,保持大量节点来适应索引负载则会增加成本。因此,我认为我们可以在索引时增加节点数量以在短时间内完成处理,而在集计时则使用较少的节点来运营Elasticsearch以控制成本。

做过的事概述

我使用三种方法计量了将650GB、20.3亿个数据导入到m6gd.4xlarge 1node上的Elasticsearch,并使其可用所需的时间。

indexing方法所要時間1nodeのまま直接indexing237分2秒5nodeに増強してindexingし、1nodeにshardを転送して縮退66分52秒 (indexing 54分55秒 + shard転送 11分57秒)5nodeの一時クラスタでindexingし、S3 snapshot & restoreで集計用クラスタに転送84分37秒 (indexing 54分55秒 + S3 snapshot 4分51秒 + restore 24分51秒)

通过暂时增加节点数量,我们确认可以在短时间内完成索引。让我们仔细看一下。

详细资料 xì zī

共同点

在本次验证中,我们已经根据以下内容统一了数据服务器的设置。

    • データ

非圧縮状態のjsonlファイルで650GB
20.3億件

Elasticsearch 7.10
サーバはAWS EC2 m6gd.4xlarge

今回のようにCPUの複数コアを全開で回す用途では、Graviton2プロセッサのコスパが圧倒的

ディスクIOがボトルネックになるのを避けるため、Elasticsearchのデータとログはインスタンスストレージに置く
本番と同等のデータ量を想定したノードサイズ
m6gdは日本では未提供なのでus-east-1で検証

indexing速度最優先の設定

shard数 = Elasticsearchクラスタ全体に割り当てたvCPU数 とする

検索・集計の点からはshard過多。対処は後日改めて考える

data post 並列数 = Elasticsearchクラスタ全体に割り当てたvCPU数 とする
refresh_intervalは0、全データPOST後に自分で_refreshを呼ぶ

直接索引1node。

direct-indexing.jpg

将5个节点进行增强并进行索引,将分片转移到1个节点以进行收缩。

scale-indexing.jpg

构建和实施的要点

    • indexing中だけ稼働させるノードは、elasticsearch.ymlにnode.roles: [data]を設定し、データ専業ノードとします。

 

    Elasticsearchのデフォルト設定では、shardの転送が負荷にならないよう制限がかかっています。今回は負荷低減よりも速度を優先したいので、下記の操作を行って制限を緩めておきます。
PUT /_cluster/settings
{
  "persistent" : {
    "indices.recovery.max_bytes_per_sec" : "100gb",
    "indices.recovery.max_concurrent_file_chunks": 4,
    "indices.recovery.max_concurrent_operations": 4,
    "cluster.routing.allocation.node_concurrent_recoveries": 16
  }
}
    indexing, refreshが完了した後、下記の操作を行うことでshardの転送が始まります。
PUT /_cluster/settings
{
  "transient": {
    "cluster.routing.allocation.exclude._ip": "退役させるノードのIPアドレスをカンマ区切りで"
  }
}
    shardの転送が完了してindexingに使ったノードを終了させたら、次に同じIPアドレスが使われたときに誤動作しないようallocationの除外設定を外しておきます。
PUT /_cluster/settings
{
  "transient": {
    "cluster.routing.allocation.exclude._ip": ""
  }
}

在5节点的临时集群上进行索引,并通过S3快照和恢复将其传输到用于聚合的集群。

dedicated-cluster.jpg

构建和实施的重点

    indexing用一時クラスタ、集計用クラスタの両方でrepository S3 pluginが必要です。aarch64用のElasticsearchはelasticsearch-plugin installコマンドがハングアップして正常終了しないため、zipファイルを特定のディレクトリに展開することでプラグインのインストールを行います。
$ curl -XGET 'https://artifacts.elastic.co/downloads/elasticsearch-plugins/repository-s3/repository-s3-7.10.0.zip' > repository-s3-7.10.0.zip
$ sudo unzip -d /usr/share/elasticsearch/plugins/repository-s3 repository-s3-7.10.0.zip
    S3 snapshotを利用するには、indexing用一時クラスタ、集計用クラスタの両方でsnapshotリポジトリを定義しておきます。
PUT /_snapshot/<snapshotリポジトリ名>
{
  "type": "s3",
  "settings": {
    "bucket": "S3バケット名",
    "base_path": "path/to/snapshot/location",
    "max_snapshot_bytes_per_sec": "100gb"
  }
}
    indexing, refreshが完了した後、indexing用一時クラスタで下記の操作を行うことで、S3にindex snapshotが作られます。
PUT /_snapshot/<snapshotリポジトリ名>/<snapshot名>?wait_for_completion=true
{
  "indices": "snapshotするindexをカンマ区切りで",
  "include_global_state": false,
  "metadata": {
    "taken_by": "me",
    "comment": "test"
  }
}
    Elasticsearchのデフォルト設定では、リカバリが負荷にならないよう制限がかかっています。今回は負荷低減よりも速度を優先したいので、集計用ESクラスタで下記の操作を行って制限を緩めておきます。
PUT /_cluster/settings
{
  "persistent" : {
    "indices.recovery.max_bytes_per_sec" : "100gb",
    "indices.recovery.max_concurrent_file_chunks": 4,
    "indices.recovery.max_concurrent_operations": 4,
    "cluster.routing.allocation.node_concurrent_recoveries": 16
  }
}
    集計用クラスタで下記の操作を行うことで、S3上のsnapshotからindexをrestoreします。
POST /_snapshot/<snapshotリポジトリ名>/<snapshot名>/_restore?wait_for_completion=true
{               
  "indices": "restoreするindex名をカンマ区切りで",
  "include_global_state": false
}

备考

spot.png

验证完成

只在索引时增加节点数量以在短时间内完成处理,并且在聚合时只使用少量节点来运营Elasticsearch,以降低成本的方法似乎变得可行。目前,我认为使用专用于索引的临时集群+ S3快照和恢复的方法对现有的聚合用ES集群影响较小,并且可以同时进行索引的备份是不错的选择。我们将继续进行验证以准备投入生产环境。

最后是宣传。今年,我也参加了Supership集团和在真实环境中犯错的人的圣诞日历。也请务必查看这个。

广告
将在 10 秒后关闭
bannerAds