見出し画像

計画的なメンテナンスで実現した Elastic Cloud 移行 - システムの安定性を最優先にした実践記録

こんにちは、PKSHA Workplace の AI ヘルプデスク開発チームに所属するソフトウエアエンジニアの徐鐘偉です。今回は、私が担当しているプロジェクトで使用している検索エンジン「Elasticsearch」についてお話ししたいと思います。

徐 鐘偉(PKSHA Workplace AI ヘルプデスク開発チーム ソフトウエアエンジニア)
大学院修了後、エンジニアとして複数の toC サービス開発に携わり、カーナビサービスやゴルフ仲間マッチングサービスの開発に従事。その後、2021 年 3 月に PKSHA Workplace に入社。「PKSHA AIヘルプデスク」の開発チームに参画し、現在はソフトウエアエンジニアとして開発業務を担当。業務効率化やユーザー体験向上を目指したプロダクト開発に取り組んでいる。

この半年間、Elasticsearch の移行作業を進めてきました。その詳細について共有させていただきますので、ご興味のある方はぜひご覧ください。


はじめに

「PKSHA AIヘルプデスク」とは

私が関わっているプロダクト「PKSHA AIヘルプデスク」は企業向けの社内問い合わせシステムで、Azure 上で展開されているサービスです。サーバーサイドの実装には高性能かつ効率的なプログラミング言語である Go が採用されています。Azure のクラウド環境と Go の組み合わせにより、柔軟でパフォーマンスに優れたシステムを実現しています。
「PKSHA AIヘルプデスク」の主なユースケースとして、社内での問い合わせ対応があります。問い合わせ対応は、「FAQ 型」「ドキュメント型」「有人対応チャット」に分かれています。別プロダクトである「PKSHA Chatbot」による「FAQ 型」の自動応答、社内ドキュメントを活用した「ドキュメント型」の回答、さらに必要に応じて有人対応を組み合わせることで、質問者からの問い合わせに柔軟に対応します。

▼「PKSHA AIヘルプデスク」の紹介記事はこちら

「PKSHA AIヘルプデスク」では、各段階で、次のようなメッセージのやり取りが行われます。

  • FAQ 型の自動応答メッセージ

  • ドキュメント型の回答メッセージ

  • 有人対応による回答メッセージ

これらの問い合わせメッセージが日々生成され、Elasticsearch にインデックスされています。Elasticsearch は社内ではすでに運用実績があり、検索・分析のパフォーマンス、柔軟性、スケーラビリティの点で優れており、問い合わせメッセージの運用にはいい選択です。

Elastic Cloudの移行を行なった経緯

これまで、「PKSHA AIヘルプデスク」では Elasticsearch のホスティングサービスとして Elastic Cloud を利用していました。

しかし、Elasticsearch を運用していたところ、アラートを通じて負荷が高いことがわかりました。各インデックスに対してシャード数が適正な値で設定されていないので、負荷分散が十分に行えませんでした。そこで Elastic Cloud のダッシュボードで確認したところ、CPU 使用率が高い状態でした。インスタンスを増やしたり、ゾーン冗長を試みたりしましたが、あまり効果がありませんでした。
インデックスのシャード数が 1 に設定されている場合、たとえインスタンスの数を増やしたとしても、インデックスを分散させることは不可能です。
上記の課題を踏まえ、インフラではすでに Azure を利用しているため、他のリソースと統一して管理を簡素化する目的で、Elastic Cloud から Elastic Cloud (Elasticsearch) - Azure Native ISV への移行を決定しました。移行とともに、負荷の課題の解消を目指しました。

Elastic Cloud 環境の移行プロセスの計画

技術的概要

  • Elasticsearch リソースの移行
      - 移行元:Elastic Cloud 7.17.9
      - 移行先:Elastic Cloud (Elasticsearch) - Azure Native ISV 8.12.1

