Taste of Tech Topics

Acroquest Technology株式会社のエンジニアが書く技術ブログ

Karateに性能試験とUI試験を任せてみる

皆さんこんにちは、QA部門のカヤ(@kareyama_r)です。

この記事はソフトウェアテスト Advent Calendar 2020の16日目です。

つい先日、ソフトウェアテスト自動化カンファレンス2020が開催され、テスト自動化に関する様々な取り組みやフレームワークが紹介されていましたね!

私のイチオシのフレームワークは、去年・一昨年と同カンファレンスで取り上げられたKarateですが、今年は話題に上がっていなかったので取り上げたいと思います。

最初はAPI試験用のフレームワークとして発表されたKarateですが、最近は負荷試験やUI試験自動化までカバーするようになっています。

今回はこれらの機能を一気に試してみよう!ということで、アプリに負荷をかけながら、画面のロード時間を計測するという内容でKarateを使ってみました。

対象アプリとしてElastic Stackを使用します。

DBとなるElasticsearch・BIツールのKibanaを立ち上げて、Elasticsearchに負荷をかけつつKibanaへのレスポンスの影響を確認します。

以下が構成イメージです。 f:id:acro-engineer:20201211015421p:plain

続きを読む

特徴量エンジニアリングのライブラリ xfeat を使ってみて便利だったこと

こんにちは。機械学習エンジニアをしている古賀です。
最近は愉快な上司@tereka114 のもと、精度の上がらないモデルに四苦八苦しています。

そんな私が普段データ分析をする際に難しいことの一つとして、特徴量エンジニアリングがあります。
特徴量エンジニアリングとは、元のデータに新たな特徴量を追加することでモデルの精度を向上させるプロセスのことです。
この結果によってモデルの精度が大きく変わりますが、正しく実行するにはデータへの深い理解やデータ分析力が必要になります。

私もあまり得意ではないのですが、これを簡単にする xfeat という便利なライブラリがあると上司が教えてくれたので、実際に使ってみて便利だったことをまとめました。

※本記事は、Pythonその3 Advent Calendar 2020 の15日目の内容になります。

目次は以下です。

xfeat とは

PFNさんが公開している特徴量エンジニアリングと特徴量探索のためのライブラリです。
一般的にデータを分析するときには、データの型を調べたり、どんな特徴量が精度に効いているか実験したりと、骨が折れますよね。
xfeat を使うと、このようなデータ分析や機械学習の際のコードをより簡単に書くことができます。
github.com

準備

xfeat を実際に使うための環境の構築と、データの準備を行います。

実行環境

Google Colaboratory を使用しました。

xfeatライブラリのインストール

pip コマンドで簡単にインストールできます。

!pip install git+https://github.com/pfnet-research/xfeat.git

ライブラリのインポート

今回使用するライブラリをあらかじめインポートしておきます。

from sklearn.model_selection import KFold
from functools import partial

import optuna
from xfeat import SelectCategorical, LabelEncoder, Pipeline, ConcatCombination, SelectNumerical, \
    ArithmeticCombinations, TargetEncoder, aggregation, GBDTFeatureSelector, GBDTFeatureExplorer

データセット

今回はみなさんおなじみ、Kaggleで初心者向けに公開されているタイタニックデータを使用しました。

データのダウンロード

下の記事を参考にして "Kaggle APIをインストール" ~ "データのダウンロード" まで実施することで、Google Colaboratory上でタイタニックデータをダウンロードできます。
qiita.com

データの読み込み

train_df = pd.read_csv("/content/train.csv")
test_df = pd.read_csv("/content/test.csv")

データの概要

1912年4月15日、氷山に衝突して沈没したタイタニック号の、乗組員の生存状況データです。
全部で1309件あり、12個の説明変数と、1個の目的変数(Survived:生存状況)からなります。
データの説明は、Kaggleのタイタニックデータページに載っています。 www.kaggle.com

中身を確認すると、下のようになっています。

