Elasticsearch を使ってみた!

お仕事で Elasticsearch という単語を何度も聞くようになったのでとりあえずどんなものか知っておこうかと。

Elasticsearch とは

What is Elasticsearch? | 公式ドキュメント

公式サイトでは次の一文で Elasticsearch とは何かを説明しています。

Elasticsearch is the distributed search and analytics engine at the heart of the Elastic Stack.(Elasticsearchとは、Elastic Stack の中心的な検索と分析の分散型のエンジンです)

Elastic Stack とは Elasticsearch を含めた複数の製品をまとめた総称のことで、その中で中心的な立ち位置の製品であると書かれています。要は様々な種類のデータを貯めて、検索、分析ができる製品と認識しておけば間違いはないかと思います。

用途の例がいくつか記載されていましたのでこちらにも載せておきます。

  • アプリやウェブサイト上に検索機能を追加する
  • ログやメトリクス、セキュリティイベントを保存し解析する
  • リアルタイムに変化するデータを機械学習に使用する
  • 地理情報システムとして空間情報を管理する
  • バイオインフォマティック研究のツールとして遺伝データの保存及び処理に使う

インストールと起動

インストールと起動は簡単です。今回はVirtualBox上にCentos7を立ち上げてそこにインストールしました。インストールするためにVagrant、Ansibleを使用しましたのでそちらの中身を以下に載せておきます。これらはElasticsearchのインストールに必須なわけではありません。ただ、色々といじくり回した挙げ句最初からやり直したいと思うことがしばしばあるので、再構築をすぐできるようにしてみました。

f:id:bau1537:20200622101636p:plain

VagrantファイルではAnsibleのコントロールノードとホストノードをそれぞれ定義しておき、 vagrant up で2つのインスタンスが起動するようにしました。

Vagrant.configure("2") do |config|
  config.vm.box = "centos/7"

  // ansible を実行するインスタンス
  config.vm.define "ansible-controll-node" do |controll|
    controll.vm.network "private_network", ip: "192.168.50.1", virtualbox__intnet: true
  end

  // elasticsearch をインストールするインスタンス
  config.vm.define "ansible-host-node" do |host|
    host.vm.network "private_network", ip: "192.168.50.2", virtualbox__intnet: true
    // elasticsearch のビジュアライズツールである kibana にアクセスするためにポートフォワーディングを設定します。
    host.vm.network :forwarded_port, guest: 5601, host: 5601
    // デフォルトの構成ではメモリが512MBなので、4GB程度に増やしてます。
    host.vm.provider "virtualbox" do |v|
      v.memory = 4096
    end
  end

end

ホストノードが保持しているAnsibleの構成ファイルはロールとして定義し、後で色々とカスタムしやすくしておきました。Ansibleを再実行するたびにrpmファイルをダウンロードすると時間がかかるので、rpmファイル自体はローカルにおいといてホストにコピーする構成にしてみました。

[vagrant@localhost role_getting_started]$ tree
.
|-- main.yml
`-- roles
    `-- elk
        |-- elasticsearch
        |   |-- files
        |   |   `-- elasticsearch.rpm
        |   `-- tasks
        |       `-- main.yml
        `-- kibana
            |-- files
            |   `-- kibana.rpm
            `-- tasks
                `-- main.yml

8 directories, 5 files
- name: copy elasticsearch rpm file
  copy:
    src: elasticsearch.rpm
    dest: /home/vagrant
- name: install elasticsearch
  yum:
    name: elasticsearch.rpm
    state: present
- name: start elasticsearch service
  service:
    name: elasticsearch
    state: started
    enabled: yes

Elasticsearch の REST API を叩くために色々と便利な Kibana というツールも入れておきます。ちなみに、Kibana も Elastic Stack の一部の製品ですので Elasticsearch との相性もバッチリです。

- name: copy kibana rpm
  copy:
    src: kibana.rpm
    dest: /home/vagrant
- name: install kibana
  yum:
    name: kibana.rpm
    state: present
- name: start kibana service
  service:
    name: kibana
    state: started
    enabled: yes

デモデータを投入し検索してみる

Kibana にアクセスすると最初の画面で「Add sample data」というボタンがあります。このボタンを押すと、デモデータを投入できる画面に飛ばされるので、そこからデータを投入できます。今回は「Sample web logs」を投入しました。おそらくですが、サーバーへのアクセスログみたいな感じかなと思います。

デモデータを投入した後、検索をしてみましょう。検索には一般的に REST API を使用するようなので今回はその方法で検索します。検索に使用できるDSLはQueryとSQLがありますが、Queryでやってみます。

REST API なのでHTTP通信できるクライアントソフトがあれば何でも大丈夫なのですが、KibanaのConsole画面を使えばより直感的にElasticsearchのAPIを叩くことができるのでおすすめです。Console画面はKibanaの最初の画面のメニューからアクセスできます。

まずは検索条件無しで検索してみます。検索は基本、どのデータの集合に対して(インデックス)、どのような条件で(QueryDSL)検索するかを指定します。インデックスはURLの一部で指定し、検索条件はボディにJSONとして詰めて送ります。(他にもいろいろやり方はあるようです。)

f:id:bau1537:20200622101656p:plain

検索のレスポンスには色々と情報が含まれています。以下のリンク先にレスポンス内容の各項目について詳細な説明があります。

以下はその一部です。

  • hits - 検索に一致したドキュメントとメタデータを含むオブジェクト(Elasticsearchでは格納するデータをドキュメントと呼ばれる単位で管理します。)
    • total.value - 検索条件に一致したドキュメント数
    • hits - 検索条件に一致したドキュメントの配列
      • _id - ドキュメントのID。ID値はインデックス内で一意
      • _source - ドキュメント本体

次はドキュメントの持っている一部のフィールドをもとにした検索もやってみます。以下のリクエストは(おそらく)Windows OS からのアクセスのドキュメントを検索しています。

GET /kibana_sample_data_logs/_search
{
  "query": {
    "match": {
      "machine.os": "win"
    }
  }
}

検索条件なしのときはレスポンスのドキュメント数が 10000 でしたが、8512 に変わったのでうまく行っているようです。レスポンスの内容を見ても、該当するフィールドが「win 8」といったドキュメントのみが返却されます。

検索条件なしのときは match_all 句を指定していましたが、検索条件ありのときは match 句を指定しました。 match 句は全文クエリと言われるカテゴリに属しています。全文クエリは Elasticsearch が分析したテキストを検索することができ、 match 句は指定されたテキストや数値などが一致するドキュメントを返します。上記の検索であれば machine.os フィールドに win テキストが含まれているドキュメントを返します。

次は検索についてもう少し詳しくまとめていきたいと思います。

使用したアイコン

Icons made by Freepik from www.flaticon.com