データ移行方法の検討

  • Logstash を利用した無停止移行
    Logstash を活用することで、Elasticsearch のデータをリアルタイムに他のクラスターへ無停止で移行することが可能です。Logstash とは、オープンソースのサーバーサイドデータ処理パイプラインです。膨大な数のソースからデータを取り込み、変換して、お好みの格納庫(スタッシュ)に送信します。Logstash はデータをソースクラスターからストリームとして取得し、ターゲットクラスターへ転送します。この方法により、システムの稼働を維持しながらスムーズなデータ移行を実現します。 しかしながら、こちらのプランは取り下げました。理由は深夜に数時間の停止が許容される環境であるため、高度な移行手法は不要だからです。
    Logstash:ログの収集、解析、変換 | Elastic

  • スナップショットで実現するデータ移行
    スナップショット(Snapshot)は、Elasticsearch のインデックスやデータの状態を特定の時点で保存するためのバックアップのことです。スナップショットを取ることで、データの復旧や移行が可能になります。リストアとは、以前に取得したスナップショットからインデックスやデータを復元する作業のことです。
    Snapshot and restore | Elasticsearch Guide [8.17]

    スナップショットリポジトリ(Snapshot Repository)とは、スナップショットデータを保存する物理的または論理的なストレージのことです。スナップショットを作成または復元する前に、リポジトリを登録する必要があります。
    Register a snapshot repository | Elasticsearch Guide [8.16] | Elastic

    Elastic Cloud では以下の 2 種類を利用することができます。

    1. マネージドスナップショットリポジトリ
      Elastic Cloud が提供するデフォルトのリポジトリで、クラウド環境内で簡単にスナップショットの作成や復元が可能です。ただし、このリポジトリは同一リージョン内のデプロイメント間でしかスナップショットを復元できません。
      Work with snapshots | Elasticsearch Service Documentation | Elastic

    2. カスタムスナップショットリポジトリ
      Elastic Cloud で外部ストレージサービスを利用して設定するリポジトリです。これを使用することで、異なるリージョンやクラウドプロバイダー間でのデータ移行が可能になります。
      Snapshot and restore with custom repositories | Elasticsearch Service Documentation | Elastic

      今回のケースでは、異なるリージョン間でデータを移行する必要がありました。そのため、Elastic Cloud マネージドスナップショットリポジトリは利用せず、カスタムスナップショットリポジトリとして Azure Blob Storage を採用しました。Azure Blob Storage は、Microsoft Azure が提供するクラウド上の大容量ストレージサービスです。主に画像や動画、ログデータなどの非構造化データを保存するために利用され、スケーラブルでコスト効率の高いデータ管理が可能です。
      Azure Blob Storage | Microsoft Azure

スナップショットで実現するデータ移行全体図

