フラミナル

考え方や調べたことを書き殴ります。IT技術系記事多め

【新規ツール探し】全文検索エンジンの ElasticSearch と Kibana を触ってみた

情報

何ができるもの?

https://www.elastic.co/guide/index.html

  • データを保存し、保存したデータを高速で検索できる検索、分析エンジン
    • 構造化テキスト、非構造化テキスト、数値データ、地理空間データなど、Elasticsearchは高速検索をサポートするために効率的にデータを保存しインデックスを作成
    • 分散型なのでデータが増えても性能劣化しづらい
  • Elastic Stack の一コンポーネント(Elasticsearch、Kibana、Beats、Logstashなどで構成される)

高速な検索のために

キャッシュについて

Elasticsearchのキャッシングに関する詳細:クエリスピードを高速化できるキャッシュ方法を1つずつ順に解説 | Elastic Blog が詳しい

  • ディスクキャッシュ(OSの機能): データ量に関係なくキャッシュ
  • クエリキャッシュ: 異なるクエリ間で再利用されるデータをキャッシュ
  • シャードレベルリクエストのキャッシュ: 同様のクエリが使用されたときにデータをキャッシュ

データ量について

  • ずっと増えていく

データの削除について

結果整合性、強整合性

デフォルトでは、Elasticsearchは1秒ごとに定期的にインデックスをリフレッシュしますが、過去30秒間に1回以上検索リクエストを受け取ったインデックスにのみ適用されます。このため、Elasticsearchはニア・リアルタイム検索が可能です。ドキュメントの変更はすぐに検索に反映されませんが、この時間枠内であれば表示されるようになります。https://www.elastic.co/guide/en/elasticsearch/reference/current/near-real-time.html

このことからも 結果整合性 であることがわかる。

データはどう持ってる?複製される?

  • シャードというところに分散して保存できる
  • この数に応じて処理の並列数が決まる

https://www.slideshare.net/snuffkin/elasticsearch-as-a-distributed-system

他のツールとの違いについて

  • BigQuery も大量にデータを集めて分析、解析していくもの。ただしバージョニングという考えはなく、解析が基本的な使い方であるため特定の商品の情報を取ってくるみたいな使い方ではない

利用シーン

  • 全文検索エンジンとして利用したい場合
  • 非構造化データ、正規化されていないデータを集めて分析したい場合

登場背景

ELasticの歴史は、2000年にShay Banonが個人開発を通じて検索基盤(全文検索)に関するオープンソースを公開したこと始まる。開発者のBanonの妻が料理学校に通っており、膨大なレシピを検索するために、個人開発を進めたのがきっかけであった。このオープンソース開発を通じて、Elasticsearchがリリースされた。

https://the-shashi.com/tse/tech-elastic/

所感

  • 全文検索エンジンとしては非常に便利
  • ただ付け焼き刃で使うのはとても危ない印象を受けた。大量にデータを保管したり、mapping を後で修正できない(追加はできる)ことからもある程度慣れてからじゃないときちんと運用がし辛い印象。
  • 息の長いサービスで、商用版もあるが故にできることが非常に多いためキャッチアップも難しい。独自の技術要素や概念が多い。

使い方

GitHub にあるチュートリアルをやっていく。

https://github.com/elastic/elasticsearch

インストール

❯ docker network create elastic
❯ docker pull docker.elastic.co/elasticsearch/elasticsearch:8.5.2
❯ docker run --name elasticsearch --net elastic -p 9200:9200 -p 9300:9300 -e "discovery.type=single-node" -t docker.elastic.co/elasticsearch/elasticsearch:8.5.2

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
✅ Elasticsearch security features have been automatically configured!
✅ Authentication is enabled and cluster connections are encrypted.

ℹ️  Password for the elastic user (reset with `bin/elasticsearch-reset-password -u elastic`):
  Q63OIuVI4l7Oc*us8CrW

ℹ️  HTTP CA certificate SHA-256 fingerprint:
  c748f42110a0b395de66ac466969c7eacaf635f11b993642d8832c96e818818c

ℹ️  Configure Kibana to use this cluster:
• Run Kibana and click the configuration link in the terminal when Kibana starts.
• Copy the following enrollment token and paste it into Kibana in your browser (valid for the next 30 minutes):
  eyJ2ZXIiOiI4LjUuMiIsImFkciI6WyIxNzIuMTguMC4yOjkyMDAiXSwiZmdyIjoiYzc0OGY0MjExMGEwYjM5NWRlNjZhYzQ2Njk2OWM3ZWFjYWY2MzVmMTFiOTkzNjQyZDg4MzJjOTZlODE4ODE4YyIsImtleSI6IndRM0szNFFCU1o1YzVGZDFSTk5MOm1GREZPd2JkVEVxaW5rb3c2SHFrS0EifQ==

ℹ️ Configure other nodes to join this cluster:
• Copy the following enrollment token and start new Elasticsearch nodes with `bin/elasticsearch --enrollment-token <token>` (valid for the next 30 minutes):
  eyJ2ZXIiOiI4LjUuMiIsImFkciI6WyIxNzIuMTguMC4yOjkyMDAiXSwiZmdyIjoiYzc0OGY0MjExMGEwYjM5NWRlNjZhYzQ2Njk2OWM3ZWFjYWY2MzVmMTFiOTkzNjQyZDg4MzJjOTZlODE4ODE4YyIsImtleSI6InZ3M0szNFFCU1o1YzVGZDFSTk5KOjFhcUROQzVFVDlTRHRSWENnMzVkbmcifQ==

  If you're running in Docker, copy the enrollment token and run:
  `docker run -e "ENROLLMENT_TOKEN=<token>" docker.elastic.co/elasticsearch/elasticsearch:8.5.2`
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

可視化ツールの kibana も入れておく

docker pull docker.elastic.co/kibana/kibana:8.5.2
docker run --name kibana --net elastic -p 5601:5601 docker.elastic.co/kibana/kibana:8.5.2

...

i Kibana has not been configured.

Go to http://0.0.0.0:5601/?code=524589 to get started.

さっきのトークンを貼り付けて設定してもらう。

ユーザ名「elastic」でパスワードがさっき表示された「Q63OIuVI4l7Oc*us8CrW」。

色々できそうなトップページが出てくる。

ここからデータを書き込んでみる。チュートリアルによると書き込みにはこれらが紹介されていた。シンプルにやるなら curl だが、SDKもあるらしい。

まずは Kibana console を使ってみる。management → dev_tools

これを送ってみる。

POST /customer/_doc/1
{
  "firstname": "Jennifer",
  "lastname": "Walters"
}

取得する。

これをみる限り REST をベースにした階層型にデータを保存しているぽい。

POST に戻して何度か実行したら _versionresult だけが更新された。つまり同じパスのデータを上書きし世代を持っている模様。

bulk insert はこれ。1 API リクエストで捌ける。

PUT customer/_bulk
{ "create": { } }
{ "firstname": "Monica","lastname":"Rambeau"}
{ "create": { } }
{ "firstname": "Carol","lastname":"Danvers"}
{ "create": { } }
{ "firstname": "Wanda","lastname":"Maximoff"}
{ "create": { } }
{ "firstname": "Jennifer","lastname":"Takeda"}

検索

Jennifer に一致するユーザが2人分出てくる。

GET customer/_search
{
  "query" : {
    "match" : { "firstname": "Jennifer" }
  }
}

Data Views を作成し、Analytics → Discover にいくと、Data Views に紐づくドキュメントの情報が見れる。