train_df.head(3)
PassengerId Survived Pclass Name Sex Age SibSp Parch Ticket Fare Cabin Embarked
0 1 0 3 Braund, Mr. Owen Harris male 22.0 1 0 A/5 21171 7.250000 None S
1 2 1 1 Cumings, Mrs. John Bradley (Florence Briggs Th... female 38.0 1 0 PC 17599 71.283302 C85 C
2 3 1 3 Heikkinen, Miss. Laina female 26.0 0 0 STON/O2. 3101282 7.925000 None S

xfeat を使ってみて便利だったこと

1. カテゴリカルデータ、数値データを中身を調べずに抽出可能

まずはデータセットから、カテゴリカルデータ、数値データをそれぞれ抽出してみます。
通常であれば、データの中身を確認し、型を調べてからでないと特定の型のデータだけを抽出することはできません。
しかし xfeat を使うとその手間が省け、データの中身を調べずに自動で抽出できます。

Ⅰ. カテゴリカルデータのみを抽出する

SelectCategorical().fit_transform(train_df).head(3)
Name Sex Ticket Cabin Embarked
0 Braund, Mr. Owen Harris male A/5 21171 None S
1 Cumings, Mrs. John Bradley (Florence Briggs Th... female PC 17599 C85 C
2 Heikkinen, Miss. Laina female STON/O2. 3101282 None S |

Ⅱ. 数値データのみを抽出する

SelectNumerical().fit_transform(train_df).head(3)
PassengerId Survived Pclass Age SibSp Parch Fare
0 1 0 3 22.0 1 0 7.250000
1 2 1 1 38.0 1 0 71.283302
2 3 1 3 26.0 0 0 7.925000

データの中身を調べず、たった一行で抽出できました。

2. Label Encoding が簡単にできる

特定のカテゴリカルデータに対し、Label Encodingを行う

Label Encoding とは、カテゴリカルデータの各カテゴリを整数に置き換える変換です。
ここでは、学習データからカテゴリカルデータを抽出し、それらに Label Encoding を行っています。

encoder = Pipeline([
    SelectCategorical(exclude_cols=["Name", "Ticket"]),
    LabelEncoder(output_suffix=""),
])

encoded_df = encoder.fit_transform(train_df)
encoded_df.head(3)
Sex Cabin Embarked
0 0 -1 0
1 1 0 1
2 1 -1 0

3. Target Encoding が簡単にできる

Target Encodingとは

目的変数を用いてカテゴリカルデータを数値に変換する方法のことです。
非常に有効な特徴量となる場合もありますが、目的変数を Leak させてしまう可能性もあるので、十分注意する必要があります。
※Leak とは、学習の過程では本来得られない目的変数の情報が見えてしまい、カンニング状態になってしまうことで、過学習してしまうことです。
リークを防ぐため自身のレコードの目的変数を使わないように変換をする必要があるため、少し実装が面倒なのですが、 xfeat を使うと下のようにシンプルに書くことができます。

fold = KFold(n_splits=5, shuffle=False)
encoder = TargetEncoder(
    input_cols=["Cabin"], 
    target_col="Survived",
    fold=fold,
    output_suffix="_re"
    )

encoded_df = encoder.fit_transform(train_df)
encoded_df[["Survived", "Cabin", "Cabin_re"]].head(3)
Survived Cabin Cabin_re
0 0 None 0.303867
1 1 C85 0.303867
2 1 None 0.303867

sklearn や Pandas だけを使うと結構長くなってしまう処理が、これだけ短くシンプルにかけるのはうれしいですね。

4. カテゴリカルデータの組み合わせが簡単にできる

Ⅰ. 二つのカテゴリカルデータを組み合わせる

ここでは、"Sex", "Cabin", "Embarked" のカテゴリカルデータのうち、二つを組み合わせた特徴量をそれぞれ作成しています。
もしも Pandas だけを使って作成しようとした場合、["Sex", "Cabin"], ["Cabin", "Embarked"], ["Embarked", "Sex"] の組み合わせごとに処理を書く必要があり、少し面倒です。
xfeat を使えば、特に処理を書かずに対象の変数と条件を指定するだけで生成してくれるので、実装がとても楽でした。

encoder = Pipeline([
    SelectCategorical(exclude_cols=["Ticket", "Name"]),

    # If there are many categorical columns,
    # users can specify the columns to be combined with `input_cols` kwargs.
    # `r=2` specifies the number of columns to combine the columns.
    ConcatCombination(
        # drop_origin=True, 
        output_suffix="_re", 
        r=2),
])

encoded_df = encoder.fit_transform(train_df)
encoded_df.head(3)
Sex Cabin Embarked SexCabin_re SexEmbarked_re CabinEmbarked_re
0 male None S male_NaN_ maleS _NaN_S
1 female C85 C femaleC85 femaleC C85C
2 female None S female_NaN_ femaleS _NaN_S

Ⅱ. 三つのカテゴリカルデータを組み合わせる

ここでは、"Sex", "Cabin", "Embarked" の三つのカテゴリカルデータを組み合わせた特徴量を作成しています。

encoder = Pipeline([
    SelectCategorical(exclude_cols=["Ticket", "Name"]),

    # If there are many categorical columns,
    # users can specify the columns to be combined with `input_cols` kwargs.
    # `r=2` specifies the number of columns to combine the columns.
    ConcatCombination(
        # drop_origin=True, 
        output_suffix="_re", 
        r=3),
])

encoded_df = encoder.fit_transform(train_df)
encoded_df.head(3)
Sex Cabin Embarked SexCabinEmbarked_re
0 male None S male_NaN_S
1 female C85 C femaleC85C
2 female None S female_NaN_S

5. 数値データの加算が簡単にできる

兄弟/配偶者、両親/子供の数を加算した特徴量を作成する

カテゴリカルデータと同様、数値データの組み合わせ(ここでは加算)も簡単に書くことができます。

# 2-order Arithmetic combinations.
encoder = Pipeline(
    [
        SelectNumerical(),
        ArithmeticCombinations(
            # 兄弟/配偶者、両親/子供の数を加算した特徴量を作成する
            input_cols=["SibSp", "Parch"], 
            drop_origin=True, 
            operator="+", 
            r=2,
        ),
    ]
)

encoded_df = encoder.fit_transform(train_df)

元のデータを確認しておきます。

train_df[["SibSp", "Parch"]].head(3)
SibSp Parch
0 1 0
1 1 0
2 0 0

変換後の結果は下になります。

encoded_df.head(3)
SibSpParch_combi
0 1
1 1
2 0

元データを加算した特徴量が作成されていることが確認できました。

6. Aggregation が簡単にできる

性別ごとに、年齢、Pclass の平均、最大を集計した特徴量を作成する

タイトルのような特徴量を作成しようとすると、Pandas を用いると、下のように長くて少々複雑なコードになってしまいます。

from copy import deepcopy
aggregated_df = deepcopy(train_df)
 
# 性別ごとの年齢の平均値を特徴量に追加
sex_mean_df = train_df.groupby('Sex')['Age'].mean()
aggregated_df.loc[aggregated_df['Sex'] == 'female', 'agg_mean_Age_grpby_Sex'] = sex_mean_df['female']
aggregated_df.loc[aggregated_df['Sex'] == 'male', 'agg_mean_Age_grpby_Sex'] = sex_mean_df['male']
 
# 性別ごとの年齢の最大値を特徴量に追加
sex_max_df = train_df.groupby('Sex')['Age'].max()
aggregated_df.loc[aggregated_df['Sex'] == 'female', 'agg_max_Age_grpby_Sex'] = sex_max_df['female']
aggregated_df.loc[aggregated_df['Sex'] == 'male', 'agg_max_Age_grpby_Sex'] = sex_max_df['male']
 
# 性別ごとのPclassの平均値を特徴量に追加
pclass_mean_df = train_df.groupby('Sex')['Pclass'].mean()
aggregated_df.loc[aggregated_df['Pclass'] == 'female', 'agg_mean_Pclass_grpby_Sex'] = pclass_mean_df['female']
aggregated_df.loc[aggregated_df['Pclass'] == 'male', 'agg_mean_Pclass_grpby_Sex'] = pclass_mean_df['male']
 
# 性別ごとのPclassの最大値を特徴量に追加
pclass_max_df = train_df.groupby('Sex')['Pclass'].max()
aggregated_df.loc[aggregated_df['Pclass'] == 'female', 'agg_max_Pclass_grpby_Sex'] = pclass_max_df['female']
aggregated_df.loc[aggregated_df['Pclass'] == 'male', 'agg_max_Pclass_grpby_Sex'] = pclass_max_df['male']

→この処理を、xfeatを使うと下のように非常にシンプルに書くことができます。これは嬉しいですね^^

aggregated_df, aggregated_cols = aggregation(train_df,
                     group_key="Sex",
                     group_values=["Age", "Pclass"],
                     agg_methods=["mean", "max"],
                     )
                     
cols_to_show = ["Sex"] + aggregated_cols
aggregated_df[cols_to_show].head(3)
Sex agg_mean_Age_grpby_Sex agg_mean_Pclass_grpby_Sex agg_max_Age_grpby_Sex agg_max_Pclass_grpby_Sex
0 male 30.726645 2.389948 80.0 3
1 female 27.915709 2.159236 63.0 3
2 female 27.915709 2.159236 63.0 3

7. LightGBM の feature importance を用いた特徴量の選択が簡単にできる

LightGBM の feature importance を見ると、どの特徴量がどれだけモデルの精度に影響を与えたかを知ることができます。
これにより、データの傾向を捉えたり、新たに追加した特徴量の効果があるかなどを調べたりできます。
通常、feature importance を確認するためには、

  1. モデルの作成
  2. 学習
  3. feature importance の抽出

というステップを経る必要があります。これを xfeat を使うと、

  1. 特徴量選択器の作成
  2. feature importance の抽出

と短いステップで書くことができます。

今回は、この記事で紹介した手法を使って元のデータにいくつか特徴量を追加し、特徴量の選択をしてみました。
最終的な入力データは以下です。

encoded_train_df.head(5)

f:id:acro-engineer:20201214230743p:plain

  • "Cabin_target"
    • "Cabin" データに Target Encoding した特徴量(3で紹介)
  • "SexCabin", "SexEmbarked", "CabinEmbarked"
    • "Sex", "Cabin", "Embarked" データのうち、二つを組み合わせた特徴量(4で紹介)
  • "SibSpParch_combi"
    • "SibSp", "Parch" データを加算した特徴量(5で紹介)
  • "agg_mean_Age_grpby_Sex", "agg_mean_Pclass_grpby_Sex", "agg_max_Age_grpby_Sex", "agg_max_Pclass_grpby_Sex"
    • 性別ごとに、年齢、Pclass の平均、最大を集計した特徴量(6で紹介)

この入力データに対して、特徴量の選択をします。

# LightGBMのパラメータを設定する
lgbm_params = {
    "objective": "binary",
    "metric": "binary_error",
}
fit_kwargs = {
    "num_boost_round": 10,
}

# 特徴量選択器を作成する
selector = GBDTFeatureSelector(
    target_col="Survived",
    threshold=0.5,
    lgbm_params=lgbm_params,
    lgbm_fit_kwargs=fit_kwargs,
)

GBDTFeatureSelector() で、特徴量選択をするインスタンスを作成しています。
また threshold の値で、入力データの変数のうちいくつを選択するかの設定をします。
今回は threshold の値が0.5, 元の説明変数が17個だったので、[17 * 0.5] = 8個の変数が最終的に選択されます。

selected_df = selector.fit_transform(encoded_train_df)
print("Selected columns:", selector._selected_cols)

Selected columns: ['Age', 'Fare', 'Cabin_target', 'SexCabin', 'Pclass', 'Sex', 'SibSpParch_combi', 'SexEmbarked']
年齢、運賃、キャビン番号の Target Encoding、性別×キャビン番号、チケットクラス、性別、兄弟/配偶者+両親/子供の数、性別×乗船場、の重要度が高いことがわかりました。

8. optuna と組み合わせて、特徴量探索が簡単にできる

7 ではパラメータを固定の状態で特徴量選択を行いましたが、さらに optuna と組み合わせることで、
Hyper Parameter Tuning によって LightGBM のモデルに重要な特徴量を探索できます。

今回は、特徴量選択数(入力データの変数のうちいくつを選択するか)と LightGBM のパラメータ二つ(num_leaves, max_depth)に幅を持たせて特徴量探索を行ってみました。入力データは7で使ったものと同じです。
※特徴量選択数は GBDTFeatureExplorer()threshold_range=(0.5, 1.0), で設定しています。
 optuna がこの (0.5, 1.0) の範囲で Hyper Parameter Tuning をして最適な値を探し出してくれます。  

LGBM_PARAMS = {
        "objective": "binary",
        "metric": "binary_error",
        "verbosity": -1,
}


def objective(df, selector, trial):
    selector.set_trial(trial)
    selector.fit(df)
    input_cols = selector.get_selected_cols()

    # Hyper Parameter Tuning するパラメータと範囲を設定する
    lgbm_params = {
        'num_leaves': trial.suggest_int("num_leaves", 3, 10),
        'max_depth': trial.suggest_int("max_depth", 3, 10),
    }
    lgbm_params.update(LGBM_PARAMS)

    # Evaluate with selected columns
    train_set = lgb.Dataset(df[input_cols], label=df["Survived"])
    scores = lgb.cv(lgbm_params, train_set, num_boost_round=100, stratified=False, seed=1)
    
    binary_error_score = scores['binary_error-mean'][-1]
    return 1 - binary_error_score


# 特徴量探索のための説明変数を設定する
# encoded_train_df は、No.7で作成したDataFrameと同じ
input_cols = list(encoded_train_df.columns)
input_cols.remove('Survived')


# 特徴量探索器を作成する
selector = GBDTFeatureExplorer(
    input_cols=input_cols,
    target_col="Survived",
    fit_once=True,
    threshold_range=(0.8, 1.0),
    lgbm_params=LGBM_PARAMS,
)

# Hyper Parameter Tuning を行う
study = optuna.create_study(direction="minimize")
study.optimize(partial(objective, encoded_train_df, selector), n_trials=100)

# 選択された特徴量を確認する
selector.from_trial(study.best_trial)
print("Selected columns:", selector.get_selected_cols())

Selected columns: ['Age', 'Fare', 'Cabin_target', 'SexCabin', 'SibSpParch_combi', 'Pclass', 'Cabin', 'SexEmbarked', 'Sex']
年齢、運賃、キャビン番号の Target Encoding、性別×キャビン番号、兄弟/配偶者+両親/子供の数、チケットクラス、キャビン番号、性別×乗船場、性別、の重要度が高いことがわかりました。

最終的なパラメータの値と学習データの正答率も見てみましょう。

print(study.best_params)

{'GBDTFeatureSelector.threshold': 0.5095199015409342, 'num_leaves': 9, 'max_depth': 8}

print(study.best_value)

0.8067415730337079
Cross Validation では、正答率80.7%でした。

※ちなみに、上のパラメータを使って Kaggle の Leaderboard で submit してみたところ、 スコアは 0.77511 でした。
これだけシンプルに書けて、特徴量の探索から予測までできるのは嬉しいですね。

9. cuDF にも適用可能

xfeat は、 cuDF を使って pandas.DataFrame と同様に Target Encoding や Aggregation を行うことができます。
cuDF とCuPyを使うことで、 Pandas だけを使うよりもなんと10~30倍速く処理を実行できるそうです(公式ページより)。
今回は、 cuDF を使って xfeat の Target Encoding を使ってみました。
cuDF のインストール方法や使い方についての詳細は、下の記事を参考にしてください。

acro-engineer.hatenablog.com

fold = KFold(n_splits=5, shuffle=False)
encoder = TargetEncoder(
    input_cols=["Cabin"], 
    target_col="Survived",
    fold=fold,
    output_suffix="_re"
    )

train_cdf = cudf.from_pandas(train_df)  # if cuDF is available.
encoded_train_cdf = encoder.fit_transform(train_cdf)
encoded_train_cdf[["Survived", "Cabin"]].head(3)

まとめ

xfeat を使って、タイタニックデータの特徴量エンジニアリング、特徴量探索を行ってみました。
Pandas だけを使うよりもシンプルでわかりやすく書けることが多かったので、今後も重宝しそうです。

Acroquest Technologyでは、キャリア採用を行っています。

  • ディープラーニング等を使った自然言語/画像/音声/動画解析の研究開発
  • Elasticsearch等を使ったデータ収集/分析/可視化
  • マイクロサービス、DevOps、最新のOSSを利用する開発プロジェクト
  • 書籍・雑誌等の執筆や、社内外での技術の発信・共有によるエンジニアとしての成長

  少しでも上記に興味を持たれた方は、是非以下のページをご覧ください。

【データ分析】 Kaggle Masterと働きたい尖ったエンジニアWanted! - Acroquest Technology株式会社のデータサイエンティストの求人 - Wantedlywww.wantedly.com

Ver.7.11からElasticsearchのスキーマ設計が大きく変わる

こんにちは、アクロクエストテクノロジー株式会社でElastic Stackのコンサルティング業務を担当している吉岡です。本記事は、Elastic Stack (Elasticsearch) Advent Calendar 2020 の14日目の内容になります。

本記事では、2020/10/13~2020/10/15に開催されたElastic ON Globalで、個人的に最もエキサイティングに感じたセッション「Schema on read with runtime fields」を紹介します。

Elastic ON Global
www.elastic.co

Schema on read with runtime fields

セッション概要

Elasticsearch has always been fast, but required structuring and indexing your data up front. We're changing that with the introduction of runtime fields, which enable you to extract, calculate, and transform fields at query time. They can be defined after data is indexed or provided with your query, enabling new cost/storage/performance tradeoffs, and letting analysts gradually define fields over time.

  • 発表動画

www.elastic.co

  • 発表資料

www2.slideshare.net

セッションを読み解くための重要キーワード

Schema on Write と Schema on Read

  • Schema on Write と Schema on Readの詳細にについては以下のブログが参考になります。

www.elastic.co

Runtime Field

これまで、Elasticsearchは主に「Schema on Write」のアプローチを採用してきました。検索/分析要件を先に決めて、Mappingを書いてからデータを投入する。スキーマレスと言いながら、最適な性能を得るには「Schema on Write」が必須でした。
Elasticsearch Ver.7.11から「Runtime Field」というデータ型が導入されます。一言で言うと、クエリ時にスクリプト(データ加工/抽出)を実行できるデータ型。スクリプトはMappingに記述(事前に定義)することも、クエリ自体に指定(実行時に定義)することも可能です。この「Runtime Field」と「非同期検索(Ver.7.7~)」を併用することで「Schema on Read」のユースケースが実現可能になります。

発表資料に関するコメント

以降はセッションの発表資料を抜粋しながらコメントしたいと思います。

f:id:acro-engineer:20201213182153p:plain:w800

  • Schema on Write と Schema on Readの比較です。
  • 左が従来の「Schema on Write」アプローチ。インデクシングする際にデータ加工を行うことで高速なクエリ/アグリゲーションを実現します。
  • 右が新しくサポートする「Schema on Read」アプローチ。インデクシング時にデータ加工をせず、ほぼ生データをロードする形になるためインデクシングは高速です。データ加工は必要に応じてクエリ毎に指定すればOK。これは、投入するデータの詳細がよく分かっておらず、事前のスキーマ(Mapping)作成が困難なシーンで特に有効です。

f:id:acro-engineer:20201213182208p:plain:w800

  • Runtimeフィールドを利用した場合「Schema on Write」と比較してインデックスサイズ(消費ストレージ)は小さく、インデクシングは高速になります。ただし、クエリの速度は大きく下がります。(クエリ時にデータ加工するので当然です)

f:id:acro-engineer:20201213182220p:plain:w800

f:id:acro-engineer:20201213182229p:plain:w800

  • Async search(非同期検索)での利用例。Rangeクエリで時間範囲を指定し、statusが「200」のドキュメントを検索しています。
  • Rangeクエリでヒットする全ドキュメントに対して「Mappingのstatusフィールドに定義されたスクリプトを実行し動的にstatusの値を生成、statusが200のドキュメントに絞り込むクエリ。Schema on Writeアプローチでの時間感覚(検索は100ms以下が当たり前)からするとスロークエリそのものです。
  • しかし、Schema on Readのユースケースはクエリの実行頻度が少ないシーンを想定しているので、非同期検索(デフォルトのタイムアウトは5日)でゆるやかに実行する形です。逆に、検索速度を求めるシーンでは、Runtimeフィールドではなく、通常のフィールドをSchema on Writeで使いましょう。

f:id:acro-engineer:20201213182242p:plain:w800

  • クエリ時にスクリプトを定義する場合のサンプル。「runtime_mappings」というパラメータに、ipフィールドを生成するスクリプトを記述しています。
  • MappingにRuntimeフィールドを定義していなくても、クエリで動的にフィールドを生成することができるのは非常に便利ですね。Schema on Writeではスキーマ設計/変更を管理者に集約する運用になると思いますが、Schema on Readでは各ユーザーがクエリを通して自由にスキーマ設計できることになります。


f:id:acro-engineer:20201213182256p:plain:w800

  • 将来的にはPainless以外にもGrokやその他のエンリッチをサポートするようです。

f:id:acro-engineer:20201213182327p:plain:w800

  • Schema on Readにおけるフィールドライフサイクルは以下のようになります。
    1. インデクシング時に@timestampだけを抽出し、時刻以外をmessageフィールドに入れておく。
    2. データを抽出したい時にクエリに抽出スクリプトを記述し、必要なデータ取得する(Mappingの変更が不要)。Schema on Writeでデータ加工をしようとすると、その都度Reindexが必要ですが、Schema on Readでは、データ加工の試行錯誤をするのにReindexが不要です。
    3. 頻繁に利用するフィールドは、通常のフィールド(Indexed Field)に移行する。具体的には、インデックステンプレートにIndexed Fieldを追加、次に生成される(日単位インデックスであれば翌日、月単位インデックスであれば翌月)インデックスからはSchema on Write用フィールドになります。

f:id:acro-engineer:20201213182340p:plain:w800

  • 通常の検索(左)と非同期検索(右)の仕様の比較。非同期検索は長時間かかるクエリを実行するもので、クエリが完了する前でも、途中までの検索結果を取得することが可能です。

f:id:acro-engineer:20201213182359p:plain:w800

  • まとめを意訳。
  • Schema on Readの導入により、Elasticsearchのスキーマ設計が大きく変わります。従来のように一気にスキーマを完成させてからデータ投入するのではなく、スキーマを大雑把に決めてデータ投入をしてしまい、必要に応じてフィールドを作成し、徐々にスキーマを確定していくことになります。また各フィールドは、検索、可視化、アドホックな調査、バッチ処理など、コンテキスト毎に設計するのが主流になるでしょう。

Acroquest Technologyでは、キャリア採用を行っています。

  • ディープラーニング等を使った自然言語/画像/音声/動画解析の研究開発
  • Elasticsearch等を使ったデータ収集/分析/可視化
  • マイクロサービス、DevOps、最新のOSSを利用する開発プロジェクト
  • 書籍・雑誌等の執筆や、社内外での技術の発信・共有によるエンジニアとしての成長

 
少しでも上記に興味を持たれた方は、是非以下のページをご覧ください。

【データ分析】
Kaggle Masterと働きたい尖ったエンジニアWanted! - Acroquest Technology株式会社のデータサイエンティストの求人 - Wantedlywww.wantedly.com

コンテナ内のアプリが複数種類のログを出力する場合の収集方法

こんにちは。アキバです。

この記事は、Elastic Stack (Elasticsearch) Advent Calendar 2020 - Qiita の12日目です。
qiita.com

当社ではリモートワークに移行し始めて9~10か月になろうかというこの頃ですが、リモートワークをされている皆さんはどのような工夫をされているでしょうか?

私はiPad Proを日常的に使って、社内のホワイトボードでやっているような手書き体験の共有をしています。
最近、新しいペーパーライクフィルムを使用することになったのですが、これまでのペーパーライクと触感がガラリと変わり、慣れるまでちょっとぎこちない感じです。

今日は、そんな手書き体験の話とは全く関係ない、ログ収集に関する話です。

何の話か?

定期的に起きる質問

今の時代、アプリケーションをDocker/Kubernetesなどのコンテナ上で動作させることが多くなってきましたが、定期的に以下のような質問が出ます。

コンテナに載せたアプリケーションが複数のログを出力するような場合に、どうやってログを収集するのが良いのか?

コンテナを使わない場合は以下のような形でログ収集することができます。

f:id:acro-engineer:20201213140525p:plain

アプリケーションをコンテナに載せて動かそうとしたときに、通常はFilebeatはコンテナの外に置きたいと思います。
特に、Kubernetesの場合はFilebeatはDaemonSetで動かし、AutoDiscoverによってログ収集対象となるPodを(アプリコンテナの外で)選択します。

こうした構成で、以下のようにコンテナ内で複数種類のログを出力していると、単純にはコンテナ外からログが収集できないわけです。
(もっとも、コンテナ内にログを出力すること自体が悪手であり、ログを活用できないため意味のない行為ではありますが...)

f:id:acro-engineer:20201213140552p:plain

単純にログが1種類ならば、コンソール出力にしてcontainer inputで取得するのが定石かなと思いますが、コンソール出力は複数にできないので、何かしら策を講じる必要が出てきます。

理想的には

お作法的なことを言えば、1つのコンテナで動作するプロセスは1つであり、そのプロセスが出力する(収集対象となる)ログも1種類にしたいところです。
しかしながら、一部のアプリケーションには(アプリケーションの動作ログの他に)以下のようなログを出力するものがあります。

  1. アクセスログ - 自分のAPIが呼び出された際の記録(エンドポイント、ステータスコード応答時間など)
  2. 監査ログ - システム/アプリケーションの重要な操作(試行)の記録(操作/権限、ユーザ、成功or失敗など)

どのようにログ収集の仕組みを構築し、Elasticsearch+Kibanaで可視化するか?をパターンに分けて検討してみたいと思います。

※個人的な見解を含みます。もっと良い方法があるかもしれません。

コンテナ内のアプリが複数種類のログファイルを出力する場合の収集方法

方法1:ログファイルをコンテナ外から参照できるように共有する

Dockerであれば、Volume Mountを使ってホストのディレクトリをコンテナ(のログ出力ディレクトリ)にマウントする方法が可能です。
これにより、ホスト側で動作するFilebeatが、コンテナ内のプロセスが出力したログファイルを参照し、ログを収集することが可能になります。

f:id:acro-engineer:20201213140609p:plain

メリット
  1. コンテナが異常終了しても出力したログはホスト側に残るので、欠損(出力したログがElasticsearchに送られない現象)が発生しにくい
  2. アプリケーションはログ出力の方式(出力するファイルの数やフォーマット)を変更する必要がない
  3. ログの種類ごとのタグ付けはFilebeatで行い、投入先のElasticsearchのインデックス指定をLogstashで行う
  4. ログ加工が必要な場合は、Ingest PipelineまたはLogstashを使用可能
デメリット
  1. コンテナの可搬性は下がる(DockerComposeを使うことで一部吸収可能だが、ホスト側のディレクトリ準備やuidの統一など一部制約が生まれる)
  2. ホスト側でコンテナx収集対象ログファイル数のFilebeatを起動する必要がある
  3. Kubernetesの場合はこの方式は適用できない

方法2:Filebeatをコンテナ内に入れる

コンテナ内でFilebeatを動かせば、任意のログファイルを収集対象にすることができます。
複数のFilebeatを動かせば、複数のログファイルを収集することができますね。

f:id:acro-engineer:20201213140626p:plain

メリット
  1. コンテナの可搬性は高い(イメージに含まれているリソースのみでログ収集が完結する)→ Kubernetesでも実現可能
  2. アプリケーションはログ出力の方式(出力するファイルの数やフォーマット)を変更する必要がない
  3. ログの種類ごとのタグ付けはFilebeatで行い、投入先のElasticsearchのインデックス指定をLogstashで行う
  4. ログ加工が必要な場合は、Ingest PipelineまたはLogstashを使用可能
デメリット

Filebeatをコンテナ内に置くことでいくつかの注意点が発生します。

  1. 「どのコンテナから送られてきたログか」を示すには、コンテナ起動時にひと工夫が必要
    (それさえ出来れば、大きなデメリットではない)
    • filebeat.yml に add_docker_metadata の指定を行う
    • dockerがUNIXソケットで通信をしている場合、ホスト側の /var/run/docker.sock をマウント(TCP/IP通信の場合は、hostパラメータにIPアドレスを記載する)
    • 必要に応じて、rootユーザ権限を付与する
  2. コンテナの終了タイミングでFilebeatも終了してしまうため、一部のログがElasticsearchに送られず欠損する可能性がある
  3. Filebeatを入れて動かす分、わずかにコンテナサイズが肥大化する
  4. 設定がコンテナごとに存在するため、Filebeatの設定変更でコンテナの再作成(再起動)が必要になる

方法3:アプリでログの種類がわかるようにタグ付けし、すべてコンソールに出力する

アプリケーションがすべてのログをコンソール出力するように設定すれば、一つのFilebeatを使ってcontainer inputでまとめて収集することが可能です。

f:id:acro-engineer:20201213140641p:plain

メリット
  1. コンテナの可搬性は高い(ログ収集に関するリソースをアプリコンテナが持たない)→ Kubernetesでも実現可能
  2. コンテナが異常終了しても出力したログはホスト側に残るので、欠損(出力したログがElasticsearchに送られない現象)が発生しにくい
  3. コンテナの外でログ収集が可能なので、Filebeat側でコンテナを区別してタグ付けが可能
  4. コンテナにFilebeatを含める必要がないため、イメージの肥大化やライフサイクルの依存がない
デメリット
  1. アプリケーション側でログ出力先とフォーマット、特に種類がわかるようにするタグ付けが必要(初期の設計または設計変更が必要となる)
  2. 1つのFilebeatで処理をするため、設定できるタグや送信先は1つになる
    ログの種類ごとにElasticsearchのインデックスを分けたり、ログ加工が必要になる場合は、Logstashが必須(Ingest Pipelineだけでは実現できない)

共通:Kibanaでの可視化について

いずれの場合も、Elasticsearchに投入するまでの過程でタグ付けやログ加工、インデックスの振り分けを行えますので、Kibana(LogsやVisualize)で可視化する際の要求に対しては柔軟な設定が可能です。
(どの段階で加工・振り分けを行うか?の違いがあるため、システムの変更/構成管理のしやすさで制約が発生する可能性があります)

逆の言い方をすると、どのような可視化をするか?に沿ってこれらの処理を決める必要があります。
タグ付けやログ加工はそれほど頻繁に変わるものではないですが、コンテナのライフサイクルに影響を与えないことを考えると、Filebeatはコンテナの外にいることが望ましいと思います。

まとめ

Docker単独/Kubernetes上で動かすか、アプリケーション側の対応や変更が可能かによって選択肢が変わってくる部分があるかと思いますが、個人的には方法3がベターなのかなと思っています。
アプリケーション側で最初の設計さえ行えれば、それ以外のログ収集に関する要素をアプリケーション側から切り離すことができるのが最大のメリットだと思います。

ログ収集は後からでも始められますが、システム構築の設計段階からこういったことを考慮しておくと運用がしやすくなるのではないかと思いますので、参考にしていただければと思います。

それでは。

Acroquest Technologyでは、キャリア採用を行っています。

  • ディープラーニング等を使った自然言語/画像/音声/動画解析の研究開発
  • Elasticsearch等を使ったデータ収集/分析/可視化
  • マイクロサービス、DevOps、最新のOSSを利用する開発プロジェクト
  • 書籍・雑誌等の執筆や、社内外での技術の発信・共有によるエンジニアとしての成長

 
少しでも上記に興味を持たれた方は、是非以下のページをご覧ください。

世界初のElastic認定エンジニアと一緒に働きたい人Wanted! - Acroquest Technology株式会社のデータサイエンティストの求人 - Wantedlywww.wantedly.com

kibanaのURL drilldownを使ってログ管理を効率化する

こんにちは。@Ssk1029Takashiです。
この記事は、Elastic Stack (Elasticsearch) Advent Calendar 2020の11日目です。
qiita.com

はじめに

Kibanaでアプリのログ管理をしていると、KibanaのDashboardだけを見ているだけではなく、実際のWebアプリの画面も確認することが多いです。
例えば、検索アプリの検索ログをKibanaでダッシュボードしている場合、急に検索回数が増えた単語などは、ユーザーがどんなコンテンツを探しているのか知るために実際の検索結果画面が見たくなります。

このような時に、DashboardとWebアプリの画面を行き来するのは、オペレーションの中で意外とストレスになります。
f:id:acro-engineer:20201206203709p:plain

そこで、Kibana 7.10から追加されたURL drilldownという機能を使うことで、より手軽にDashboardからWebページを参照できるようなります。

今回書かないこと

今回以下のことは記事の対象外にしています。

  • App Search・Elastic Stackの構築方法
  • Visualizeの作成方法

URL Drilldownとは

簡単に言うと、DashboardからクリックしたVisualizeの値をもとにしたURLへ遷移できる機能です。
URLはテンプレートを使って、クリックした値やVisualizeのタイトルなどを参照できます。

使い方として、以下のようにケースがあります。

  • 問題を絞り込んでクリックする際に、チケット管理システムのURLの特定フィールドに渡して起票する
  • ログ管理で表示したIPアドレスを外部のReputationサイトに渡して、そのページで結果を見てさらに詳しい情報を参照する。

IPアドレスをReputationサイトで調査する機能はSIEM UIに標準で実装されていますが、Dashboardからでも実現可能になります。

詳しくは以下のドキュメントを参照してください。
www.elastic.co

実際に試してみる

環境

今回はElastic Cloud上のApp Searchを検索アプリとして、URL drilldownを使った画面遷移を試してみます。
Elasticsearch:7.10
Kibana:7.10
App Search:7.10

また、今回は事前にApp Searchでこのブログのデータを検索できるようにしています。
構成としては以下のようになっています。
f:id:acro-engineer:20201211004519p:plain

Dashboardを作成する

まずは、App Searchのログを参照して、検索されたキーワードの頻度を出すVisualizeを作成して、Dashboardに設定します。
今回はLensのTreeMapを使用しています。
f:id:acro-engineer:20201207001405p:plain

URL drilldownを設定する

それではDashboardにURL drilldownを設定していきます。
Dashboardの編集画面から、URL drilldownを設定したいVisualizeを選択すると、「Create drilldown」というメニューが出てきます。
f:id:acro-engineer:20201207004241p:plain
選択すると、drilldown作成メニューが表示されます。
まず、Dashboard drilldownかURL drilldownのどちらを作成するかを選択する必要があるので、「Go to URL」を選択します。
f:id:acro-engineer:20201209231824p:plain
drilldown名とURLテンプレートを設定する画面なので、任意の名前と、URLを設定しましょう。
URLは以下のように検索サイトのURLにテンプレート文字列で選択した値がURLパラメータになるように設定します。
App Searchでは、URL引数にq=<検索キーワード>の形式で指定することで、検索できるので、以下のようにテンプレートを設定します

https://<検索サイトのURL>?q={{event.value}}

上記の{{event.value}}の部分にDashboardで選択した部分が表示している値が入ります。

上記を設定後、「Create drilldown」を選択して、URL drilldownを作成します。
設定後は、Dashboardを保存する必要があるので、忘れないようにしましょう。

Dashboardから検索ページに遷移する

保存後に、Dashbaord上でデータがある場所をクリックすると、以下のように、ポップアップが表示されるようになります。
f:id:acro-engineer:20201209234437p:plain

ポップアップのうち、URL drilldownをクリックすることで、Dashboard上で選択した値で検索されたページに飛ぶことができます。
f:id:acro-engineer:20201209235755p:plain

このように、Dashboard上でログを見ながら、スムーズにアプリでより詳細な情報を確認することができます。
無駄な画面移動や入力が減って、効率的になりましたね。

まとめ

本記事では、Kibanaの新機能であるURL drilldownを利用して、DashboardからWebアプリの画面にスムーズに移動できるようにすることで、日々の運用の効率化を図りました。
別のページを開きなおす、再度入力し直すなどの手間が減って、効率的になりそうです。
皆さんもDashboardでアプリログを運用するときにはぜひ参考にしてみてください。

Acroquest Technologyでは、キャリア採用を行っています。

  • ディープラーニング等を使った自然言語/画像/音声/動画解析の研究開発
  • Elasticsearch等を使ったデータ収集/分析/可視化
  • マイクロサービス、DevOps、最新のOSSを利用する開発プロジェクト
  • 書籍・雑誌等の執筆や、社内外での技術の発信・共有によるエンジニアとしての成長

 
少しでも上記に興味を持たれた方は、是非以下のページをご覧ください。

世界初のElastic認定エンジニアと一緒に働きたい人Wanted! - Acroquest Technology株式会社のデータサイエンティストの求人 - Wantedlywww.wantedly.com

超爆速なcuDFとPandasを比較した

皆さんこんにちは。
@tereka114です。
今年末はKaggleで開催される面白いコンペも多くて日々、エンジョイしています。

最近は巨大なデータを扱うことが増えており、Pandasだと時間がかかりすぎて効率が悪いと感じています。
そのため、データを高速に処理できるcuDFを利用することも多くなってきました。
この記事ではcuDFの魅力と扱う際の注意点を説明していきます。

※この記事は「Pythonその2 アドベントカレンダー」10日目の記事です。
qiita.com

cuDFとは

cuDFはNVIDIAさんが開発している、Pandasの代わりに利用することができるGPUのライブラリです。
最も大きな特徴はGPUで計算するため、高速であることです。
主に、カテゴリ変数ごとの平均計算や、テーブル同士の結合といった、時間のかかるテーブル処理で、効果を発揮します。

github.com

cuDFは特徴量を簡単に作れるライブラリであるxfeatでもサポートされています。

github.com

cuDFとPandasの性能比較

cuDFがどの程度強力なライブラリなのかを評価します。
今回は利用頻度の多い、次の2点に関して性能を計測しました。

  • カテゴリごとの平均値の計算
  • テーブルの結合

前準備

Colaboratory上での準備

cuDFは手元にGPU環境がなくとも、Google Colaboratoryを利用すれば、簡単に試せます。
今回の性能計測もGoogle Colaboratory上で実施しました。
Google ColaboratoryでcuDFを動かすためには、次のコマンドを最初に実行してください。

!git clone https://github.com/rapidsai/rapidsai-csp-utils.git
!bash rapidsai-csp-utils/colab/rapids-colab.sh stable

import sys, os

dist_package_index = sys.path.index('/usr/local/lib/python3.6/dist-packages')
sys.path = sys.path[:dist_package_index] + ['/usr/local/lib/python3.6/site-packages'] + sys.path[dist_package_index:]
sys.path
exec(open('rapidsai-csp-utils/colab/update_modules.py').read(), globals())
データ作成

本検証では擬似データとして2つのテーブルを作成します。
作成条件は次の通りです。

  • メインテーブル:2000万レコード、カテゴリを2つ100000種類
  • 結合用テーブル:100万レコード、カテゴリを100000種類
import numpy as np
import pandas as pd
import cudf

N = 20000000
MERGE_N = 1000000

df = pd.DataFrame([{"Category": np.random.randint(0,100000), "Category2":np.random.randint(0,100000), "Value": np.random.rand()} for _ in range(N)])
right_df = pd.DataFrame([{"Category": np.random.randint(0,100000), "Value2": np.random.rand()} for _ in range(MERGE_N)])
cudf_table = cudf.from_pandas(df)
cudf_right_table = cudf.from_pandas(right_df)

試したこと

カテゴリごとの平均値の計算

巨大データからカテゴリごとの平均を計算する(df.groupby.mean)ケースで試してみます。
この場合Pandasだと非常に長時間の計算が必要です。
先程作成した「メインテーブル」で平均を計算します。実装は次の通りです。(時間計算部は省略しています)

df.groupby(["Category", "Category2"]).mean() # Pandas
cudf_table.groupby(["Category", "Category2"]).mean() # cuDF

結果はcuDFが50倍高速でした。(驚異的なスピード)

  • Pandas:50.92s
  • cuDF:1.02s
テーブルの結合

次に巨大ファイルの結合を試します。
作成した「メインテーブル」と「結合用テーブル」を"Category"列で結合します。実装は次の通りです。

df.merge(right_df, on="Category", how="left") # Pandas
cudf_table.merge(cudf_right_table, on="Category", how="left") # cuDF

結果、cuDFが37.5倍高速です。(早い!)

  • Pandas:20.65s
  • cuDF:0.55s

cuDFを扱う上での注意点

Pandasと比較して爆速なcuDFですが、3点注意点があります。

1. mergeの並び順が異なる。

Pandasのmergeは元のテーブルと順番が変わりません。
しかし、cuDFの出力結果は並列計算の都合で元のテーブルと順番が異なります。
そのため、順番に依存する処理(ex:インデックス番号でデータを分ける)を記載している場合に期待しない動作になるので注意が必要です。

2. 平均の結果がPandasと異なる。

巨大なデータを扱うときにはPandasと平均値の結果が異なる場合があります。
現在Kaggleで開催されている「Riiid! Answer Correctness Prediction」では、平均値を取ったときに計算結果がpandasとcuDFで異なる結果が返ってきます。
本件についてはオープンに議論しており、議論している場所は次の箇所です。

www.kaggle.com

原因は不明ですが、色々と検証した結果、cuDFの値が正しそうです。
何らかの事情で計算環境が異なりPandasとcuDFの実装が混ざる状況の場合はテストコードを書いて検知するなど、対策が必要だと思っています。

3. 未実装/IFが異なる関数がある

cuDFは全てのPandasの関数をサポートできておらず、未実装関数やIFがPandasと合わないものがいくつかあります。
df.unstackのIFが若干異なることでプログラムで例外が発生したり、df.applyを対応していなかったりします。
その場合は一時的にPandasに変換(df.to_pandas())を行い、計算するなどで回避可能です。

最後に

ここまでcuDFが爆速であることをお伝えしてきました。
しかし、挙動を把握しながら実装していかないと思わぬ罠にハマり、苦労することがあります。
個人的にcuDFの性能が最高なので、挙動のクセを正しく理解、評価した上で、使っていきたいと思います!

Acroquest Technologyでは、キャリア採用を行っています。

  • ディープラーニング等を使った自然言語/画像/音声/動画解析の研究開発
  • Elasticsearch等を使ったデータ収集/分析/可視化
  • マイクロサービス、DevOps、最新のOSSを利用する開発プロジェクト
  • 書籍・雑誌等の執筆や、社内外での技術の発信・共有によるエンジニアとしての成長

 
少しでも上記に興味を持たれた方は、是非以下のページをご覧ください。

【データ分析】
Kaggle Masterと働きたい尖ったエンジニアWanted! - Acroquest Technology株式会社のデータサイエンティストの求人 - Wantedlywww.wantedly.com

ソースからビルドしてElastic Stackの最新バージョンを触ってみる

こんにちは、ノムラです。
この記事はElastic Stack (Elasticsearch) Advent Calendar 2020 の7日目になります。

目次は以下です。

はじめに

Elastic Stackはご存じの通り、OSSの製品であるため、ソースコードがGit上に公開されています。
github.com
github.com

このソースをビルドすることで開発中の最新バージョンもお試しで触ることができます。
そこで今回は、実際にビルドしてみて、Elastic Stack 8.0を触ってみたいと思います。

環境情報

環境:AWS
OS:Amazon Linux 2 AMI (HVM)
インスタンスタイプ:t2.large
Java:14.0.2

Elasticsearchをビルドする

Elasticsearchのビルドにはgradleを利用します。
まずはgradleのインストールから、と思うところですが、gradlewが作成されているため、実際はgit cloneをしてコマンドを実行するだけです。

ソースを github から clone する

$ sudo yum install -y git
$ git clone https://github.com/elastic/elasticsearch.git

Elasticsearchをビルドする

$ cd elasticsearch/
$ ./gradlew :distribution:archives:linux-tar:assemble

ビルドされたファイルは distribution ディレクトリに出力されます。

$ ls distribution/archives/linux-tar/build/install/elasticsearch-8.0.0-SNAPSHOT
bin     data  lib          logs     NOTICE.txt  README.asciidoc
config  jdk   LICENSE.txt  modules  plugins

Elasticsearchを起動する

$ cd distribution/archives/linux-tar/build/install/elasticsearch-8.0.0-SNAPSHOT
$ bin/elasticsearch
$ curl localhost:9200
{
  "name" : "es-sample",
  "cluster_name" : "elasticsearch",
  "cluster_uuid" : "tQl8J8LZQPOCfqESKImJRQ",
  "version" : {
    "number" : "8.0.0-SNAPSHOT",
    "build_flavor" : "default",
    "build_type" : "tar",
    "build_hash" : "966189fa6a42882c127742c43c52d29f668c3f48",
    "build_date" : "2020-12-05T16:13:39.509805Z",
    "build_snapshot" : true,
    "lucene_version" : "8.7.0",
    "minimum_wire_compatibility_version" : "7.11.0",
    "minimum_index_compatibility_version" : "7.0.0"
  },
  "tagline" : "You Know, for Search"
}

無事起動できました。
次はKibanaを構築したいと思います。

Kibanaを構築する

Kibanaのソースからの起動方法は公式ドキュメントの開発者ガイドに記載されています。
www.elastic.co

ソースを github から clone する

$ git clone https://github.com/elastic/kibana.git

nvm をインストールする

公式ドキュメントに従ってnvmをインストールします。
github.com

$ wget -qO- https://raw.githubusercontent.com/nvm-sh/nvm/v0.37.2/install.sh | bash
$ nvm use
$ nvm install 14.15.1

yarn をインストールする

同様に公式ドキュメントに従ってyarnをインストールします。
classic.yarnpkg.com

$ curl --silent --location https://dl.yarnpkg.com/rpm/yarn.repo | sudo tee /etc/yum.repos.d/yarn.repo
$ curl --silent --location https://rpm.nodesource.com/setup_12.x | sudo bash -
$ sudo yum install -y yarn

bootstrapを実行し必要なパッケージをインストールする

bootstrap実行の前にgccをインストールします。
後述のyarnコマンド実行のために必要です。

$ sudo yum -y install -y gcc*

yarnコマンドを実行し、パッケージをインストールします。

$ yarn kbn bootstrap

Kibanaを起動する

$ yarn start

Kibanaが起動できました。
f:id:acro-engineer:20201207025620p:plain:w400f:id:acro-engineer:20201207071254p:plain:w400

おまけ

今回は利用しませんでしたが、以下のコマンドを実行することで、Kibanaプロジェクトのみで動作確認をすることもできます。便利ですね。

$ yarn es snapshot --license trial

まとめ

ソースからビルドして、Elastic Stack 8.0を触ってみました。
これで、今後いち早く気になる最新機能を触ることができそうです。

それでは。

Acroquest Technologyでは、キャリア採用を行っています。

  • ディープラーニング等を使った自然言語/画像/音声/動画解析の研究開発
  • Elasticsearch等を使ったデータ収集/分析/可視化
  • マイクロサービス、DevOps、最新のOSSを利用する開発プロジェクト
  • 書籍・雑誌等の執筆や、社内外での技術の発信・共有によるエンジニアとしての成長

 
少しでも上記に興味を持たれた方は、是非以下のページをご覧ください。

世界初のElastic認定エンジニアと一緒に働きたい人Wanted! - Acroquest Technology株式会社のデータサイエンティストの求人 - Wantedlywww.wantedly.com