データ移行の作業手順

  • go-elasticsearch を v8.12 にアップデート
    Elasticsearch を v7.17.9 から v8.12.1 に移行するため、go-elasticsearch も最新の 8.12 にアップデートします。Elastic Cloud のバージョンと go-elasticsearch のメジャーバージョンが一致しないと不具合が発生する可能性があるためです。これまでクエリは go-elasticsearch の esapi パッケージを使用し、JSON ベースのクエリで記述していましたが、go-elasticsearch v8.4.0 から Typed API がサポートされたため、セキュリティ面を考慮しながら段階的に JSON ベースのクエリから型安全な Typed Client へのリファクタを進めました。一気にリファクタするのはリスクがあるため、少しずつ対応を進め、最終的に go-elasticsearch v7.17.1 を完全に廃止することを目指すことにしました。
    https://github.com/elastic/go-elasticsearch/releases/tag/v8.4.0-alpha.1
    Typed API | Elasticsearch Go Client [master] | Elastic

  • インデックステンプレートの作成、およびインデックスのマッピング、アナライザ、Index Lifecycle Management(ILM)の適用
    インデックステンプレートとは、Elasticsearch で新しいインデックスを作成する際に、自動的に適用される設定やマッピングのテンプレートです。これにより、インデックスの作成時に必要な設定を一貫して適用でき、複数のインデックスに共通の設定を簡単に管理できます。
    Index templates | Elasticsearch Guide [8.16] | Elastic

    マッピングとは、Elasticsearch のインデックスに格納されるデータのフィールド(項目)の構造やデータ型を定義する設定です。これにより、データの検索や分析が効率的に行えるようになります。例えば、フィールドが「文字列」や「数値」「日付」などのどの型であるかを指定することができます。
    Mapping | Elasticsearch Guide [8.16] | Elastic

    アナライザとは、テキストデータをインデックスに格納する前に処理する方法です。アナライザは、文字列を「トークン」と呼ばれる単位に分割し、必要に応じて小文字化や不要な文字の削除を行います。
    analyzer | Elasticsearch Guide [8.16] | Elastic

    ILM とは、インデックスの作成から削除までのライフサイクルを自動的に管理する機能です。ILM を使うことで、インデックスのサイズやドキュメント数や経過時間に基づいて、データの移動や削除、アーカイブを自動化できます。これにより、効率的なデータ管理とストレージの最適化が可能になります。
    Elasticsearchでインデックスライフサイクル管理を使用してHot-Warm-Coldアーキテクチャーを実装

  • 移行元から移行先にデータをリストア
    このステップでは、移行前のインデックスをそのまま移動します。しかし、移動したインデックスは新しい環境で設定されたマッピングやアナライザに適応していないため、単純なデータ移行作業となります。そのため、次にリインデックスを行い、マッピングとアナライザに適応したインデックスを作成します。

  • 新しいマッピング、アナライザ、ILM、インデックステンプレートに対応させるリインデックス
    リインデックスとは、既存のインデックスから新しいインデックスにデータをコピー(または移行)する操作です。新しいインデックスにはマッピング、アナライザー、ILM、およびインデックステンプレートが設定されているため、ドキュメントはアナライザーを通してから新しいインデックスにインデックス化されます。
    Reindex API | Elasticsearch Guide [8.16] | Elastic

  • リインデックス後のインデックスにエイリアスを適用
    エイリアスとは、実際のインデックスに対して付ける仮想的な名前で、インデックスの操作を柔軟に行うための便利な機能です。エイリアスを使うことで、インデックスを直接操作することなく、間接的にアクセスしたり、管理したりすることができます。リインデックスされた新しいインデックスに対して、エイリアスを付与します。
    Aliases | Elasticsearch Guide [8.16] | Elastic

  • アプリケーションの接続先を移行元から移行先に切替
    こちらは、Terraform を使用してアプリケーションの環境変数を既存のElastics Cloud のエンドポイントから Elastic Cloud (Elasticsearch) - Azure Native ISV のエンドポイントに切り替え、Elastic Cloud の接続先を変更したアプリケーションをリリースする作業でした。

  • 移行後の動作確認
    移行後の動作確認を行います。基本動作確認に加えて、エラーが発生していないか、アラートが飛んでくるかどうかも注意します。

  • 移行用スナップショットリポジトリとスナップショット削除
    実際の運用データが保存されているため、移行作業が完了後、削除作業を行います。

  • 既存の Elastic Cloud Deployment の削除
    顧客から異常の報告がないことを確認した後、既存の Elastic Cloud 環境のデプロイメントを削除し、Elastic Cloud (Elasticsearch) - Azure Native ISV のデプロイメントに切り替えます。

データ移行の実施

  1. go-elasticsearch のアップデート
    これはアプリケーション開発における重要な作業です。大規模なリファクタであり、重要な機能に直結するため、QA チームと連携しながら段階的にリリースを進めました。これを踏まえ、go-elasticsearch のアップデートとコードの修正を実施し無事に完了しました。

  2. ローカル環境の準備
    ローカル開発環境では、Docker コンテナ上で移行先バージョンを稼働させ、既存の Elasticsearch 7.17.9 と共存する形で移行環境を構築しました。普段のローカル開発環境を Elasticsearch 8.13.2 に接続し、異常があればローカル開発の段階で気づくことを目指しました。

  3. 移行手順の検証
    移行に必要な各手順について、以下の項目を準備し、検証を行いました。ローカル環境で十分な検証作業を行い、仕組みを理解しました。また、開発環境での検証も行いました。

    • スナップショットリポジトリ用の Azure Blob Storage の準備

    • 各 Elasticsearch 環境でのスナップショットリポジトリ設定

    • リストア API 検証

    • リインデックス API 検証

    • ILM API 検証

    • エイリアス API 検証

    • Rollover 検証

  4. ペアワークによる手順書の作成
    移行作業のミスを防ぐため、一人で進めるのではなく、週 2 回のペアワークを行い、手順の精度を高めます。

    • 検証した移行作業をスクリプト化
      上記のリストア API やリインデックスなどを一つ一つ手動で実行するとミスが発生する可能性があるため、スクリプトにまとめて一括で実行できるようにしました。また、移行用のスクリプトを実行し、ローカルと Dev 環境の Elasticsearch 7.17.9 からローカルと Dev 環境の Elasticsearch 8.13.2 への移行作業を複数回行いました。

    • 実際の移行手順書作成
      手順書の本来の目的は、移行作業の際に深く考えずに手順書通りに進められるようにすることです。そのため、綿密な手順書を作成しました。もちろん、手順書は一度で完成するわけではありません。実際にローカルでの検証作業やリハーサルを重ね、気づいた課題や網羅できていなかった点をどんどん追加して、最終的にまとまった形にしました。

  5. リハーサル
    以下の環境で複数回リハーサルを実施し、手順に漏れがないかの確認とデータ移行が想定通り完了することを確認していきます。安心感も高めています。ローカル環境と開発環境で複数回リハーサルを実施した結果、いくつかの重要な問題に気付き、それに対する対策を講じました。十分なリハーサルを行わない場合、本番移行時に問題が発覚し、移行の失敗につながる可能性があります。インフラ移行では、できる限り自らリハーサルの機会を設けていくことが重要です。 今回、ローカル環境と開発環境で複数回、ステージング環境で 2 回のリハーサルを実施しました。

  6. 移行日の決定
    実際の移行日は、ローカル環境と Dev 環境での確認が完全に問題なくなった時点で決定しました。また、顧客への事前通知が必要というルールがあるため、移行日は少なくとも 3 週間後に設定する必要がありました。

  7. 移行リハーサル用と移行用の PR を作成
    サービスを完全に停止するのではなく、顧客からのリクエストに対して「メンテナンス中」とのメッセージを返すことにしました。万が一対応しきれない場合には、メンテナンス中に Elasticsearch へのインデックスが発生し、移行前後でデータ数が一致しないという不具合が生じる可能性があります。顧客からのリクエストは多岐にわたるユースケースから発生するため、慎重に計画し実施と確認を行いました。

  8. ステージング環境での移行リハーサル
    ステージング環境では手順書通りに実施しました。作成した手順書は、本番環境での移行時に問題がないかを確認するためのものです。また、ステージングリハーサルの完了はステージング移行の完了を意味し、その後 QA チームと共にメッセージ機能に異常がないことを確認しました。

  9. 本番環境の移行実施
    実施予定時刻に関連するエンジニアたちを集め、顧客にメンテナンスメールを配信して、画面共有しながら手順書通りに進めました。リハーサルを通して準備していたので、かなり落ち着いて進めることができました。無事に完了したら、メンテナンス解除メールを配信し、解散という流れでした。

  10. 翌日の確認
    関連しそうなエラーのアラートに注意を払いましたが、異常はありませんでした。

パフォーマンス向上と負荷分散の最適化

アナライザの設定での工夫

今回の移行を機に、既存のアナライザが存在しないことによる課題を解消するため、事前にアナライザの定義を検討しました。 アナライザの構成要素である CharacterFilter、Tokenizer、Filter について、それぞれ以下の定義を行いました。

Character Filter は、Elasticsearch におけるアナライザの一部で、テキストをトークン化する前に適用される処理ステップです。このフィルターは、文字列の内容を変更したり、不要な文字を削除したり、特定の文字を置換したりする役割を担います。
Character filters reference | Elasticsearch Guide [8.16] | Elastic

Tokenizer は、Elasticsearch でテキストをインデックス化する際に、テキストを単語やフレーズといった小さな単位(トークン)に分割する役割を担うコンポーネントです。トークナイザーは、アナライザの一部として機能し、文字列を処理して検索やインデックス作成を効率的に行えるようにします。
Tokenizer reference | Elasticsearch Guide [8.16] | Elastic

Token Filter は、Elasticsearch において、トークン化された単語やフレーズ(トークン)をさらに加工・変換するための処理ステップです。トークナイザーが生成したトークンに対して適用され、検索やインデックス作成の精度を向上させる役割を担います。
Token filter reference | Elasticsearch Guide [8.16] | Elastic

以下は、Elasticsearch の Character Filter、Tokenizer、Token Filter のデータ処理フローを表現しています。

以下は、具体的なアナライザを通じて Elasticsearch にインデックスされる流れを示したものです。最終的に「今日」と「天気」と「良い」が検索対象としてインデックスされます。

CharacterFilter の工夫点

Elasticsearch に保存するチャット内容はリッチテキストで作成された HTML コンテンツであるため、その中に含まれる p タグなども以前は動的にインデックスされていましたが、これは性能面で非常に無駄がありました。そのため、今回は html_strip を導入しました。チャット内容をインデックスする前に HTML タグを除去し、純粋な内容だけを分割してインデックスさせました。

また、顧客は Windows をよく利用しており、会話履歴には Windows のファイルパスが頻繁に含まれています。以前、顧客はファイルパスを含むチケットを検索する際に、よくバックスラッシュ一つで検索していました。しかし、Elasticsearch では単一のバックスラッシュが無視されてしまいます。そのため、独自の CharacterFilter を定義し、バックスラッシュを Elasticsearch のエンジンに通す前に「backslash」という文字列に変換しました。実際には、すべての「\」を「backslash」としてインデックス化していますが、検索時には元のバックスラッシュでファイルパスを検索できるようになっています。実際にカスタマイズした CharacterFilter は以下の通りです。

"char_filter": {
    "backslash_filter": {
      "type": "mapping",
      "mappings": [
          """\\=>-backslash-"""
	      ]
      }
	}

導入した Token Filter

  • lowercase: すべての文字を小文字に変換することで、検索時の大文字・小文字の違いをなくし、一貫した検索結果を得られるようにします。
    例:「PKSHAWorkplace」 → 「pkshaworkplace」

  • katakana_stemmer: カタカナ語の語尾を正規化し、同義語を扱いやすくするために使用しています。これにより、カタカナの語尾変化に対応し、検索の精度が向上します。
    例:「パークシャテクノロジー、」→ 「パークシャテクノロジ」

  • kuromoji_number: 日本語の数字を正規化し、一貫した数値検索を可能にするためのフィルターです。日本語特有の数字表記にも対応しています。 例:「二千四百」→ 「2400」

  • cjk_width: 全角と半角の違いを統一し、CJK(日本語・中国語・韓国語)文字の幅を正規化することで、表記の違いによる検索ミスを減らしています。
    例:「パ‐クシャワークプレイス」 → 「パークシャワークプレイス」

Tokenizer 選定

Tokenizer の選定において、以下のオプションを検討しました。

  • kuromoji tokenizer

  • sudachi tokenizer

  • standard tokenizer

Elastic Cloud (Elasticsearch) - Azure Native ISV では sudachi tokenizer の導入については、手動でプラグインをアップロードする必要があります。契約プランによっては標準プラグイン以外を使用できないこと、サポートに問い合わせるなどして有効にする必要もあるようです。ただ、現時点での必要性がないことから、今回は選択しませんでした。

代わりに、kuromoji tokenizer が標準プラグインとして導入できるのでこちらを検討しました。Elastic Cloud (Elasticsearch) - Azure Native ISV では、 analysis-kuromoji が標準で搭載されており、下のスクリーンショットのようにチェックを入れるだけで kuromoji tokenizer を使用することができます。

kuromoji tokenizer を導入する場合、次のようなトークン化のルールに従う必要があります。

例: 「出張しました」 → 「出張」「し」「まし」「た」
この場合、「出張」は一つのトークンとなり、「出」で検索しても該当する文章が検索結果に表示されなくなります。一方、既存の standard tokenizer を使用すると、「出張しました」は「出」「張」「し」「ま」「し」「た」にトークン化されます。そのため、「出張」や「出」や「張」で検索しても該当する文章がヒットします。

既存の環境が一つの単語や漢字で検索を行うことが可能な仕様であるため、上記の検証を行った後、最終的に standard tokenizer を使用することにしました。

シャード数の決定

  • シャード: Elasticsearch でデータを効率的に保存・検索するために、インデックスを分割した単位。シャードを複数のノードに分散することで、インデックスやクエリの処理能力を向上させます。

  • プライマリシャード: インデックス内のデータを最初に保存する主要なシャード。各ドキュメントは必ず 1 つのプライマリシャードに属します。

  • レプリカシャード: プライマリシャードのコピーで、データの冗長性を確保し、ハードウェア障害に備えるとともに、検索やドキュメント取得の処理能力を高めます。

プライマリシャードの数はインデックス作成時に固定されますが、レプリカシャードの数は後から変更可能です。
Elasticsearchクラスターのシャード数はいくつに設定すべきか?

シャード数は以下の通りです。
   - プライマリシャード: 3
   - レプリカシャード: 1
Elastic Cloud のインスタンスを 3 ゾーン構成にし、各ゾーンにプライマリシャードを配置して耐障害性を向上させます。仮にシャード数を 4 以上に設定すると、過剰なシャード数がパフォーマンスに悪影響を及ぼす可能性があるため、特定のインデックスに対してプライマリシャード数を 3 に設定し、各プライマリシャードが各インスタンスに 1 つずつ配置されるようにしました。

インデックスのポリシー設定での工夫

Elasticsearch のインデックスライフサイクル管理(ILM)ポリシーは、インデックスのライフサイクルを管理するための設定です。ILM ポリシーは、以下の4つのフェーズに分かれています

  • Hot フェーズ: データが最も活発に使用される段階で、検索とインデックス作成の性能を最大化します。

  • Warm フェーズ: データの更新頻度が減少した段階で、コスト効率を重視します。

  • Cold フェーズ: ほとんどアクセスされないが保持する必要があるデータの段階で、ストレージコストを最小化します。

  • Delete フェーズ: もはや必要のないデータを削除します。

公式には以下のように記載されています。

すべての Hot-Warm-Cold アーキテクチャーに適合する万能なものはありませんが、一般的に Hot ノードには、より多くの CPU リソースとより高速な IO が必要になります。Warm および Cold ノードは一般的に、ノードごとのディスク容量がより多く必要になりますが、より少ない CPU で対応でき、より遅い IO でも許容されます。

Elasticsearchでインデックスライフサイクル管理を使用して
Hot-Warm-Coldアーキテクチャーを実装
」より

現時点では、すべてのドキュメントが検索対象となるべきなので、検索レイテンシは許容できません。そのため、Hot フェーズのみを使用しています。すべてのノードは Hot ノードになっています。

  • Rollover ポリシーの導入
    インデックスの ILM ポリシーで、Hot フェーズに Rollover ポリシーを設定しました。Hot フェーズに対して、インデックスが無制限に膨張しないようにするため、Rollover ポリシーを導入します。Rollover はインデックスのサイズやドキュメント数が一定のしきい値を超えた際に、自動的に新しいインデックスを作成して古いインデックスを「ロールオーバー」する機能です。このプロセスは、インデックスの運用を簡単にし、パフォーマンスや管理の負担を軽減するために役立ちます。
    Rollover API | Elasticsearch Guide [8.16] | Elastic

  • Rollover の閾値の選定
    Rollover の閾値は、max_docs と max_size の 2 つの条件で設定できます。いずれかの条件が満たされるとインデックスがスプリットされ、00001 から 000002 に移行します。この条件設定の選定例は少ないため、最適な設定を探索することにしました。
    Rollover | Elasticsearch Guide [8.16] | Elastic

    閾値を決定するは 2 点あります。
       - 1 プライマリシャードあたり 2 億ドキュメント程度
       - 1 プライマリシャードあたり 10GB~50GB 程度
    上記基準を元に現在のデータ量と増加するデータ量を考慮した比例計算を行い、Rollover の閾値を決定しました。

CI/CD を活用した Elasticsearch のマッピング管理

インデックスのマッピング情報は JSON ファイルで一元管理しています。新たにプロパティを追加する場合、Elastic Cloud 上で手動操作を行うとリスクを伴うため、社内で既に運用されている手法を採用しました。 具体的には、CI/CD 環境を利用し、リリース時に実際のマッピング情報と GitHub リポジトリで管理している JSON ファイルを比較します。JSON ファイルに新たなプロパティが追加されている場合、そのプロパティを該当するインデックスに適用します。

まとめと感想

今回の移行計画では、Elastic Cloud から Elastic Cloud (Elasticsearch) - Azure Native ISV への移行を行い、シャード設定の見直しやマッピング、アナライザ、Rollover ポリシーの適用を通じて、検索・分析基盤の強化を図りました。リーダーのアドバイスのもと、ペアワーク体制を取りましたが、お互いに情報を共有し助け合う中で、移行手順の精度を高めリスクを最大限に抑えることの重要性を改めて実感しました。多くのリハーサルを重ねたことが、手順の精度をさらに向上させ、移行作業を無事に完了することに繋がったと感じています。

おわりに

Elasticsearch を活用した検索エンジンには、まだ多くの可能性が広がっています。私たちは、今回のような取り組みを通じて事業の成長を支えながら、自身のスキルやキャリアを磨き続けたいと考えています。もし、Elasticsearch 等の活用野中で新しい挑戦をしたいという方がいれば、ぜひ私たちと一緒に取り組みましょう。ご興味をお持ちの方は、ぜひお気軽にご連絡ください。新しい仲間と出会えることを楽しみにしています!

―INFORMATION―
▼ 中途採用:ソフトウエアエンジニアの募集要項はこちら

新卒採用:ソフトウエアエンジニア 本選考

▼ PKSHA 採用サイト

▼ Wantedly はこちら:カジュアル面談も受付中です!