Quantcast
Channel: Elastic Blog - Elasticsearch, Kibana, and ELK Stack
Viewing all 419 articles
Browse latest View live

Elastic Stack 6.7.0 リリース


Elasticsearchでのイベントベースのデータ重複を効果的に防止

$
0
0

Elastic Stackは、多くのさまざまなユースケースに使われています。最も一般的なものの一つに、セキュリティイベント、ログ、メトリックといった、色々な種類のイベントや時系列データの格納と分析があります。これらのイベントは、イベント発生時または収集時を表す特定のタイムスタンプにリンクしたデータからなることが多く、往々にしてそのイベントを他と区別できる適切なキーがありません。

いくつかのユースケース、またおそらくユースケース内のデータのタイプにとっては、Elasticsearch内のデータが重複しないことは重要です。それは、ドキュメントの重複が分析の誤りや検索結果のエラーを導くからです。昨年、Logstashを用いた重複対策についてというブロク記事で本件を見ていきましたが、今回はもう少し詳しくよくある質問にお答えしていきたいと思います。

Elasticsearchへのインデックス

Elasticsearch内にデータをインデックスするときは、データが正常にインデックスできたと確認できるレスポンスを受け取ることが必要です。接続エラーやノードクラッシュなどのエラーがあるとそうしたレスポンスを受け取ることができず、データがインデックスできていないものがあるかどうかも分かりません。クライアントがこうした事態に遭遇したとき、確実な結果を得るためには再試行するのが標準的ですが、これでは同じドキュメントを2回以上インデックスすることになります。

重複対策のブログ記事で説明したように、これは、クライアント内の各ドキュメントにユニークなIDを定義しておくことで回避することが可能で、インデックス時にElasticsearchのID自動割り当てを利用するよりも有効です。重複するドキュメントを同じインデックスに書き込むと、2回ドキュメントを書き込む代わりに更新することになるので、重複を防ぐことになります。

UUIDとハッシュベースのドキュメントID

IDにどのタイプを使うか決めるにあたっては、主に2つのタイプから選ぶことができます。

Universally Unique Identifiers (UUID)は128ビット数に基づく識別子で、実用的な目的にかなってユニークでありながら、分散システム全体で横断的に生成可能です。このタイプの識別子は通常、イベントが関連付けられているコンテンツに依存しません。

UUIDを使用して重複を回避するには、イベントが正確に1回だけ発生していることを保証する境界をイベントが通過する前に、UUIDが生成され、イベントに割り当てられる必要があります。これは実際面では、UUIDをイベントの発生時に割り当てることを意味します。イベントが発生するシステムがUUIDを生成できないと、異なるタイプの識別子を使用する必要が生じる場合があります。

もう一つの主な識別子のタイプは、ハッシュ機能を用いてイベントのコンテンツをベースにした数値ハッシュを生成するものです。このハッシュ機能は特定のコンテンツに対して必ず同じ値を生成しますが、生成された値はユニークであるとは限りません。この2つの異なるイベントが同じハッシュ値になるというハッシュの衝突は、使用されるハッシュ関数のタイプと作成する値の長さだけでなく、インデックス内のイベント数に依存します。MD5やSHA1などの少なくとも128ビット長のハッシュは、多くのシナリオにおいて、一般的に長さと低い衝突率の間でバランスがとれたものです。さらに厳密にユニークであることを保証するためには、SHA256のような長いハッシュを使うことができます。

ハッシュベースの識別子はイベントのコンテンツに依存するので、どこで生成されても同じ値が算出されるため、後の処理段階で割り当てることが可能です。このことから、このタイプのIDはデータがElasticsearchにインデックスされる前ならいつでも割り当てることができ、投入パイプラインをデザインするときに柔軟性を与えます。

Logstashは、フィンガープリントフィルター プラグインにより、UUID算出とよく使われる一般的な幅広いハッシュ関数に対応しています。

効果的なドキュメントIDの選択

Elasticsearchがインデックス時に識別子の割り当てを許されている場合は、生成された識別子がインデックスに既存のものであってはならないことが分かっているので、最適化を行うことができます。これによりインデックス化のパフォーマンスが上がります。外部で生成されドキュメントとともに渡された識別子に対しては、Elasticsearchはこれが更新の可能性があるものとみなし、ドキュメントの識別子が既存のインデックスセグメントにあるかどうかチェックするので、余分な作業が必要となり処理が遅くなります。

外部ドキュメントの識別子は、すべて等しく作成されているわけではありません。並べ替え順序に基づいて時とともに徐々に増加する識別子は、完全にランダムな識別子よりもインデックス化のパフォーマンスが上です。その理由は、Elasticsearchが、最小および最大の識別値のみに基づく古いインデックスセグメントに識別子があるかどうかを、全体を検索しなければならないよりもすばやく判断できるからです。本件はこちらのブログ記事にて紹介しており、少し前のものですが今でも有効です。

ハッシュベースの識別子と多くの種類のUUIDは、一般的にランダムであるという性質があります。一つひとつタイムスタンプを定義するイベントのフローを扱うときは、このタイムスタンプを識別子のプレフィクスとして使い並べ替え可能にして、インデックス化のパフォーマンスを上げることが可能です。

タイムスタンプをプレフィクスにして識別子を作成することは、ハッシュ値がタイムスタンプごとにユニークでありさえすれば良いため、ハッシュの衝突可能性を減らすメリットもあります。これにより、投入量の多いシナリオにおいてもより短いハッシュ値を使うことが可能になります。

Logstashでは、UUIDあるいはハッシュを生成するためにフィンガープリントフィルター プラグインを使ったり、タイムスタンプを16進の文字列表現をRubyフィルターを使うことで、この種の識別子を作成することができます。ハッシュ化できるメッセージフィールドがあり、イベントのタイムスタンプがすでに@timestampフィールドへパースされていることが推測される場合は、その識別子のコンポーネントを作成し、メタデータに次のように格納することが可能です。

fingerprint {
  source => "message"
  target => "[@metadata][fingerprint]"
  method => "MD5"
  key => "test"
}
ruby {
  code => "event.set('@metadata[tsprefix]', event.get('@timestamp').to_i.to_s(16))"
}

すると、ドキュメントIDをElasticsearch出力プラグイン内に作成する際に、次の2つのフィールドが使用されます。

elasticsearch {
  document_id => "%{[@metadata][tsprefix]}%{[@metadata][fingerprint]}"
}

これは、16進法で長さ40文字のドキュメントIDとなり、例えば4dad050215ca59aa1e3a26a222a9bbcaced23039のようになります。完全な設定例は、こちらのGistでご覧いただけます。

インデックスのパフォーマンスへの影響

さまざまなタイプの識別子を使うことの影響は、データ、ハードウェア、ユースケースによって異なります。一般的なガイドラインは提供できますが、ベンチマークを実行して自分のユースケースには正確にどんな影響があるのか判断することが重要です。

最適なインデックスのスループットのためには、Elasticsearchで自動生成された識別子を使用することがいつでも一番効果的な選択肢でしょう。更新チェックが不要なため、インデックスのパフォーマンスは、インデックスやシャードのサイズが拡大するほどには変わりません。ゆえに、可能であればいつでも使用することをおすすめします。

外部ID使用が理由で生じる更新チェックは、余分なディスクアクセスを必要とします。これによる影響は、オペレーティングシステムが必要なデータをどの程度効果的にキャッシュできるか、またストレージの速度や、ランダムな読み取りがどの程度うまく処理されるかによって異なります。インデックスのスピードはまた、インデックスとシャードが拡大しチェックするセグメントが増えるほど低下することもよくあります。

ロールオーバーAPIの使用

従来の時間ベースのインデックスは、特定の設定期間をカバーするインデックス一つひとつに依存しています。つまり、データ量が時間とともに変動する場合は、このインデックスとシャードのサイズがかなり大きく変化するということです。不規則なサイズのシャードは好ましくなく、パフォーマンス上の問題を引き起こします。

ロールオーバーインデックスAPIは、時間だけでなく複数の基準に基づく時間ベースのインデックスを管理する、柔軟な方法を提供するために導入されました。これは、既存のインデックスが一定のサイズ、ドキュメント数/古さに達したときに新しいインデックスにロールオーバーすることを可能にし、シャードとインデックスのサイズがより予測可能になっています。

しかしながらこれによって、イベントのタイムスタンプとそれが属するインデックスとのつながりは絶たれてしまいます。インデックスが厳密に時間を元にしたものであれば、到着がどれだけ遅くなっても、イベントはかならず同じインデックスになります。この考え方が、外部識別子を使った重複防止を可能にしています。ゆえに、ロールオーバーAPIを用いると、重複の確率が低くなったとしても、完全に重複を防ぐことはもう不可能です。 2つの重複したイベントがロールオーバーしたどちらかに到着して、そのため同じタイムスタンプを持っていても別々のインデックスになってしまう可能性があり、これが更新されることにはなりません。

ですから、重複防止が厳密な要件の場合には、ロールオーバーAPIの使用は推奨しません。

予測できないトラフィック量への対策

ロールオーバーAPIを使うことはできなくとも、トラフィック量が上下し時間ベースのインデックスが過剰に小さく、あるいは大きくなってしまった場合に、シャードサイズを適応させ変更する方法がまだあります。

トラフィックの急増などによりシャードが過剰に長くなってしまった場合は、分割インデックスAPIを使用してインデックスを複数のシャードに分けることが可能です。このAPIは、インデックス作成時に適用するよう設定する必要があるので、インデックステンプレートによって追加する必要があります。

反対にトラフィック量が少なすぎて、異常に小さいシャードができてしまった場合は、圧縮インデックスAPIを使ってインデックス内のシャード数を減らすことができます。

まとめ

このブログ記事でご覧になったように、Elasticsearch内での重複を防ぐことは、Elasticsearchにデータをインデックスする前に外部でドキュメントの識別子を特定することで可能になります。識別子のタイプと構造は、インデックス化のパフォーマンスに著しく影響することがあります。ただし、これはユースケースごとに異なるため、自分の特定のシナリオにはどれが最適か、ベンチマークによって見極めることをおすすめします。

ディスク容量の節約:Elasticsearchのインデックスソートに関するあまり知られていないメリット

$
0
0

Elasticsearch 6.0では、インデックスソートという新機能をリリースしました。詳細についてはリンク先のブログをお読みいただければと思いますが、要約すると、ドキュメントをインデックスする際に、キーまたはキーのセットを使用して、指定した順序に並び変えることができます。この機能によって、今までに述べてきたような新しいメリットが実現します。

  • インデックスソートに使用したのと同じキーで並べ替えて結果を返すようにElasticsearchに指示すると、クエリ時の結果の並べ替えが不要になります。すでにソートされているからです。
  • 総ヒット件数が不要でソートキーで並べ替える場合、Elasticsearchでは、リクエストを満たすヒット件数に達した場合にそのクエリは終了します。これにより、クエリパフォーマンスが驚くほど向上します。
  • 異なるフィールドに関してANDを使用してクエリを実行する場合、それらのフィールドはインデックスソートによってグループ化されるため、Elasticsearchは一致しない多数のドキュメントブロックをスキップすることが可能になり、検索も速くなります。

つまり、特に複数のユーザーがドキュメントの検索や並べ替えにいくつかの共通の方法を使用している場合には、インデックスソートによってより迅速に検索できるようになります。 そして、実はこのインデックスソートに関してあまり語られていないメリットがあります。それは、インデックスに使用されているディスク容量の削減も可能になることです。その理由と仕組みについて説明しましょう。

注意:インデックスソートは誰にでも役立つものではない

この機能の仕組みについて話す前に再度確認しておきたいのは、インデックスソートは誰にでも役立つものではないということです。ソートはインデックスを作る際に実行されます。ソートは負荷の高いオペレーションであるため、インデックスする速度が主な懸念事項の場合は、実行前に注意が必要です。書き込みのパフォーマンスが40~50%も低下します。そのためインデックス作成のスループットが主な懸念事項の場合、たとえば大量のロギング、メトリック、セキュリティ分析などのユースケースでは往々にしてそれが問題となりますが、インデックスソートは適していません。 インデックス数が少ない場合やクエリ速度が最も重要なユースケースの場合、またはインデックス付けのオフピーク時に定期的に再インデックスプロセスが実行される場合には便利です。

ソートオーダーの検討:一例

Elasticsearchインスタンス使用して製品検索を行うとしましょう。インデックスを作成する際に、以下のようなドキュメントのセットを持っていると仮定します(見やすくするために表の形式にしています)。

製品ID 製品カテゴリー 製品カラー 価格
206f467b-8cfe シューズ レッド $97.00
4f89fbec-acc3 ジャケット ブラック $120.50
47771396-dfe3 ジャケット グレー $170.10
c6c8fbdf-651b 帽子 イエロー $15.00
dc18c426-0eb3 シューズ レッド $107.20
ee304259-df57 ジャケット ブラック $88.00
9332c0ac-e55e シューズ ブラック $49.00
30e96765-52a1 帽子 ブルー $11.00
811cc8ca-d6bb ジャケット ブルー $92.99

ここで、インデックスソートを有効にしたいとします。何でソートしますか?製品カテゴリー、製品カラー、および/または価格といったいくつかのオプションがあります。ユーザー検索がほぼ常に価格のみでソートされており、カテゴリーやカラーのフィルターがない場合には、ソートキーとして価格で並び変えることが最も有用です。しかし、おそらくユーザーは最安値の商品を見つける前に、少なくともカテゴリーは選択しているでしょう。また、カラーの好みもあるはずです。 カテゴリーの昇順、カラーの昇順、そして価格の昇順でソートしてみましょう。

"sort.field" : ["product_category", "product_color", "price"], "sort.order" : ["asc", "asc", "asc"]

ソートされたインデックスは次のようになります。

製品ID 製品カテゴリー 製品カラー 価格
30e96765-52a1 帽子 ブルー $11.00
c6c8fbdf-651b 帽子 イエロー $15.00
ee304259-df57 ジャケット ブラック $88.00
4f89fbec-acc3 ジャケット ブラック $120.50
811cc8ca-d6bb ジャケット ブルー $92.99
47771396-dfe3 ジャケット グレー $170.10
9332c0ac-e55e シューズ ブラック $49.00
206f467b-8cfe シューズ レッド $97.00
dc18c426-0eb3 シューズ レッド $107.20

興味深いことが見えてきました。例を示しながら説明します。

  • 価格でソートして最安値上位2つのシューズを示すように指示し、すべてのシューズの総ヒット数が不要な場合、ElasticsearchはShoesのブロックを見つける必要があり、その他のすべてのカテゴリーをスキップするので効率的です。そして、結果となる2つが見つかると、残りのインデックスに対する処理を停止し、結果を返します。このように機能させるためには、一致するフィルターがあったとしても、ソートオーダーのすべての要素をインデックスに含める必要があります。
  • Elasticsearchでproduct_category:Jackets AND product_color:Blackと指定すると、HatsのすべてとShoesのすべてがスキップされ、Jacketsの中で「Black」のものが検索され、それが見つかると、他のカラーのすべてがスキップされるので効率的です。
  • Elasticsearchは、見えないところでかなりの圧縮を行っているわけです。この圧縮は繰り返し値がある場合に機能します。最も効率的に機能するのは、繰り返し値がインデックス内でお互いに近い位置にある場合です。「Jackets」のすべてまたは「Color」のすべてがお互いに側にある場合、ディスクに効率的に圧縮されます。これによってディスクスペースが少なくて済むとともに、オペレーティングシステムのファイルシステムキャッシュがより効率化され、動作がさらに迅速になります。

一般的に、ソートオーダーはカーディナリティの高い順番にすることがベストプラクティスです。1行内のできるだけ多くの繰り返し値を利用できるという利点があるからです。

節約できるディスク容量

インデックスソートを有効化することで、どれくらいのディスク容量を節約できるでしょうか。 それは他のさまざまなことと同様、「場合による」ことになります。 その主な要素の1つは、ソートするフィールドのカーディナリティです。これによるディスク容量の節約はかなりの量になります。 先週末、私は個人的なプロジェクトに使用しているIoT/ホームオートメーションのデータの一部を、古いマシンから新しいマシンに移動させることにしました。そのデータの移行にはスナップショット/復元のような迅速な方法がありますが、再インデックスする時間の余裕があったため、インデックスソートによってどれくらいディスク容量が節約できるかを見てみたいと思いました。そこでまず、ソートされていないインデックスとしてリモートに再インデックスを実行しました。

status    index           pri    docs.count    docs.deleted    pri.store.size 
open      devices-2017    1      33310674      0               4.2gb

デバイスは30台より少し多いぐらいで、各デバイスは30秒ごとにステータスを送信、全体のインデックス登録の速度は1秒あたり1ドキュメントです。私はインデックス登録に関して制約を受けることはありません。インデックス登録の速度またはデバイス数を大きく増加させる必要があれば、影響を受けるでしょう。つまり、インデックスソートの利点が得られるケースに該当するようです。 データはハードウェア ID、ハードウェア名、時間、さまざまなセンサー値(温度、特定の時間におけるデバイスのオン/オフ、その他のセンサーレベルなど)で構成されています。インデックスをデバイスIDでソートし、そして時間でソートしたところ、あるデバイスではかなり高い確率で、ほぼ同じ時間に同様または同じ値が見られるらしいことが分かりました。つまり、さらに効率的に圧縮できる可能性があることになります。例えば、スイッチが7:00:00に「オン」の状態になる場合、そのオンになる時間が7:00:30、7:01:00、および少なくとも数分後になる可能性は非常に高く、この場合だと効率的に圧縮できることになります。 ソートされたインデックスの統計によると…

status    index           pri    docs.count     docs.deleted    pri.store.size
open      devices-2017    1      3310674        0               2.5gb

ディスク容量を約40%節約できました!

再び注意

同じデータを40%も少ないディスク容量で格納できることは、誰にとってもありがたいことでしょう。ここで、皆さんにもう一度注意を喚起しなければなりません。要約すると次の2つの内容になります。

  • 節約量は異なります。私は別のデータセットにインデックスソートを使用しましたが、そちらは20%の節約でした。どのフィールドでソートするか、慎重に考えてください。
  • インデックスする速度が遅くなります。インデックスする速度が非常に重要な場合、例えば大量のロギングを実行している、またはメトリックのユースケースなどの場合、短時間でインデックスするにはドキュメント数に影響を受けるため、インデックスソートを実行するのに適していない可能性があります。

インデックスする速度よりもディスク容量のほうがはるかに重要な場合、またはインデックスの容量が少なく、インデックスする速度に制限を受けない場合は、インデックスソートから利点を得られるかどうか確認してみる価値はあるでしょう。

Elasticsearchに切り替えて世界最速スーパーコンピューターのサイバーセキュリティを向上

$
0
0

本記事は最近のElastic{ON} Tourでの事例紹介セッションの要約です。Elastic{ON}のトークはアーカイブで多数公開中です。また、お近くの都市で開催されるElastic{ON} Tourのスケジュールもご覧ください。

世界最速のスーパーコンピューター「サミット」は、米国エネルギー省(DOE) のオークリッジ国立研究所(ORNL)にあります。ORNLの研究者の仕事は演算速度200ペタフロップスの能力に支えられており、このことが物質科学、中性子科学、エネルギー、国家安全保障、高機能演算といった幅広い分野の科学的発見を促進しています。

これらすべての研究で生み出されたデジタル情報を保護するために、ORNLのサイバーセキュリティチームはElasticsearchElastic Stackをセキュリティ情報およびイベント管理(SIEM)に用いています。しかし、最初からそうだったわけではありません。ワシントンでのElastic{ON} Tourで、ORNLのサイバーセキュリティ部門のエンジニアにしてSIEM管理者のLarry Nichols氏は、ORNLが大規模なログ監視と異常検知にわたる約20,000のエンドポイントのセキュリティ管理能力を改善するために、SplunkからElasticsearchへと移行した理由について解説しました。

6年間にわたり、ORNLのサイバーセキュリティチームはSplunkをSIEMに使用していました。しかしORNLのニーズが高まり、ますます大量のデータを投入することや300億件を超えるドキュメントの莫大なインデックスに対してクエリーを実行することが必要になってくると、いくつかの課題に直面して、別のソリューションを追求せざるを得なくなりました。Splunkのライセンスは1日あたりの投入データ量をベースにしており、このために研究所はデータを追加することが制限されていました。スピードも障害となっていました。ORNLの主要目標は研究の促進ですが、Splunkクラスターでは検索に15分もかかることがあり、データ分析から貴重な時間を奪っていたのです。「Splunkによる処理は私たちが望むよりも長く時間がかかり、アナリストはデータ収集を待つ間に自分で分析できるほどでした」(Nichols氏)。

Elasticsearchへの切り替えという決断はORNLにとって有意義なものでした。投入できるデータ量の制限がなくなり、何分もかかっていた検索が数秒に短縮されたのです。「私達には拡張できるハードウェアもリソースもありましたが、データの投入に余分なお金をかけたくなかったので、Elasticは明らかに魅力的でした」とNichols氏は語り、「スピードは明らかに、Elasticsearchの方がはるかに上でした」とも付け加えました。

Elasticsearchで、ORNLはスピードとセキュリティを強化したSIEMを展開することが可能になりました。現在、研究所の実働アーキテクチャでは、25のElsaticsearchのノードが、すべてDocker内で25の仮想マシンにわたって実行されています。このシステムには1日あたり20億以上のドキュメント(データ量約1.5TB)が投入され、180日分のデータ(3千億以上のドキュメント)を10のホットノードと7つのウォームノードにわたり保持しています。3つの機械学習ノード、3つのマスターノード、2つのコーディネーションノードも、合計120TBのディスク容量で実行しています。開発アーキテクチャは保持するログがより少ない(30日分)だけで、ほとんど同じです。ORNLには、研究とテスト専用の3番目のクラスターがあります。日々約1.5TBのデータが投入されるこのクラスターでは、物理サーバーに6つのElasticsearchノードを備えています。最後のクラスターはシングルノードで、他の3つのクラスターの監視に使われています。

Elasticsearchに加えElastic Stackの他の部分によって、セキュリティ上の問題の特定と対処を強化しています。チームはKibanaを使用しており、ユーザーの一般的な使用状況をひと目で確認したり、必要に応じて特定のユーザーに注目したりすることができます。またグラフによって、さまざまなインデックスに基づく関連データを可視化することも可能です。この情報により、1台のマシンの感染が判明した場合には、その問題を食い止め解決するために、感染したデバイスと通信した他のマシンをすばやく特定することができます。さらに最近、チームはCanvasの使用を始めており、ダイナミックなインフォグラフィックスタイルのダッシュボードを作って研究所でのアクティビティに関するハイレベルな画面を管理者層に提供しています。

ORNLがElasticsearchをどのように使用し世界最速のスーパーコンピューター上で検索とセキュリティ管理を強化しているか、さらに詳しくはElastic{ON} TourでのNichols氏のセッション全体をご覧ください

ORNLがElasticsearchをどのように使用し、世界最速のスーパーコンピューター「サミット」の検索およびセキュリティ管理を強化したかをご紹介します。

ElasticsearchとElastic APMでアプリを監視する

$
0
0

APM(アプリケーションパフォーマンス監視)とは?

APMについて説明する場合、ログやインフラメトリックの"監視性"など、別の側面も考えるとよりわかりやすくなります。ログとAPM、インフラメトリックは監視の3大要素です。

3つの領域には重なり合う部分もあり、相互に関連付ける際に役立ちます。ログは、エラーが生じた痕跡を示すかもしれませんが、エラーの理由までは示しません。メトリックはサーバー上でCPU使用量にスパイクがあったことを示すかもしれませんが、何が原因だったかは示しません。しかし、うまく組み合わせて活用すれば、はるかに広い範囲の問題を解決できる可能性があります。

ログ

はじめにいくつかの定義について考えておきましょう。ログとメトリックには、わずかな違いがあります。通常、ログは何かが生じたときに発信されるイベントです。あるリクエストが受信されたとか、反応があったとか、ファイルを開いた、コードでprintfが生じた... といった出来事です。

たとえば、Apache HTTPサーバーのプロジェクトからくるよくあるログ形式はこんな感じです(フェイクデータ、短縮のため一部省略)。

264.242.88.10 - - [22/Jan/2018:07:08:53 -0800] "GET /ESProductDetailView HTTP/1.1" 200 6291
264.242.88.10 - - [22/Jan/2018:07:08:53 -0800] "POST /intro.m4v HTTP/1.1" 404 7352
264.242.88.10 - - [22/Jan/2018:16:38:53 -0800] "POST /checkout/addresses/ HTTP/1.1" 500 5253

ログの情報は、アプリケーションの全体を把握するというより、コンポーネントレベルにとどまる傾向にあります。しかし人間が読む上では便利です。上の例では、IPアドレスと、明らかに設定のないフィールド、日付、ユーザーがアクセスしていたページ(とその方法)、いくつかの数字を確認することができます。私の経験から、一連の数字がレスポンスコード(200はよい、404は良くないが、500よりはマシ)であることと、データが返された量であることがわかります。

ログは通常、対応するアプリケーションやサービスが実行されているホスト/マシン/コンテナーインスタンス上で使用でき、この例のように人間が読める情報であるため、"便利"です。一方でログには、「コードを書いておかなければ、プリントされない」という本質的なデメリットもあります。Rubyでputsを使うか、Javaでsystem.out.printlnするか、あるいは類似の作業が必須です。またプリントする場合も、フォーマットが重要です。前出のApacheログに、見慣れない日付フォーマットが含まれています。たとえば"01/02/2019"という日付を考えてみましょう。米国に住む私にとっては2019年1月2日という意味ですが、世界の多くの仲間はこの日付を2019年2月1日と読みます。ロギングでstatementの形式を決定する際は、こうした点も考慮されることをお勧めします。

メトリック

一方、メトリックは周期的なサマリーやカウントの情報が主です。たとえばこの10秒間に、平均CPUは12%で、アプリケーションが使用したメモリ量は27MB、であるとか、プライマリディスクの容量は71%、といったことです(いま筆者のマシンのメトリックを確認してみました)。

上のスクリーンショットは、あるMacで実行されているiostatです。多くのメトリックがあることがわかります。メトリックは傾向や履歴を示したいときに便利であり、シンプルで予測可能、また信頼できるルールを作成してインシデントや異常を捉える場合に特に役立ちます。メトリックのデメリットとして、インフラレイヤーの監視や、コンポーネントインスタンスレベル(ホスト、コンテナー、ネットワークなど)のデータ捕捉が中心で、カスタムアプリケーションレベルのデータをあまり扱わない点があります。というのも、メトリックは一定の経過時間に対してサンプルされるため、わずかな外れ値が"平均化"されるリスクを伴うためです。

APM

メトリックとログのギャップに橋を架ける存在がアプリケーションパフォーマンス監視です。ログやメトリックは、インフラや複数のコンポーネントを扱う横断的なデータです。APMは特にアプリケーションに注目し、エンドユーザーエクスペリエンスを含むスタック中のアプリ層を、IT部門や開発者が監視できるようサポートします。

監視にAPMを追加するメリットとして、次のような点があります。

  • サービス提供にかかる時間と、クラッシュの原因を把握できる
  • サービスと他の要素の通信状況や、ボトルネックを可視化できる
  • パフォーマンスのボトルネックやエラーの予防的な発見・修正に役立つ
    • 最良のシナリオは、多数のエンドユーザーが影響を受ける前の発見・修正
  • 開発チームの生産性向上をサポート
  • ブラウザー上でエンドユーザーエクスペリエンスを追跡可能

特に注目したいのが、"APMにはコードが通じる"という点です(この後詳しく取り上げます)。

ログとAPMで、得られる情報を比較してみましょう。先ほどこのようなログエントリがありました:

264.242.88.10 - - [22/Jan/2018:07:08:53 -0800] "GET /ESProductDetailView HTTP/1.1" 200 6291

先ほど見た通り、よい内容になっています。レスポンスに成功しており(200)、6,291バイトを返しました。しかし、レスポンスに16.6秒かかったことは示されていません。これは次のAPMスクリーンショットに表示されています。

その他にも豊富なコンテクストが見て取れます。最初のログには、このようなエラーもありました:

264.242.88.10 - - [22/Jan/2018:07:08:53 -0800] "POST /checkout/addresses/ HTTP/1.1" 500 5253

APMが捉えた内容はこうなります:

最終発生日時、発生頻度、アプリケーションで処理されたか否か、という情報が表示されています。たとえばNumberParseExceptionを使って例外処理の詳細を見ると、エラーが発生した回数の分布がウインドウで視覚的に表示されます。

パッと見て、一定の時間に数回起きているということ、一日中発生していることがわかります。ログで見ても、ログファイルの1つに対応するスタックの痕跡が見つかるはずです。しかしAPMのように、そのコンテクストやメタデータまで見つかる可能性は高くありません。

赤い長方形の部分はこの例外処理を実施したコード行を示し、APMが提供するメタデータが問題の正確な内容を伝えています。pythonプログラマーでない筆者のような人間が見てもどういう問題であるか正確に理解でき、チケットをオープンするために必要十分な情報があります。

スクリーンショットで見るAPMオプションツアー

Elastic APMについて一日中語ることもできる筆者ですが(よかったらTwitterで検索してください)、ここではスクリーンショットを使って、もう少し視覚的にご紹介したいと思います。早速ツアーをはじめましょう。

APMを開く

KibanaでAPMアプリケーションを開くと、Elastic APMに搭載されているすべてのサービスが表示されます:

サービスの詳細を見る

個々のサービスについて詳細を見ることができます。今回は"petclinic-spring"サービスを見てみましょう。各サービスとも、レイアウトは似ています:

左上にレスポンスタイムがあります。平均、95パーセンタイル、99パーセンタイルがあり、外れ値の部分を表示しています。さまざまな線グラフのエレメントを表示/非表示にして、外れ値がチャート全体に与える影響をわかりやすくすることもできます。右上はレスポンスコードです。時間に対してRPM(requests per minute/1分あたりリクエスト数)を詳しく表示しています。実際の画面では、各チャートの上でマウスを動かすとポップアップが現れ、特定の時間のサマリーを表示します。最初に得られるインサイトは、データを深堀りせずともすぐにわかります。すなわち、レイテンシの大きなスパイクに、"500"のレスポンス(サーバーエラー)がまったくありません。

トランザクションレスポンスタイムを詳しく見る

引き続きトランザクションサマリーを見ると、下の方にリクエストの詳細があります。各リクエストは、基本的には(さまざまなエージェントAPIを使用して初期設定を拡張可能できる)アプリケーション中の異なるエンドポイントです。リクエストは列見出しで並べ替えできますが、筆者が個人的に好んで使うのは"impact"列です。これは、そのリクエストのレイテンシと出現度を考慮します。今回の事例では、"getOwners"が最も問題を生じさせているように見えますが、それでも平均レイテンシは96ミリ秒に留まっています。このトランザクションを詳細にドロップダウンしていくと、先ほどと同じレイアウトが表示されます。

"ウォーターフォール作戦"

さて、最も遅いリクエストでも、1秒未満にレスポンスしていることがわかりました。下に向かってスクロールしてゆくと、トランザクション中のオペレーションが滝のように表示されています。

クエリ詳細表示

見ると確かに、大量のSELECT文があります。APMでは実行された実際のクエリを表示させることができます。

分散トレーシング

このアプリケーションスタックは、多層化されたマイクロサービスアーキテクチャーを扱っています。すべての層にElastic APMを組み込んであるため、[View full trace]ボタンを押してこのコールに関与する全要素が入るまでズームアウトすることが可能です。こうして、トランザクションに参加したすべてのコンポーネントの分散トレーシングを表示します:

多層的にトレーシングする

今回の事例で最初に見たのは、他の層がコールする"Spring"という層でした。いまこの画面で、"petclinic-node"が"petclinic-spring"層をコールしたことがわかります。これは2つの層でしたが、ブラウザー(React)層からはじまるより多層的な例もあります。

リアルユーザー監視

分散トレーシングの力を最大に引き出すためには、リアルユーザー監視(RUM)も含めて、できる限り多くのコンポーネントやサービスを組み込むことが重要です。サービスレスポンスタイムの早さが、必ずしもブラウザーでのすばやい動作を意味するわけではありません。つまり、ブラウザー上でのエンドユーザーエクスペリエンスを測定することこそが重要です。この事例で、分散トレーシングは4つの異なるサービスが同時に実行されていることを示しています。複数あるサービスの1つが、Webブラウザー(クライアント)です。53ミリ秒の時点でdomはインタラクティブでした。67ミリ秒では、domが完了していることがわかります。

UIにとどまらない魅力

Elastic APMは使いやすいAPM UIに加え、アプリ開発者に必要な機能を豊富にそろえています。そして、追跡データをUIで表示できるだけでなく、一歩深く活用できます。実は、Elastic APMデータは1つのインデックスとなっています。ログやメトリックから、事業データまでの情報が揃うことにより、サーバー遅延が収益に及ぼした影響を把握することも、影響の大きいリクエストを調べるなどして、次のコード拡張の計画策定にAPMデータを役立てることも可能です。

APMはデフォルトの可視化とダッシュボード機能を搭載しており、ログとメトリック、さらに事業データを組み合わせて可視化することができます。

Elastic APMを使いはじめる

Elastic APMは、LogstashやBeatsと似たデプロイトポロジーを使い、組み合わせて実行することができます:

APMサーバーはデータプロセッサーとして振る舞い、APMデータをAPMエージェントからElasticsearchに転送します。インストール手順もシンプルです。ドキュメントの"install and run"ページを参照いただくか、Kibanaで"K"ロゴをクリックしてホーム画面を表示し、"Add APM"オプションをクリックしてはじめることができます:

画面の案内にしたがって進むだけで、APMサーバーを稼働させることができます:

設定が完了したら、搭載させる各エージェントタイプについてKibanaのチュートリアルを参照することができます:

わずか数行のコードで、すべての設定が完了します。

Elastic APMの入口

新しいことを学ぶには、実際に手を動かしてみるのが一番です。また、その方法も1つではありません。実際のインターフェースをライブで、リアルに見てみたいという方はこちらのAPMデモ環境をクリックしてご覧ください。ローカルで実行してみたいという方は、APMサーバーダウンロードページの手順に沿って進めていただくことができます。

最も手軽な方法は、Elastic CloudElasticsearch Serviceです。APMサーバー6.6、Kibanaインスタンス、機械学習ノードを含むすべてのElasticsearchデプロイが、SaaSで提供されており、1分ほどで使いはじめることができます(全サービスを2週間の無料トライアルでお試しいただけます)。クラウドサービスのため、デプロイインフラの保守/管理を行わなくて済むという大きなメリットがあります。

Elasticsearch ServiceでAPMを有効化する

APMクラスターを作成する(または既存のクラスターにAPMを追加する)には、クラスター設定の画面でAPM設定のセクションが表示されるまで下にスクロールします。既存のデプロイをアップデートする場合は[Enable]、[Save changes]の順にクリック、新規デプロイの場合は[Create deployment]をクリックします。

ライセンス

ElasticのAPMサーバーと、全APMエージェントはオープンソースとして提供されています。洗練されたAPM UIはElastic Stackでデフォルトの配布、また無料のベーシックライセンスより使用可能です。アラートや機械学習と統合する場合はベースとなるオプションのライセンスが必要になり、アラートにはゴールド、機械学習にはプラチナをご購入いただく必要があります。

まとめ

APMは、アプリケーションのあらゆる層で起きていることを表示します。機械学習やアラートと統合できるElastic APMなら検索機能を最大に活用でき、アプリケーションインフラの可視性が大きく向上します。トランザクションから痕跡、エラー、例外処理まで可視化でき、洗練されたAPMユーザーインターフェースがコンテクストも表示します。問題が発生していないときも、Elastic APMのデータを参考に修正内容の優先順位付けを行って、アプリケーションパフォーマンスの最大化と、ボトルネックの排除に取り組むことができます。

Elastic APMと監視に関するウェビナーも複数あります。併せてぜひご覧ください。

はじめてみませんか? APMに関するトピックはディスカッションフォーラムでもご覧いただけます。チケットの送信や機能のリクエストは、APM GitHub reposにお寄せください。

複数のデータ・センターにおける Elasticsearch クラスター間のレプリケーション

$
0
0

データセンター間のレプリケーションは、Elasticsearch のミッション・クリティカルな用途では、しばらくの間は要件となってきましたが、以前は他のテクノロジーによって部分的に解決されていました。Elasticsearch 6.7 でのクロス・クラスター・レプリケーションの導入により、データ・センター、地理的にも、または Elasticsearch クラスター全体にわたって、情報をレプリケートするための追加のテクノロジーは不要になります。

クラスター横断複製 (CCR) は、1つの Elasticsearch クラスターから1つ以上の Elasticsearch クラスターへの特定のインデックスのレプリケーションを可能にします。データの局所性を含む複数のレプリケーション(ユーザー/アプリケーション・サーバへの近い場所にデータをレプリケートする、製品カタログのレプリケーションを、20個の異なるデータセンターに複製するなど) に加えて、CCR にはさまざまな使用例(本社のクラスターへの1,000の銀行の支店から報告を目的としてレプリケーションするなど)があります。

このチュートリアルでは、CCR を使用したデータセンター間のレプリケーションについて、私たちは CCR の基本を簡単に紹介し、アーキテクチャオプションとトレードオフを強調し、データセンターを使用しない展開のサンプルを構成して、管理コマンドを強調します。CCR の技術概要については、「リーダーをフォローする: Elasticsearch でのクラスター間レプリケーションの概要」を参照してください。

CCR は、プラチナレベルの機能であり、試用版の API を通じて有効にするか、または Kibana から直接有効化できる30日間の試用ライセンスを使用できます。

クロスクラスターレプリケーション (CCR) の基本事項

レプリケーションはインデックス・レベル (またはインデックスパターンに基づいて)で構成される

CCR は Elasticsearch のインデックスレベルで構成されます。レプリケーションをインデックスレベルで構成することにより、一部のインデックスを一方向にレプリケートする、他のインデックスを別の方向に複製する、複数のデータセンターアーキテクチャなど、レプリケーションに関する多数の戦略を利用できます。

レプリケートされたインデックスは読み取り専用である

インデックスは、1つ以上の Elasticsearch クラスターによって複製できます。インデックスをレプリケートしている各クラスターは、インデックスの読み取り専用コピーを保持しています。アクティブなインデックス書き込みを受信できるのはリーダーといいます。そのインデックスのパッシブな読み取り専用コピーは、フォロワーと呼ばれます。新しいリーダーには選挙の概念はなく、リーダーインデックスが使用できない場合 (クラスターやデータセンターの停止など)、別のインデックスは、アプリケーションまたはクラスターアドミニストレーター (多くの場合別のクラスターでも可) によって書き込みが行われるよう明示的に選択する必要があります。

CCR の既定値は、多種多様な高スループットの用途で選択可能

値を調整することがシステムに与える影響を完全に理解していない限り、既定値を変更することはお勧めしません。 ほとんどのオプションは、"max_read_request_operation_count""max_retry_delay" などのフォロワーの作成 API にあります。すぐに、独自の作業負荷に合わせて、これらのパラメーターを調整するための情報を今後公開します。

セキュリティ要件

CCR 入門ガイドで説明しているように、ソース・クラスターのユーザーは、"read_ccr" クラスター特権、"監視"、および "読み取り" インデックスの特権を持っている必要があります。ターゲット・クラスター内では、「manage_ccr」クラスタ権限、「monitor」、「read」、「write」、「manage_follow_index」インデックスの権限が必要です。LDAP などの集中認証システムも使用できます。

複数データセンター CCR アーキテクチャの例

本番および DR データセンター

Screen Shot 2019-04-04 at 10.21.55 AM.png

データはプロダクションデータセンターから DR データセンターにレプリケートされます。プロダクション・データ・センターが利用できない場合は、DR (災害復旧) データセンターを使用できます。

2つ以上のデータセンター

Screen Shot 2019-04-04 at 10.22.09 AM.png


データは、datacenter A から複数のデータセンター (ダイアグラムの B と C) にレプリケートされます。データセンター B および C には、データセンター a 内のインデックスの読み取り専用コピーが現在保存されています。

チェーンレプリケーション

Screen Shot 2019-04-04 at 10.22.19 AM.png

また、複数のデータセンターにまたがるレプリケーションをチェーン化することもできます。この例では、リーダーインデックスはデータセンター a に含まれています。データのレプリケート先はデータセンター A からデータセンターB に複製され、データセンター C は データセンター B のフォロワーから複製し、チェーンレプリケーションのパターンを作成します。

双方向のレプリケーション

Screen Shot 2019-04-04 at 10.22.30 AM.png

レプリケーションはインデックスレベルで構成されるため、リーダーインデックスはデータセンターごとに維持できます。アプリケーションは、各データセンター内のローカルインデックスに書き込み、すべての情報をグローバルに表示するために複数のインデックスにわたって読み取られます。

データセンター間の導入に関するチュートリアル

1. セットアップ

このチュートリアルでは2つのクラスターを使用し、両方のクラスターはローカルコンピューター上にあります。どのような場所にいても、クラスターは自由に検索できます。

  • 「us-cluster」: これは当社の「米国のクラスター」であり、ポート9200でローカルに実行します。ドキュメントは米国のクラスターから日本のクラスターに複製されます。
  • 「japan-cluster」: 当社の「日本のクラスター」である、ポート8200でローカルに実行します。日本のクラスターでは、米国のクラスターからレプリケートされたインデックスを維持します。

Screen Shot 2019-04-04 at 10.22.44 AM.png

2. リモートクラスターの定義

CCR を設定する場合、Elasticsearch クラスターは他の Elasticsearch クラスターを認識している必要があります。これは単一方向の要件であり、ターゲットクラスターはソースクラスターに対する単一方向の接続を維持します。他の Elasticsearch クラスターをリモートクラスターとして定義し、それらを説明するエイリアスを指定します。

日本のクラスターにおける「us-cluster」の認識を確保したいと思います。CCR でのレプリケーションはプルベースであるため、「us-cluster」から「japan-cluster」への接続を指定する必要はありません。

「japan-cluster」の API 呼び出しで 「us-cluster」 を定義します。

# From the japan-cluster, we’ll define how the us-cluster can be accessed
PUT /_cluster/settings
{
  "persistent" : {
    "cluster" : {
      "remote" : {
        "us-cluster" : {
          "seeds" : [
            "127.0.0.1:9300"
          ]
        }
      }
    }
  }
}

(APIベースのコマンドについては Kibana 内で Dev tools コンソールを使用することをおすすめしますが、これは Kibana-> Dev tools-> Console) から入手できます。

API の呼び出しでは、"127.0.0.1: 9300" でエイリアス "us-cluster" を持つリモートクラスターにアクセスできます。1つ以上のシードを指定できますが、ハンドシェイクフェーズ中にシードが使用できない場合には、一般に複数を指定することをお勧めします。

リモートクラスターの構成の詳細については、リファレンスドキュメントを参照してください。

また、「us-cluster」と接続するためにポート9300に注意しても重要なのは、elasticsearch がポート9200で HTTP プロトコルを耳にしていることです (これはデフォルトであり、「us-cluster」の yml ファイルで指定されています)。ただし、レプリケーションは、Elasticsearch のトランスポートプロトコル (ノード間通信のため) を使用して行われます。デフォルトはポート9300です。

Kibana 内では、リモートクラスターの管理 UI があり、このチュートリアルでは、ui と CCR の API を順を追って説明します。Kibana のリモートクラスター UI にアクセスするには、左側のナビゲーション・パネルで [管理] (歯車アイコン) をクリックし、Elasticsearch のセクションで「リモート・クラスター」に移動します。

Screen Shot 2019-03-27 at 2.17.24 PM.pngKibanaの Elasticsearch Remote Cluster Management UI


3. レプリケーションに使用するインデックスを作成する

「products」と呼ばれるインデックスを「us-cluster」に作成し、このインデックスをソース「 us-cluster」から「japan-cluster」に複製します:

"us-cluster" で、次のようになります。

# Create product index
PUT /products
{
  "settings" : {
    "index" : {
      "number_of_shards" : 1,
      "number_of_replicas" : 0,
      "soft_deletes" : {
        "enabled" : true      
      }
    }
  },
  "mappings" : {
    "_doc" : {
      "properties" : {
        "name" : {
          "type" : "keyword"
        }
      }
    }
  }
}

"soft_deletes" の設定にお気づきかもしれません。CCR のリーダーインデックスとして機能するインデックスには、論理削除が必要です (ご存知ない方はこちらを参照してください)。

soft_deletes: 論理削除は、既存のドキュメントが削除または更新されたときに発生します。これらの論理削除を構成可能な制限まで保持することで、工程の履歴をリーダーシャードに保持し、工程の履歴を再現することでフォロワーシャードの作業に使用できるようになります。

フォロワーシャードがリーダーから操作を複製すると、リーダーシャードにマーカーが残され、リーダーのフォロワーの位置がわかるようになります。これらのマーカーの下にあるソフト削除された操作は、破棄対象となります。これらのマーカーの上にあるリーダーシャードは、シャード履歴保持リースの期間 (デフォルトは12時間) これらの操作を保持します。この期間により、致命的が遅れてリーダーから再ブートストラップされるリスクが生じる前にフォロワーをオフラインにできる期間が決定されます。

4. レプリケーションの開始

リモートクラスターのエイリアスを作成し、レプリケートするインデックスを作成したので、次にレプリケーションを開始しましょう。

「japan-cluster」において:

PUT /products-copy/_ccr/follow
{
  "remote_cluster" : "us-cluster",
  "leader_index" : "products"
}

このエンドポイントには ' product-copy ' が含まれていますが、これは "japan-cluster ' クラスター内の複製さインデックスの名前です。前に定義した ' us-cluster ' クラスターからレプリケートしていますが、レプリケートしようとしているインデックスの名前は、' us-cluster ' クラスター上の ' product ' と呼ばれています。

重要なのは、レプリケートされたインデックスが読み取り専用であり、書き込み操作を受け付けることができないという点です。

これでElasticsearch クラスター間で複製を行うインデックスを構成しました!

Screen Shot 2019-03-27 at 2.18.37 PM.png

KibanaのCCR Management UI


インデックス・パターンのレプリケーションの開始

お気づきかもしれませんが、上記の例は時間ベースの使用法には十分なものではなく、日次インデックス、または大量データに関しては正しく動作しません。また、CCR API には、複製するパターンを自動で指定するパターン、つまり、レプリケートする必要があるインデックスものを定義するメソッドも含まれています。

CCR API を使用して、自動フォローパターンを定義できます

PUT /_ccr/auto_follow/beats
{
  "remote_cluster" : "us-cluster",
  "leader_index_patterns" :
  [
    "metricbeat-*",
    "packetbeat-*"
  ],
  "follow_index_pattern" : "{{leader_index}}-copy"
}

上記のサンプル API 呼び出しは、'metricbeat' または 'packetbeat' で始まるインデックスを複製します。

また、Kibana で CCR UI を使用して、自動フォローパターンを定義することもできます。

Screen Shot 2019-03-27 at 2.20.07 PM.png

Kibanaのauto-follow patternsのためのCCR Management UI

5. レプリケーションのセットアップのテスト

「us-cluster」から「japan-cluster」に製品を複製したので、今度はテスト用の文書を挿入し、それが複製されたことを確認してみましょう。

"us-cluster" クラスター上:

POST /products/_doc
{
  "name" : "My cool new product"
}

次に、「日本のクラスター」クエリして、ドキュメントが確実に複製されているか確認しましょう:

GET /products-copy/_search

1つのドキュメントが存在し、「us-cluster」に書き込まれて、「japan-cluster」に複製されるはずです。

{
  "took" : 1,
  "timed_out" : false,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : 1,
    "max_score" : 1.0,
    "hits" : [
      {
        "_index" : "products-copy",
        "_type" : "_doc",
        "_id" : "qfkl6WkBbYfxqoLJq-ss",
        "_score" : 1.0,
        "_source" : {
          "name" : "My cool new product"
        }
      }
    ]
  }
}

データセンター間管理に関する注意事項

CCR の管理上の API、チューニング可能な設定、およびレプリケートされたインデックスを通常のインデックスに変換する方法の概要について見てみましょう。

レプリケーションの管理 API群

CCR では、Elasticsearch に、便利な管理用 API がいくつかあります。これらは、レプリケーションのデバッグ、レプリケーション設定の変更、詳細診断の収集などに役立つ場合があります。

# Return all statistics related to CCR
GET /_ccr/stats
# Pause replication for a given index
POST /<follower_index>/_ccr/pause_follow
# Resume replication, in most cases after it has been paused
POST /<follower_index>/_ccr/resume_follow
{
}
# Unfollow an index (stopping replication for the destination index), which first requires replication to be paused 
POST /<follower_index>/_ccr/unfollow
# Statistics for a following index
GET /<index>/_ccr/stats
# Remove an auto-follow pattern
DELETE /_ccr/auto_follow/<auto_follow_pattern_name>
# View all auto-follow patterns, or get an auto-follow pattern by name
GET /_ccr/auto_follow/
GET /_ccr/auto_follow/<auto_follow_pattern_name>

CCR 管理 APIs の詳細については、Elasticsearch のリファレンスドキュメントを参照してください。

フォロワーインデックスを通常のインデックスに変換する

上記の管理 API群 の一部を使用して、フォロワーインデックスを Elasticsearch の通常のインデックスに変換し、書き込みを受け入れることができます。

上記の例では、かなり単純な設定がありました。日本クラスターにおける複製された「products-copy」インデックスは読み取り専用であるため、書き込みを受け付けることができないことに注意してください。「products-copy」インデックスを通常のインデックスに変換したい場合は Elasticsearch (書き込みを受け入れることが可能) であれば、次のコマンドを実行できます。当社の元のインデックス (「products」) への書き込みは継続できるうえ、「products-copy」のインデックスを通常の Elasticsearch ・インデックスに変換する前に、「products」インデックスへの書き込みを制限しておくことを留意してください。
# Pause replication
POST /<follower_index>/_ccr/pause_follow
# Close the index
POST /my_index/_close
# Unfollow
POST /<follower_index>/_ccr/unfollow
# Open the index
POST /my_index/_open

Elasticsearch の CCR (クロスクラスターレプリケーション) を引き続き探索する

このガイドは Elasticsearch での CCR の使用を開始するお手伝いをするために作成されたものですが、CCR を十分に理解していただき、CCR のさまざまな APIs (Kibana で使用できる UI を含む) について学習し、この機能を試していただければうれしいです。その他のリソースとしては、「クロスクラスターレプリケーションの概要」および「クロスクラスターレプリケーション API ガイド」を参照してください。

ディスカッションフォーラムにご意見やご感想をお寄せください。すべての質問については、できるだけ早く回答するように心がけています。

Elastic Stack 7.0.0 リリース

$
0
0
7.0が出ました!このリリースでは861名のコミッターからの1万以上のプルリクエストが含まれています。 まず最初に、コミュニティならびに従業員に感謝いたします。 本リリースに関する情報を聞きたい方は、[ライブバーチャルイベント][1]を太平洋夏時間の2019年4月25日の午前8時に開催いたしますので、ぜひご参加ください。7.0のデモまた、ElasticのエンジニアによるAMA(Ask Me Anything)も行う予定です。また、日本でもライブウェビナーを4月23日に開催する予定です。[日本のウェビナーの詳細はこちらのページ](https://events.elastic.co/2019-04-23-releasewebinar-tokyo)をご覧ください。 Elastic Stack 7.0はすでに利用可能です。[ダウンロード](/downloads)したり、Elastic Cloudの[Elasticsearch Service](/cloud/elasticsearch-service)(新機能を提供する唯一のマネージドElasticsearchのサービス)でいますぐお試しください。 7.0では様々な機能がリリースされており、どこから始めれば良いか迷うかもしれません。いくつかを簡単にご紹介いたします。 ### Kibana 7.0: 新デザイン & ナビゲーション。そしてダークモード! Kibana7.0のデザインでは、よりコンテンツにフォーカスしてもらうように、UI は全体として明るく、最小限の構成になりました。最も目を引く変更内容は、新しいグローバルナビゲーションの導入です。Kibana スペースの切り替え、階層リンクの表示、パスワードの変更やログアウトなどのユーザー操作の開始を行うための固定ヘッダーを導入しています。また、この実現と一貫性を保つために、Elastic UI Frameworkを作成しました。ここ1年の間に、これらのコンポーネントを使用するために Kibana のほとんどを書き換えました。これらのコンポーネントを使用して、設計チームと技術部門の徹底的な努力により、スタイルやスタイルシートがどのように適用されるかについても大幅に簡略化しました。 一貫性とスタイルシートが強化されたことで、Kibana 履歴の中で最も大きな機能の要求の1つであるKibana全体のダークモードを利用できるようになっています。これらの変更のもう1つの利点として、Kibana のダッシュボードはレスポンシブデザインになったため、モバイルデバイスでの利便性を飛躍的に向上させる第一歩です。 ![enter image description here][2] ### 新世代Elasticsearchクラスターコーディネーション 開発当初からElasticsearch を使いやすくし、壊滅的な障害に復旧できるようにすることに注力してきました。このような要件をサポートするために、個々のノードのスケーラビリティと信頼性を高めることから、Zen discoveryと呼ばれるクラスターの調整レイヤーを継続的に改善するということまで、複数のアプローチを行ってきました。7.0 では、両方の分野で、さらに大きな改善点が発表されています。 **Zen2はElasticsearchのための完全に新しいクラスター調整レイヤーです**。高速、安全、使いやすさを備えています。これを達成するために、私達は設計を検証するために[形式モデル][3]を使用して私達の新しい分散合意アルゴリズムの[理論的正当性][4]に焦点を合わせることから始めました。 Paxos、Raft、Zab、Viewstamped Replication(VR)などのよく知られたコンセンサスアルゴリズムがありますが、Elasticsearchクラスターの要求には、クラスター変更のためのより高いスループット、クラスターの容易な拡大または縮小のサポート、およびシームレスローリングアップグレード戦略が必要で、これらの参照アルゴリズムでは提供できなかった機能がいくつかありました。Zen2には、人的ミスの可能性を減らし、壊滅的な障害から回復する際のより明確な選択を提供するいくつかの変更も含まれています。 特にそのような中心的な要素において、信頼性、パフォーマンス、およびユーザーエクスペリエンスを一度に向上させることは容易ではありません。 私たちはZen2、そしてここに到達するために私たちが引き受けたプロセスを誇りに思っています。 Zen2の詳細については、[こちらのブログ][5]を読んでください。 回復性を考慮して、Elasticsearch 内の個々のノードを作成してます。ノードに送信する要求が多すぎる場合、または要求が大きすぎる場合、ノードはプッシュバックします。この処理を、Elasticsearch のサーキットブレーカーで実現し、特定の要求を扱うことができないノードで、場合によっては、クライアントに再試行を要求します (その場合は別のノードで応答するなど)。より小さな JVM ヒープサイズを持つノードの場合、ユーザーが大規模なマルチテナントクラスターではなく、そのようなクラスター単位のモデルに移動するほど一般的になり、これはさらに重要になります。 7.0では、サービス不能なリクエストをより正確に検出し、それらが個々のノードを不安定にするのを防ぐための**リアルメモリサーキットブレーカ**を導入しました。 この変更によってノードおよびクラスタ全体の信頼性がどのように向上するかについての詳細は[こちらのブログ] [6]を読んでください。 ### ユース・ケース全体にわたる関連度と速度の向上 関連度と検索の速度は優れた検索エクスペリエンスの要です。および Elasticsearch 7.0 は、両方を向上させる基本的な機能をいくつか導入しています。 - **上位kクエリの高速化**: 多くの検索ユースケースでは、クエリで上位k(20件など)の結果をすばやく表示することは、正確なヒット数(つまり、クエリに一致する結果の総数)よりもはるかに重要です。 たとえば、電子商取引のWebサイトで誰かが商品を検索している場合、検索クエリに一致した他の120,897件の結果ではなく、最も関連性の高い10件の結果に関心があります。 Elasticsearch 7.0(およびLucene 8.0)[新しいアルゴリズム(Block-Max WAND)を実装しています][7]。これは、トップヒットを取得するときに大幅な速度向上をもたらします。 - **Intervalクエリ:** 法律や特許の検索のようなユースケースでは、単語やフレーズが互いに一定の距離内にあるレコードを検索する必要が生じることがあります。 Elasticsearch 7.0のIntervalクエリは、そのようなクエリを構築するためのまったく新しい方法を導入しており、以前の方法(スパンクエリ)と比べて使用および定義が非常に簡単です。Intervalクエリはまた、スパンクエリと比較してエッジケースに対してはるかに回復力があります。 - **Function score 2.0:** カスタムスコアは、関連性と結果のランク付けをより細かく制御したい、高度な検索のユースケースの基本です。 Elasticsearchは、初期の頃からこれを実行する機能を提供してきました。 7.0では、レコードごとにランク付けスコアを生成するための、よりシンプルでモジュール式、そしてより柔軟な方法を提供する、次世代の関数スコア機能が導入されています。新しいモジュール構造により、ユーザーは一連の算術関数と距離関数を組み合わせて任意の関数のスコア計算を構築し、結果のスコア付けとランク付けをより詳細に制御できます。 ### 地理タイルでElastic Mapsをスムーズに拡大 長年にわたり、[ジオサポートがElasticsearchに最初に追加された][8]、[Bkd-Treeデータ構造][9]をLuceneに導入してそれを使用するまで、ジオデータのサポートは継続的に向上しています。 Kibanaのグローバルベースマップを強化するElastic Mapsサービスにより、ジオシェイプクエリのパフォーマンスが25倍以上向上しました。 7.0では、この改善を継続し、ユーザーが結果データの形状を変更することなく地図上でズームインおよびズームアウトできるように(ジオ)地図タイルを処理するためのElasticsearchの新しい集計を導入します。新しいgeotile_grid アグリゲーションでは、geo_pointsをグリッド内のセルを表すバケットにグループ化し、各セルをマップ内のタイルと関連付けます。この変更の前は、長方形のタイルは異なるズームレベルで向きが変わるため、ズームレベルの変更に伴ってシェイプのフリンジがわずかに変わる可能性がありました。拡大縮小してもビューが安定していることを確認するために、7.0のElastic Mapsはすでにこの新しい集計を使用しています。攻撃者からネットワークを保護したり、特定の場所でアプリケーションの応答が遅い時間を調べたり、[tracking your brother hiking the Pacific Crest Trail][10]など、このレベルの精度は重要です。 ### ナノ秒の精度サポートによる時系列ユースケースの強化 インフラストラクチャメトリクス、システム監査ログ、ネットワークトラフィック、火星の移動局など、Elastic Stackを使用するの多くがデータシリーズデータを扱っています。複数のシステムやサービスにわたって、イベントの正確な順序付けと関連付けを行うことが重要です。 これまで、Elasticsearchはミリ秒単位でのみタイムスタンプを格納していました。 7.0では数桁のゼロが追加されてナノ秒の精度が扱えます。高頻度のデータ収集を必要とするユーザーは、このデータを正確に格納してシーケンス処理するために必要な精度を持つことができます。 [1]: http://www.elastic.co/live/v7 [2]: /jphttps://www.elastic.co/assets/blt932dc11f09e989cc/dark-mode.gif [3]: https://www.elastic.co/elasticon/conf/2018/sf/reliable-by-design-applying-formal-methods-to-distributed-systems [4]: https://www.elastic.co/elasticon/conf/2018/sf/reliable-by-design-applying-formal-methods-to-distributed-systems [5]: https://www.elastic.co/blog/a-new-era-for-cluster-coordination-in-elasticsearch [6]: https://www.elastic.co/blog/improving-node-resiliency-with-the-real-memory-circuit-breaker [7]: https://www.elastic.co/blog/faster-retrieval-of-top-hits-in-elasticsearch-with-block-max-wand [8]: https://www.elastic.co/blog/geo-location-and-search [9]: https://www.elastic.co/blog/lucene-points-6.0 [10]: https://www.elastic.co/blog/hiking-the-pacific-crest-trail-with-the-elastic-stack

Elastic APMからLogstashまたはKafkaを通してデータを送信するには

$
0
0
今日のデプロイでは、アプリケーションサーバーの寿命が短いことや、アプリケーションサーバーがメッセージキューやデータベースなどのような他のコンポーネントよりも信頼性の低いハードウェア(プリエンプティブあるいは低優先度のVM、スポットインスタンス)を使用していることがよくあります。そのようなケースでは、より信頼性の高いシステムに早くデータを移すのがベストです。 リリース6.4.0から、APMサーバーはLogstashまたはKafkaにデータを送信し、信頼性の要件をこうしたシステムの一つに分散することができるようになります。また、Logstashを使用すると、多くの利用可能なLogstashプラグインの1つを使って、APMデータを強化することもできます。 ここで、データをElasticsearchに投入する前に別システムを通してデータを送信する場合の設定を紹介し、注意点をいくつか見ていきましょう。 1. [Elasticsearchへの出力にLogstashを設定する](#configure-logstash) 1. [Elastic APMサーバーをLogstashに送信するよう設定する](#configure-apm-server) 1. [Elasticsearchを設定する](#configure-elasticsearch) 1. [オプションとしてソースマップを含める](#configure-source-maps) 1. [Kafkaを導入する](#introduce-kafka) ## Logstashの設定 まず、パイプラインを追加して、beats/lumberjackプロトコルを使用してLogstashがAPMサーバーからイベントを受け取るよう設定し、次にそれをElasticsearchに送信します。 ```prettyprint input { beats { id => "apm-server" port => 5044 } } output { elasticsearch { hosts => ["elasticsearch:9200"] index => "apm-%{[beat][version]}-%{[processor][event]}-%{+YYYY.MM.dd}" } } ``` 1日につきトランザクションやスパンなどの1イベントタイプごとにインデックスが1件作成されます。これは、デフォルトのAPMサーバー設定が生成するときと同様です。 ソースマップでここにちょっとおかしな部分ができてきますが、後でこの記事内で修正します。 注意深く見ている人は、beatへのリファレンスは何をするものだろうと思うことでしょう。 APMサーバーは[Beats Framework](/jp/products/beats)上に構築されており、従って同じメタデータがイベント内で引数を渡します。 つまり、別のBeatデータと同じLogstashインスタンス内のAPMデータ処理は、`[@metadata][beat] == "apm-server"`という条件文を使用して行われるということです。 ## APMサーバーの設定 これでLogstashが設定できたので、APMサーバーの`apm-server.yml`をアップデートして、イベントをそれに応じて出力できるようにします。 ```prettyprint output.elasticsearch: enabled: false output.logstash enabled: true hosts: ["logstash:5044"] ``` backoff、proxy、ssl設定などの追加オプションについては、[Elastic APMサーバードキュメント](/guide/en/apm/server/6.4/logstash-output.html)で詳しく説明しています。 APMサーバーで監視を有効にしている場合は、必ず次のように設定します。 ```prettyprint xpack.monitoring.elasticsearch: enabled: true hosts: ["elasticsearch:9200"] ``` これで、APMサーバー自体の監視がElasticsearchに直接フローし続けるようになります。 ## Elasticsearchの設定 APMサーバーをスタートする準備ができるまで、あと1ステップです。 Elasticsearchはまず、APM UIが期待するとおりにAPMデータを格納する方法を知る必要があります。つまり、インデックスのテンプレートが必要だということです。 このテンプレートを読み込む方法は2通りあります。 ElasticsearchでAPMサーバーを一時的に指定することが可能なら、次のようにします。 ```prettyprint apm-server setup --template ``` それ以外の場合は、まずAPMサーバーからテンプレートをエクスポートします。 ```prettyprint apm-server export template > apm-6.4.2.tmpl.json ``` それからElasticsearchに読み込みます。 curlを使って、次のようにします。 ```prettyprint curl -XPUT -H 'Content-Type: application/json' http://elasticsearch:9200/_template/apm-6.4.2 -d @apm-6.4.2.tmpl.json ``` 次のコマンドは、各操作が成功したか失敗したかをレポートします。 テンプレートが正常に読み込まれたか確認するには、 _template/apm-* をクエリします。 そうすると、次のようなドキュメントのセットが返されます。 ```prettyprint { "apm-6.4.2": { "order":1, "index_patterns": [ "apm-6.4.2-*" ], ... ``` インデックスパターンが、前のLogstashのステップで設定したものと合っていることに注意してください。 さらに、そこにバージョン情報が含まれていることにも注意してください。つまり、この設定ステップは次のようになるということです。 1.Logstashに接続しているAPMサーバーとまったく同じバージョンで行われる。 1.毎回APMサーバーのアップグレード中に繰り返される。 ## 使ってみる APMサーバーを起動して、アプリケーションの動作を分析していきましょう。 ## ソースマップ [ソースマップ](/guide/en/apm/server/6.4/sourcemaps.html)は、分かりにくいコードを元のソースに戻すマッピングのために使用されます。 一番良く見かけるのは、縮小されたJavascriptを戻すときに使われるものです。 ソースマップは、APMサーバーの出力がElasticsearchではない場合、特別な考慮が必要です。 結果的にElasticsearchにどう届くかにかかわらず、APMサーバーがこれを使うためにそこに格納されなければなりません。 ソースマッピングのストレージ設定は、`rum.source_mapping.elasticsearch`を次のようにセットします。 ```prettyprint apm-server: rum: source_mapping: elasticsearch: hosts: ["elasticsearch:9200"] index_pattern: "apm-*-sourcemap*" ``` これは、APMサーバーに、`apm-*-sourcemap*`にマッチしたインデックスでソースマップを探すように指示しています。 ソースマップはLogstashによってアップロードすることができますが、デプロイメントプロセスの間に直接Elasticsearchに送信して、マッピングの到着が必要なイベントが起こる前に確実に格納することをおすすめします。 それができない場合は、この記事で紹介したLogstashの設定が、適用するタイミングでソースマップ取得に使用されるデフォルトのインデックスパターンに適しているので、さらに変更を加える必要はありません。 ## フローにKafkaを導入する Kafkaもまた、APMサーバーからElasticsearchに送るイベント出力をバッファするときに使えます。 Kafkaを使った簡単なAPMサーバーの設定は次のとおりです。 ```prettyprint output.kafka: enabled: true hosts: ["kafka:9092"] topics: - default: 'apm' topic: 'apm-%{[context.service.name]}' ``` ここでは1サービスに1トピックの使用をお見せしていますが、必須ではありません。 ドキュメントには、他の構成オプションも記載されています。 イベントがKafkaにフローすれば、これをElasticsearchにプルできるようLogstashを設定することができます。 たとえば以下のようにします。 ```prettyprint input { kafka { id => "apm-server-kafka" bootstrap_servers => ["kafka:9092"] topics_pattern => "apm.*" codec => "json" } } output { elasticsearch { hosts => ["elasticsearch:9200"] index => "apm-%{[beat][version]}-%{[processor][event]}-%{+YYYY.MM.dd}" } } ``` ここでも、1日につきトランザクションやスパンなどの1イベントタイプごとにインデックスが1件作成されます。これは、デフォルトのAPMサーバー設定が生成するときと同様です。 Logstash Kafka出力プラグインのその他の方法は、[ドキュメント](/guide/en/logstash/6.4/plugins-inputs-kafka.html)で紹介しています。 ## Give it a try APMサーバーには、LogstashやKafkaを使用したAPMデータ送信に対する柔軟性があります。 ぜひお試しになり、[ディスカッションフォーラム](https://discuss.elastic.co/c/apm)にご意見をお寄せください。 皆さんのアイデアも、いつでも歓迎しています。どうぞ自由に[ソースコード](https://github.com/elastic/apm-server)をご覧になり、問題を報告したりリクエストしたりしてください。

Canvas:メトリック要素とマークダウン要素

$
0
0

KibanaでCanvasの要素を使用してみる

Canvasは現在、workpad(ブログ「KibanaでCanvasを使い始める」を参照)に追加できる約20の組み込みの要素を提供しています。このブログでは、そのうちの2つ、メトリックとマークダウンのみをご紹介します。

メトリック:

1つのデータ値とラベルを表示する簡素化されたテキストボックス

blog01.3.png

マークダウン:

handlebars.js {{variables}}およびマークダウン構文を使用して動的なデータを表示する、フル機能のテキストボックス

注:すでにCanvasを所有しており、サンプルデータがインストールされている場合は、レビューセクションをスキップしてチュートリアル本文(メトリックの使用)に進んでください

クイックレビュー

まだ「KibanaでCanvasを使い始める」ブログを読んでいない場合は、これにアクセスして記載の手順を実行することを強く推奨します。今回のこのブログでは前回説明したコンセプトを基に構築すること、および読者がすでに以下の状態であることを想定しているからです。

  1. ElasticsearchおよびKibanaを使用可能(バージョン6.4以降)
  2. Canvasをインストール済み

Canvas Workpadの作成

  1. サイドバーの[Canvas]タブをクリックします
  2. [Create workpad]をクリックします
  3. 新しいworkpadに一意の名前をつけます

サンプルデータのインストール

このチュートリアルでは、Elastic提供のサンプルデータセット、具体的にはsample flight dataを使用します。

注:このデータセットはKibanaバージョン6.4以降でのみ利用可能です。

Kibanaインスタンスにアクセスします。

  1. サイドバーでメインの[Kibana]ホームページをクリックします
  2. 「Add Data to Kibana」セクションの下部にあるリンク[Load a data set and a Kibana dashboard]をクリックします
  3. [Sample flight data]タイルで[Add]をクリックします

blog01.gif

クイックリファレンス

下の表は、先ほどインストールしたサンプルデータセットの情報を示しています。太字の下線が引かれている項目はこのアクティビティの後のほうで使用しますが、その他の項目については自由に使ってみてください。

kibana_sample_data_flights
AvgTicketPrice
Carrier
DestCityName
DestCountry
FlightDelayType
FlightTimeMin
OriginCityName
OriginCountry
Dest
DestAirportID
DestLocation
DestRegion
DestWeather
DistanceKilometers
DistanceMiles
FlightDelay
FlightDelayMin
FlightNum
FlightTimeHour
Origin
OriginAirportID
OriginLocation
OriginRegion
OriginWeather
_id
_index
_score
_type
dayOfWeek
hour_of_day
timestamp

メトリックの使用

基本から開始

フライトの遅延総時間(分)を導き出し、メトリック要素で表示しましょう。そのためにはSQLクエリを使用して、サンプルデータセットのFlightDelayMinフィールドから総時間を求めます。

  1. [Add Element]をクリックします
  2. [Metric]を選択します
    1. ヒント:初めて要素を作成すると、デモ用データが入った状態で表示され、すぐに各種の操作ができるようになっています。
  3. 右の編集パネルで[Data]タブを選択します
  4. [Change your data source]をクリックします
  5. [Elasticsearch SQL]を選択します
  6. SQLクエリエディターに、次のように入力します
SELECT
    SUM(FlightDelayMin) AS delay
FROM
    kibana_sample_data_flights

詳細説明:SQLクエリは、インデックスkibana_sample_data_flightsからキー FlightDelayMinのすべてのJSON値を選択します。このデータは「delay」という名前の「column」に返されます。

  1. [Save]をクリックします

メトリック要素には警告マークが表示されています。これは、要素が誤ったデータを指しているからです。

  1. 右の編集パネルの上部で[Display]タブを選択します
  2. 「Numbers」セクションで、次のように設定します
  • Measurement:Value
  • Field:delay
  • メトリックのラベルを次のように変更します。「Total Delay in Minutes」
  • blog03.gif

    項目のカスタマイズ

    任意の期間におけるフライトの遅延総時間を表示できるように、時間フィルターを設定します。

    1. [Add element]をクリックします
    2. [Time Filter]を選択します

    メトリック要素には警告マークが表示されています。時間フィルターはworkpadのすべての要素にすぐに適用されますが、この警告マークはその時間フィルターがまだ正しく設定されていないことを示しています。

    1. 時間フィルターをworkpadの空白の場所に移動します
    2. 時間フィルター要素のデフォルトの時間フィールドは@timestampですが、ここでは適切ではありません。時間フィルターの編集パネルで、列の値を timestamp にします(つまり@マークを削除します)
    3. [Set]をクリックします
    4. 時間フィルターをクリックし、以下の期間から選択します
    • 最近24時間
    • 最近7日間
    • 最近2週間

    注:サンプルデータは4週間分あります。サンプルデータがインストールされた日を中心として、そこから過去のデータが2週間分、未来のデータが2週間分あります。

    blog04.gif

    高度な内容

    次に、フライト遅延時間の平均を求めてみましょう。ここで表示を見やすくするためには、背後で動作するコードを少しカスタマイズすることが必要になります。

    1. 作成した最初のメトリックが選択されていることを確認します
    2. 画面の右上隅にある[Duplicate]ボタンをクリックします
    3. 新しい時間フィルターをworkpadの空白の場所に移動します
    4. メトリックのラベルを次のように変更します。「Average Delay in Minutes」
    5. [Data]タブを選択します
    6. SQLクエリエディターに、次のように入力します
    SELECT
        AVG(FlightDelayMin) AS delay
    FROM
        kibana_sample_data_flights
    
    1. [Save]をクリックします
    2. 数値のすべてが見えるようにメトリック要素を拡大します
    • 次のような数値が表示されます。47.33517114633586
    • 四捨五入したほうがいいのは明らかです
  • 右下隅の[Expression editor]をクリックします。するとコードエディターが開きます。ここで、選択した要素の表示形式を指定するコードを修正できます。
  • 表現エディターのコードの3行目に、 「math」関数が記述されています。修正する命令行はこれです
  • blog03.png

    1. ElasticはCanvasドキュメントで、使用可能な数学関数のリストを提供しています
    2. round(a,b)関数を使います
    • aは四捨五入する値
    • bは小数点以下の桁数
  • 表現エディターで3行目を変更して、下記のように四捨五入関数を含めるようにします
    1. 3行目:| math "round(delay,0)"
  • 表現エディターの右下隅にある[Run]をクリックします
  • blog05.gif

    マークダウンの使用

    基本から開始

    フライト総数を導き出してマークダウン要素に表示します。そのためには、サンプルデータセットのFlightNumフィールドに対してSQLコマンドを実行します。

    1. [Add Element]をクリックします
    2. [Markdown]を選択します
      1. ヒント:初めて要素を作成すると、デモ用データが入った状態で表示され、すぐに各種の操作ができるようになっています。
    3. 右の編集パネルで[Data]タブを選択します
    4. [Change your data source]をクリックします
    5. [Elasticsearch SQL]を選択します
    6. SQLクエリエディターに、次のように入力します
    SELECT
        FlightNum
    FROM
        kibana_sample_data_flights
    
    1. [Save]をクリックします
    2. [Display]タブをクリックします
    3. 以下のものを除き、「Markdown content」エディターからすべてを削除します
    **{{rows.length}} rows**
    

    注:マークダウン要素は、その名前が示すとおり、マークダウン構文を完全にサポートします。例:**##```、など。マークダウン構文に慣れていない方のために、上記の例では太字にするテキストを**で囲んでいます。

    1. [Apply]をクリックします
    2. これでマークダウン要素にはデータセットの列の総数、つまりフライトの総数が表示されます。テキストを次のように更新します
    Total number of flights: **{{rows.length}}**
    
    1. [Apply]をクリックします
    2. マークダウンエディターの画面右上隅にある[+]をクリックします
    3. ドロップダウンメニューで[Text Settings]を選択します
    4. テキスト設定で、次のように調節します
      1. フォントサイズ:36
      2. アラインメント:中央揃え
    5. テキストが見やすくなるようにマークダウン要素のサイズを調整します

    blog06.gif

    項目のカスタマイズ

    次に、いくつのフライトがどのような理由で遅延したかについて調べてみましょう。そのためには、FlightDelayTypeフィールドを使用します。

    1. [Add Element]をクリックします
    2. [Markdown]を選択します
    3. 右の編集パネルで[Data]タブを選択します
    4. [Change your data source]をクリックします
    5. [Elasticsearch SQL]を選択します
    6. SQLクエリエディターに、次のように入力します
    SELECT
        FlightDelayType,
        COUNT(FlightDelayType) AS count
    FROM
        kibana_sample_data_flights
    GROUP BY
        FlightDelayType
    
    1. [Save]をクリックします
    2. [Display]タブをクリックします
    3. 以下のものを除き、「Markdown content」エディターからすべてを削除します
    {{#each columns}}
     **{{name}}**
    {{/each}}
    
    1. 詳細説明:
    2. これはhandlebar.js構文です。SQLクエリで返された各列には、列の名前が出力されていますが、FlightDelayType列の各行の値を出力する必要があります。次の手順でこれを修正します。
    1. 「Markdown content」エディターで、次のように置き換えます
    • columnsrowsに置き換える
    • nameFlightDelayTypeに置き換える
  • [Apply]をクリックします
  • これで遅延タイプのリストができます。各タイプにカウントを追加しましょう。「Markdown content」エディターで、現在の内容を下記のコードに置き換えます
  • {{#each rows}}
    - {{FlightDelayType}} -- {{count}}
    {{/each}}
    
    1. 上記のコードの説明
    2. 1行目:各行に対し...
    3. 2行目:リスト項目であることを示すために「-」を入力し、2つの変数を「--」で区切って入力します
    4. 3行目:改行
    5. 4行目:ループを終了させます
    1. [Apply]をクリックします

    blog07.gif

    高度な内容

    先ほど作成したマークダウン要素では、行の1つが次のようになっています。

    No Delays -- 2856

    これは遅延について示しているのではなく、実際にはその逆で、定刻どおりに出発したフライトを示しています。この行を削除し、実際に遅延したフライトのみを表示するようにしましょう。そのためにはfilterrowsと呼ばれる、Canvasの関数を使用します。
    blog02.7.png
    1. 先ほど作成したマークダウン要素(すべての遅延タイプを表示)が選択されていることを確認します。
    2. 画面の右下隅にある「Expression editor」をクリックします。するとコードエディターが開きます。ここで、選択した要素の表示形式を指定するコードを修正できます。
    3. 表現エディターでは以下に類似した記述になっているはずです。
    filters
    | essql 
      query="SELECT
        FlightDelayType,
        COUNT(FlightDelayType) AS count
    FROM
        kibana_sample_data_flights
    GROUP BY
        FlightDelayType"
    | markdown "{{#each rows}}
    - {{FlightDelayType}} -- {{count}}
    {{/each}}"
    
    1. まずfilterrows関数でデータをパイプし、その後、マークダウン要素にパイプします。10行目に改行を挿入し、| markdown関数のすぐ上にfilterrows関数を追加します。行頭にパイプ(縦線)|を入れるのを忘れないようにしてください。
    ...
    GROUP BY
        FlightDelayType"
    <b style="background-color:#ffae5b"><i>| filterrows {}</i></b>
    | markdown "{{#each rows}}
    - {{FlightDelayType}} -- {{count}}
    ...
    
    1. FlightDelayType列に含まれている値に基づいて行をフィルターします。そのためには、getCellと呼ばれる別の関数を使用する必要があります。これによって、所定の列の各行の値が出力されます(「getCell」関数についてのドキュメントを参照)。
    | filterrows { <b style="background-color:#ffae5b"><i>getCell “FlightDelayType”</i></b> }
    
    1. 次に、anyと呼ばれる関数に、各行から値をパイプします。これは、 チェック条件に基づいてtrueまたはfalseを返します(「any」関数についてのドキュメントを参照)。
    | filterrows {getCell “FlightDelayType” <b style="background-color:#ffae5b"><i>| any {}</i></b> }
    
    1. 最後に、チェック条件について「No Delay」 に等しくないという値を返すために、neqと呼ばれる関数を使用します(「neq」関数についてのドキュメントを参照)。
    | filterrows {getCell “FlightDelayType” | any { <b style="background-color:#ffae5b"><i>neq “No Delay”</i></b> }}
    
    1. 表現エディターの右下隅にある[Run]をクリックします。「No Delay -- 2856」となっていた行が表示されなくなります。

    blog08.gif

    その他の便利なリソースリンク

    お疲れ様でした。Canvasのメトリック要素およびマークダウン要素を使用する例をいくつか見てきました。ぜひ他の要素もworkpadに追加して、Canvasのフル機能をお試しください。

    Canvasのチュートリアルはこの他にもあります。ぜひご活用ください。

    Canvas: データ表要素とデバッグ要素

    $
    0
    0

    Canvasは現在、workpadに追加できる約20の組み込みの要素(一覧についてはブログ「KibanaでCanvasを使い始める」を参照)を提供しています。このブログでは、そのうちの2つ、データ表およびデバッグ要素のみをご紹介します。

    image16.png

    データ表

    高度に柔軟かつ動的な表です。初期状態のままで、スクロール、ページネーション、カスタムCSSがサポートされます。

    image2.png

    デバッグ

    背後で動作するJSONデータへのアクセスを提供し、発生する問題をより正確に分析できます。

    ここでは具体的に、非常に馴染みのあるデータ表である空港のフライト発着表を作成するためにCanvasを使用します。
    下記がCanvasで作成する表の完成例です。

    要件とレビュー

    読者の環境が以下の条件を満たしていることを前提に、ブログ「KibanaでCanvasを使い始める」で説明した概念に基づき作成します。

    1. ElasticsearchおよびKibanaが稼働中(バージョン6.4以降)
    2. Canvasをインストール済み(CanvasはKibanaバージョン6.5以降に組み込み)

    サンプルデータのインストール

    このチュートリアルでは、Elastic提供のサンプルデータセット、具体的にはsample flight dataを使用します。

    注:このデータセットはKibanaバージョン6.4以降でのみ使用できます。

    Kibanaインスタンスにアクセスします。

    1. サイドバーでメインの[Kibana]ホームページをクリックします
    2. Add Data to Kibana」セクションの下部にあるリンク「Load a data set and a Kibana dashboard」をクリックします
    3. Sample flight data]タイルで[Add]をクリックします

    クイックリファレンス

    下記の表は、先ほどインストールした、フライトのサンプルデータセットの情報を示しています。太字の下線が引かれている項目は、このアクティビティの後のほうで使用しますが、その他の項目については自由に使ってみてください。

    kibana_sample_data_flights
    AvgTicketPrice
    Cancelled
    Carrier
    DestCityName
    DestCountry
    FlightDelayType
    FlightTimeMin
    OriginCityName
    OriginCountry
    Dest
    DestAirportID
    DestLocation
    DestRegion
    DestWeather
    DistanceKilometers
    DistanceMiles
    FlightDelay
    FlightDelayMin
    FlightNum
    FlightTimeHour
    Origin
    OriginAirportID
    OriginLocation
    OriginRegion
    OriginWeather
    _id
    _index
    _score
    _type
    dayOfWeek
    hour_of_day
    timestamp

    空港の発着表の作成

    作成

    最初にworkpadを作成し、次にデータ表にデータを追加します。

    Canvas Workpadの作成

    1. Kibanaインスタンスにアクセスします
    2. サイドバーの[Canvas]タブをクリックします
    3. Create workpad]をクリックします
    4. 新しいworkpadに一意の名前をつけます

    データ表要素の作成

    1. Add element]ボタンをクリックします
    2. Data Table]要素を選択します
      1. ヒント:初めて要素を作成すると、デモ用データが入った状態で表示されるため、すぐに各種の操作ができます。
    3. 右の編集パネルで[Data]タブを選択します
    4. Change your data source]をクリックします
    5. Elasticsearch SQL]を選択します
    6. SQLクエリエディターに、次のように入力します
    SELECT
      DestCityName AS Destination,
      timestamp AS Time,
      Carrier AS Airline,
      FlightNum AS Flight,
      FlightDelayType AS Status,
      Cancelled
    FROM
      kibana_sample_data_flights
    

    注:このサンプルデータセットには空港のゲート番号のフィールドが含まれていません。このブログの後のほうで、ランダムに番号を生成し、その列を作成します。

    1. Save]をクリックします
    2. 以下のようなデータ表ができているはずです

    image12.png

    コード

    これでデータが入力されたデータ表ができましたが、望んでいる形式にはなっていません。背後で動作するコードを表示し、調整する必要があります。

    Time列の形式の調整

    1. データ表が選択されていることを確認します
    2. 画面の右下隅にある[Expression editor]をクリックします
    3. 式エディター内に次のコードが見つかるはずです
    filters
    | essql
      query="SELECT
      DestCityName AS Destination,
      timestamp AS Time,
      Carrier AS Airline,
      FlightNum AS Flight,
      FlightDelayType AS Status,
      Cancelled
    FROM
      kibana_sample_data_flights"
    | table
    | render

    分類 -- このコードには次の4つのメインセクションがあります。

      1. フィルター: Time Filter要素をこのworkpadに追加すると、このデータ表要素に入力されたデータには最初に時間フィルターが適用されて、フィルターで除外されなかったデータのみが表示されることになります。この行を消去すると、データ表要素はworkpadに追加されるどのフィルター要素にも影響を受けることがなくなり、状況によっては便利です。
      2. データソース: Elastic SQLデータソースを使用しているため、ここでもSQLクエリの表示と編集ができます。
      3. 要素: この行は、workpadに表示する要素のタイプを定義します。試してみる場合は、「table」を「shape」に変更し、次に右下隅の[Run]をクリックして、どうなるか見てみましょう。元に戻すことを忘れないようにしてください。
      4. レンダリング: 要素の表示の見た目をカスタマイズできます。このブログの後のほうで、データ表をよりスタイリッシュにするために、カスタムのCSSをレンダリング関数に追加します。
    1. table」要素の関数で表示する前に、データを修正する必要があります。そのために、「essql」データソース関数と「table」要素の関数の間に、「mapColumn」という新しい関数を追加します。 この関数「mapColumn」は単に任意の列の値を修正するためのものです。ここで修正しようとしている列は「Time」列です。そのため、12列目に次のコードを追加します。
    ...
    FROM kibana_sample_data_flights"
    <b style="background-color:#ffae5b"><i>| mapColumn Time fn={}</i></b>
    | table
    ...
    1. Canvasには、「formatdate」関数など、利用可能な多くの組み込みの関数が用意されています。ここでは時間を「hh:mm A」の形式で表示します。そのために、コードの12行目に以下を追加します。
    ...
    FROM kibana_sample_data_flights"
    | mapColumn Time fn={ <b style="background-color:#ffae5b"><i>formatdate “hh:mm A”</i></b> }
    | table
    ...
    1. 式エディターの右下隅にある[Run]をクリックします
    2. すると、エラーになりました。デバッグが必要です

    デバッグの時間(この手順をスキップしないでください)

    後ですぐにコードに戻りますが、まずはCanvasでのデバッグ方法を見てみましょう。

    エラーの特定

    1. 表要素の警告シンボルをクリックします。
    2. 下図のように、エラーの原因が表示されるはずです。

    image17.png

    1. mapColumn」関数がタイムスタンプデータを「number」にキャストしようとしているようです。これは、使用している「formatdate」関数が、数値形式のタイムスタンプ(UTCミリ秒など)を要求しているからです。
    2. 実際には、どのようなタイムスタンプ形式になっているのでしょうか。それを解明するために、「debug」要素を追加しましょう。

    デバッグ要素の追加

    1. Add element]をクリックします
    2. Debug]要素を選択します
    3. 右の編集パネルで[Data]タブを選択します
    4. Change your data source]をクリックします
    5. Elasticsearch SQL]を選択します
    6. SQLクエリエディターに、次のように入力します
    SELECT
      DestCityName AS Destination,
      timestamp AS Time,
      Carrier AS Airline,
      FlightNum AS Flight,
      FlightDelayType AS Status,
      Cancelled
    FROM
      kibana_sample_data_flights
    1. [Save]をクリックします
    2. デバッグ要素では、[Time]フィールドのタイプが「date」になっており、最初のエントリーは次のようになっています:2018-11-05T00:00:00.000Z
      image9.png
    3. ありがたいことに、Canvasには 「date」タイプをUTCミリ秒の数値に変換できる機能が組み込まれています。
    4. データ表を再度選択し、下記のとおり式エディターでコードに「date」関数を追加します。
    | mapColumn Time fn={<b style="background-color:#ffae5b"><i> date | </i></b>formatdate “hh:mm A” }
    1. Run]をクリックします
    2. データ表に適切な形式でタイムスタンプが表示されます。

    image6.png

    ヒント:毎回、デバッグ要素を追加する必要はありません。どの要素の式エディターでも、コード | render as="debug"を追加して、その要素のJSONを見ることができます。ただし、作業中の参照用として、専用のデバッグ要素を準備しておくと便利です。

    では、通常のプログラムに戻りましょう。

    コードの続き

    次に、「Gate」列を追加しましょう。このデータセットにはゲートのデータが含まれていないため、Canvasに組み込まれている強力な機能を使用してランダムに生成します。

    ゲートのデータの追加

    1. 列を追加する最も簡単な方法は、SQLクエリにエントリーを追加することです。単純に「FlightNum」データを追加し、新しい列の名称を「Gate」にします。
    2. 右側のエディターパネルで[Data]タブをクリックし、SQLエディターで次の行を追加します。
    SELECT
      DestCityName AS Destination,
      timestamp AS Time,
      Carrier AS Airline,
      FlightNum AS Flight,
      <b style="background-color:#ffae5b"><i>FlightNum AS Gate,</i></b>
      FlightDelayType AS Status,
      Cancelled
    FROM
      kibana_sample_data_flights
    1. Save]をクリックします
    2. 式エディターで、1行目の下にもう1つ「mapColumn」関数を追加します。今回は「Gate」列を修正します。
    ...
    | mapColumn Time fn={ date | formatedate “hh:mm A” }
    <b style="background-color:#ffae5b"><i>| mapColumn Gate fn={}</i></b>
    | table
    ...
    1. 実際のゲート番号を取得するには、1~100の間の数字をランダムに生成する必要があります。ありがたいことに、Canvasには活用できる数学関数がいくつか組み込まれています。 ここで「random」関数を使用しますが、この関数では小数点以下の桁数の多い数字をランダムに生成するため、求めているものにはなりません。そこで、2つ目の関数を追加します。ランダムに生成した数字を四捨五入する「round」関数です。コードは次のようになります。
    | mapColumn Gate fn={ <b style="background-color:#ffae5b"><i>math "round(random(0,100),0)"</i></b> }
    1. Run]をクリックします
    2. これで、新しい「Gate」列にはすべて、ランダムに生成されたゲート番号が表示されるはずです。

    image5.png

    列の結合

    値が「true」のときは常に「Cancelled」ステータスが表示されるように、「Cancelled」列を「Status」列と組み合わせる必要があります。

    1. データ表要素が選択されていること、および式エディターが開いていることを確認します
    2. mapColumn」関数をもう1つ追加する必要がありますが、今回は「Status」列に追加します
    ...
    | mapColumn Gate fn={math "round(random(1,100),0)"}
    <b style="background-color:#ffae5b"><i>| mapColumn Status fn={}</i></b>
    | table
    ...
    1. 次に、「Cancelled」列のフィールド(または「cell」)が「true」になっているかどうかを確認する必要があります
    | mapColumn Status fn={<b style="background-color:#ffae5b"><i>if {getCell "Cancelled" | eq true}</i></b>}
    1. そして、条件がtrueの場合に「Status」列の値が文字列「Cancelled」になるように設定します
    | mapColumn Status fn={if {getCell “Cancelled” | eq true}<b style="background-color:#ffae5b"><i> then=”Cancelled” </i></b>}
    1. ここで[Run]をクリックすると、「Cancelled」を「Status」列にマッピングできます。ただし、true以外の場合については「Status」の値が「null」値になります。 image4.png
    1. 最後に必要な作業は、「Status」列の値が「Cancelled」ではない場合に、元の値を維持するようCanvasに指示することです。
    | mapColumn Status fn={if {getCell “Cancelled” | eq true} then=”Cancelled”<b style="background-color:#ffae5b"><i> else={getCell "Status"}</i></b>}
    1. Run]をクリックします
    2. これで、「Status」列を「Cancelled」列と組み合わせることができました。

    image8.png

    列の削除

    これで「Status」列に、必要な情報をすべて含めることができたので、「Cancelled」列を表示する必要がなくなりました(背後では機能している必要があります)。そのため、「Cancelled」列を削除します。

    1. データ表要素が選択されていること、および式エディターが開いていることを確認します
    2. Canvasには、列を含めるまたは除外するのに使用する「columns」という関数があります。ここでは「Cancelled」列を除外します。次のとおり、コードを1行追加します。
    ...
    | mapColumn Status fn={if {getCell “Cancelled” | eq true} then=”Cancelled” else={getCell “Status”}}
    <b style="background-color:#ffae5b"><i>| column exclude=”Cancelled”</i></b>
    | table
    ...
    1. Run]をクリックします
    2. 背後ではその列のデータを使用していますが、データ表要素に「Cancelled」列が表示されなくなっているはずです。

    image10.png

    カスタマイズ

    これで望むとおりのデータがすべて揃いました。次は、workpadの表示の見た目をカスタマイズしてみましょう。

    背景色の設定

    1. workpadで色が何も選択されていないことを確認します
    2. ページ右側の編集パネルで[Page Background]カラーピッカーをクリックし、値を「#0276fd」に設定します

    image15.png

    ページネーションの削除

    1. データ表要素を選択します
    2. ページの右側の編集パネルで、[Display]タブを選択します
    3. Table Style]パネルの[+]ボタンをクリックします
    4. ドロップダウンから[Pagination]を選択します
    5. 切り替えボタンをクリックしてオフにします

    image18.png

    表の行数の設定

    1. 再度、[Table Style]パネルの[+]ボタンをクリックします
    2. ドロップダウンから[Rows per page]を選択します
    3. ページごとの行数を25に増やします
    4. 実際には18行にするので、データ表要素の式エディターを開き、「perPage」の値を18に変更します
    | table paginate=false perPage=<b style="background-color:#ffae5b"><i>18</i></b>
    1. Run]をクリックします
    2. 18行すべてが表示されるようにデータ表要素を広げます

    表テキストのスタイル設定

    1. 再度、[Table Style]パネルの[+]ボタンをクリックします
    2. 今回は[Text Settings]を選択します
    3. テキストを太字に、色をホワイトに設定します

    表ヘッダーのスタイル設定

    1. 表の他の行よりも目立つように、表のヘッダーのスタイルを設定します。すでに[Table Style]パネルでできることは見てきたので、ここではカスタムCSSを使います
    2. そのためには、[Element Style]パネルの[+]ボタンをクリックします
    3. ドロップダウンメニューから[CSS]を選択します
    4. CSSエディターの内容を消去し、次のコードをCSSエディターにペーストします
    canvasDataTable__th { text-decoration: underline; background-color: #d0e9ff; color: black;}
    1. Apply stylesheet]をクリックします
    2. これで表のヘッダーには、薄いブルーの背景色とブラックの下線が引かれたテキストが表示されるはずです

    表の行のスタイル設定

    1. 表の行の色が交互になるよう設定するために、ここでもカスタムCSSを使用します
    2. 次のコードをCSSエディターにペーストします
    .canvasDataTable__tbody>:nth-child(even) {
    background-color: #2a2a50;
    }
    
    .canvasDataTable__tbody>:nth-child(odd) {
    background-color: #5f67af;
    }
    1. Apply stylesheet]をクリックします
    2. workpadの幅に合うようにデータ表要素の幅を調整します
    3. 下図のように、行の色が交互になるように表示されるはずです

    タイトルの追加

    1. Add element]をクリックします
    2. Markdown]要素を選択します
    3. 画面右側の[Markdown content]エディターにあるすべてのテキストを削除します
    4. Markdown content]エディターに「Departures」と入力します
    5. Apply]をクリックします
    6. Markdown]要素のサイズを調整し、画面の中央に揃えます
    7. 右側の編集エリアにある [Markdown]パネルで、[+]ボタンをクリックします
    8. ドロップダウンメニューから[Text Settings]を選択します
    9. テキストを次のとおりに設定します
      1. サイズ:48
      2. フォント:太字
      3. アラインメント:中央揃え
      4. 色:ホワイト
    10. これで、実際に空港で見るものによく似たworkpadが完成したはずです。

    完成したコード

    下記は、式エディターでのデータ表の完全なコードです。

    filters
    | essql
      query="SELECT
      DestCityName AS Destination,
      timestamp AS Time,
      Carrier AS Airline,
      FlightNum AS Flight,
      FlightNum AS Gate,
      FlightDelayType AS Status,
      Cancelled
    FROM
      kibana_sample_data_flights
    "
    | mapColumn "Time" fn={date | formatdate "hh:mm A"}
    | mapColumn "Gate" fn={math "round(random(1,100),0)"}
    | mapColumn "Status" fn={if {getCell "Cancelled" | eq true} then="Cancelled" else={getCell "Status"}}
    | columns exclude="Cancelled"
    | table paginate=false perPage=18
     font={font family="'Open Sans', Helvetica, Arial, sans-serif" size=14 align="left" color="#FFFFFF" weight="bold" underline=false italic=false}
    | render
     css=".canvasDataTable__th { text-decoration: underline; background-color: #d0e9ff; color: black;}
    .canvasDataTable__tbody>:nth-child(even) {
    background-color: #2a2a50;
    }
    .canvasDataTable__tbody>:nth-child(odd) {
    background-color: #5f67af;
    }"

    その他の便利なリソースリンク

    お疲れ様でした。Canvasのデータ表要素およデバッグ要素を使用する例をいくつか見てきました。ぜひ他の要素もworkpadに追加して、Canvasのフル機能をお試しください。

    Canvasのブログ記事はこの他にもあります。ぜひご活用ください。

    バナー画像:MPD01605による「Miami Airport Screen」はCC BY 2.0 によって許可を得ています。

    Elastic Stackで一元管理データベースを監視する

    $
    0
    0

    本記事はElastic{ON} 2018での事例紹介セッションの要約です。Elastic{ON} 2018のトークはアーカイブで多数公開中です。また、お近くの都市で開催されるElastic{ON} Tourのスケジュールもご覧ください。

    シティグループは世界100か国以上で金融サービスを展開し、世界160か国以上に顧客を抱えています。同社の大規模でグローバルな運用インフラを支える部門が、ビジネスアプリケーションチームです。事業規模が大きく、ITインフラが複雑であることから、ビジネスアプリケーションチームはこれまで数多くの難題に直面してきました。スケール化や事業回復力、ITアジリティ、IT資産活用、ITツーリング(ITツールの最適化)、新たなテクノロジーの導入など、シティグループのITチームは近年さまざまな側面で急速な進化を迫られています。同時に、コスト最適化も重要です。

    こうした状況下で、特に大きな課題となっていたのが部門間でのITツーリング(ITツールの最適化)です。自動化ソフトウェアのデプロイや、デプロイ環境の増設、マルチユースな一元化ツールへの移行など、新たなトレンドに対応できるITツールはあらゆる部門で求められていました。基幹業務に関する技術的課題を多く抱える一方、ITチームはシティグループの経営陣からも多くの問い合わせを受けていました。経営陣もITインフラの活用や、ツールが事業にもたらすメリットにますます関心を寄せるようになったためです。

    シティグループが業務を監視するためには、大量のデータが必要です。しかし、データが異なる部門や国のあちこちに、さまざまな形式で存在している限り、ツールやインフラの状態、運用の改善に役立つようなエンドツーエンドのインフラ監視システムを構築することは不可能です。そこでITチームはあらゆる場所で既存、および新規のツーリングパフォーマンスを追跡・監視でき、そのパフォーマンスを経営陣にわかりやすいレポートとして出力する統合監視システムを構築することにしました。

    新たな統合監視システムには、次のすべての機能と仕様が必要です。

    • 一元化されたデータストアとして振る舞うことが可能
    • エージェントを設定可能
    • ツールライセンスのサポートコストを軽減
    • データガバナンスを統一し、一元化する

    Elastic Stackを使ったデプロイ

    類似のアーキテクチャーで検索解析テクノロジーが確かな実績を持つことから、シティグループのITチームはElastic Stackに注目しました。新たなインフラでツールのパフォーマンスを監視するには、メトリック、イベント、ログ(全社で1日に9千万ドキュメント)を投入する必要がありますが、Elasticsearchを使えば、あらゆるデータを1か所にまとめて格納、検索できるようになります。シティグループはElasticsearchを使用し、アクティブな、プライマリデータストレージクラスターを構築しました。このクラスターは各種データを30日間保持し、検索と可視化に対応します。30日を経過すると、自動のスナップショットでElasticsearchから安価なオンプレミスのオブジェクトストレージへデータを移行させる設計です。

    citigroup-datastorage.png


    シティグループでは、セキュリティオペレーションセンターと監査用のインデックス、さまざまなユースケースとレベルに応じたアクセス権限も設計する必要がありました。Elasticsearchを導入したことで、ITチームはデータのグループ化、ネーミングスキームの標準化、ロールベースのアクセス制御と、データガバナンス用認証の定義も実現させました。さらにシティグループではITチームと経営陣向けに、通常のダッシュボードと社内用APIを組み合わせ、手軽にデータを取得・分析できる環境を構築しています。基幹業務部門でもこのAPIを呼び出し、取得したデータをローカルシステムに投入して部署ごとに詳しく分析することができます。

    citigroup-users.png

    シティグループではアラート(旧Watcher)を活用したコンテナーインフラ監視を構築し、1つの部署に限定せず、全部門にわたりコンテナーのメトリック、イベント、ログを収集するシステムも開発しました。収集された情報は監査、アラート管理、システム管理などの幅広いユースケースに使用されています。

    citigroup-container.png

    監視ニーズの他に、シティグループのITチームでは経営陣を含む多様なユーザーグループにデータから得たインサイトを共有するスケーラブルで安全な手段を必要としていました。そこで作成されたのがKibanaをベースとするダシュボードです。このダッシュボードはリアルタイムなアプリケーション状態の集約ビュー、さらにメトリックやログ、コンテナーリソースの使用状況、トポロジー情報に関する個別のビューを表示します。ユーザーはこのダッシュボードでアプリケーションやコンテナーの詳細情報を取得し、ソースの問題を把握することができます。データ表示の切り替えも簡単です。運用チームとアプリケーションチームはツーリングのパフォーマンス監視やレポートの実行に際してトップダウン、あるいはボトムアップビューでデータを取得し、レポートから各種ツールの実際の効率を把握しています。

    シティグループでインフラの監視を支える高度な検索解析テクノロジーについては、Elastic{ON}の事例紹介セッション「シティグループが実践するアプリインフラ監視」でさらに詳しくご紹介しています。

    Screen Shot 2018-10-29 at 1.37.52 PM.png

    Elastic APMからLogstashまたはKafkaを通してデータを送信するには

    $
    0
    0
    今日のデプロイでは、アプリケーションサーバーの寿命が短いことや、アプリケーションサーバーがメッセージキューやデータベースなどのような他のコンポーネントよりも信頼性の低いハードウェア(プリエンプティブあるいは低優先度のVM、スポットインスタンス)を使用していることがよくあります。そのようなケースでは、より信頼性の高いシステムに早くデータを移すのがベストです。 リリース6.4.0から、APMサーバーはLogstashまたはKafkaにデータを送信し、信頼性の要件をこうしたシステムの一つに分散することができるようになります。また、Logstashを使用すると、多くの利用可能なLogstashプラグインの1つを使って、APMデータを強化することもできます。 ここで、データをElasticsearchに投入する前に別システムを通してデータを送信する場合の設定を紹介し、注意点をいくつか見ていきましょう。 1. [Elasticsearchへの出力にLogstashを設定する](#configure-logstash) 2. [Elastic APMサーバーをLogstashに送信するよう設定する](#configure-apm-server) 3. [Elasticsearchを設定する](#configure-elasticsearch) 4. [オプションとしてソースマップを含める](#configure-source-maps) 5. [Kafkaを導入する](#introduce-kafka) ## [Logstashの設定](Logstashの設定) まず、パイプラインを追加して、beats/lumberjackプロトコルを使用してLogstashがAPMサーバーからイベントを受け取るよう設定し、次にそれをElasticsearchに送信します。 input { beats { id => "apm-server" port => 5044 } } output { elasticsearch { hosts => ["elasticsearch:9200"] index => "apm-%{[beat][version]}-%{[processor][event]}-%{+YYYY.MM.dd}" } } 1日につきトランザクションやスパンなどの1イベントタイプごとにインデックスが1件作成されます。これは、デフォルトのAPMサーバー設定が生成するときと同様です。 ソースマップでここにちょっとおかしな部分ができてきますが、後でこの記事内で修正します。 注意深く見ている人は、beatへのリファレンスは何をするものだろうと思うことでしょう。 APMサーバーは[Beats Framework](/jp/products/beats)上に構築されており、従って同じメタデータがイベント内で引数を渡します。 つまり、別のBeatデータと同じLogstashインスタンス内のAPMデータ処理は、`[@metadata][beat] == "apm-server"`という条件文を使用して行われるということです。 ## [APMサーバーの設定](APMサーバーの設定) これでLogstashが設定できたので、APMサーバーの`apm-server.yml`をアップデートして、イベントをそれに応じて出力できるようにします。 output.elasticsearch: enabled: false output.logstash enabled: true hosts: ["logstash:5044"] backoff、proxy、ssl設定などの追加オプションについては、[Elastic APMサーバードキュメント](/guide/en/apm/server/6.4/logstash-output.html)で詳しく説明しています。 APMサーバーで監視を有効にしている場合は、必ず次のように設定します。 xpack.monitoring.elasticsearch: enabled: true hosts: ["elasticsearch:9200"] これで、APMサーバー自体の監視がElasticsearchに直接フローし続けるようになります。 ## [Elasticsearchの設定](Elasticsearchの設定) APMサーバーをスタートする準備ができるまで、あと1ステップです。 Elasticsearchはまず、APM UIが期待するとおりにAPMデータを格納する方法を知る必要があります。つまり、インデックスのテンプレートが必要だということです。 このテンプレートを読み込む方法は2通りあります。 ElasticsearchでAPMサーバーを一時的に指定することが可能なら、次のようにします。 apm-server setup --template それ以外の場合は、まずAPMサーバーからテンプレートをエクスポートします。 apm-server export template > apm-6.4.2.tmpl.json それからElasticsearchに読み込みます。 curlを使って、次のようにします。 curl -XPUT -H 'Content-Type: application/json' http://elasticsearch:9200/_template/apm-6.4.2 -d @apm-6.4.2.tmpl.json 次のコマンドは、各操作が成功したか失敗したかをレポートします。 テンプレートが正常に読み込まれたか確認するには、 _template/apm-* をクエリします。 そうすると、次のようなドキュメントのセットが返されます。 { "apm-6.4.2": { "order":1, "index_patterns": [ "apm-6.4.2-*" ], ... インデックスパターンが、前のLogstashのステップで設定したものと合っていることに注意してください。 さらに、そこにバージョン情報が含まれていることにも注意してください。つまり、この設定ステップは次のようになるということです。 1.Logstashに接続しているAPMサーバーとまったく同じバージョンで行われる。 1.毎回APMサーバーのアップグレード中に繰り返される。 ## 使ってみる APMサーバーを起動して、アプリケーションの動作を分析していきましょう。 ## [ソースマップ](ソースマップ) [ソースマップ](/guide/en/apm/server/6.4/sourcemaps.html)は、分かりにくいコードを元のソースに戻すマッピングのために使用されます。 一番良く見かけるのは、縮小されたJavascriptを戻すときに使われるものです。 ソースマップは、APMサーバーの出力がElasticsearchではない場合、特別な考慮が必要です。 結果的にElasticsearchにどう届くかにかかわらず、APMサーバーがこれを使うためにそこに格納されなければなりません。 ソースマッピングのストレージ設定は、`rum.source_mapping.elasticsearch`を次のようにセットします。 apm-server: rum: source_mapping: elasticsearch: hosts: ["elasticsearch:9200"] index_pattern: "apm-*-sourcemap*" これは、APMサーバーに、`apm-*-sourcemap*`にマッチしたインデックスでソースマップを探すように指示しています。 ソースマップはLogstashによってアップロードすることができますが、デプロイメントプロセスの間に直接Elasticsearchに送信して、マッピングの到着が必要なイベントが起こる前に確実に格納することをおすすめします。 それができない場合は、この記事で紹介したLogstashの設定が、適用するタイミングでソースマップ取得に使用されるデフォルトのインデックスパターンに適しているので、さらに変更を加える必要はありません。 ## [フローにKafkaを導入する](フローにKafkaを導入する) Kafkaもまた、APMサーバーからElasticsearchに送るイベント出力をバッファするときに使えます。 Kafkaを使った簡単なAPMサーバーの設定は次のとおりです。 output.kafka: enabled: true hosts: ["kafka:9092"] topics: - default: 'apm' topic: 'apm-%{[context.service.name]}' ここでは1サービスに1トピックの使用をお見せしていますが、必須ではありません。 ドキュメントには、他の構成オプションも記載されています。 イベントがKafkaにフローすれば、これをElasticsearchにプルできるようLogstashを設定することができます。 たとえば以下のようにします。 input { kafka { id => "apm-server-kafka" bootstrap_servers => ["kafka:9092"] topics_pattern => "apm.*" codec => "json" } } output { elasticsearch { hosts => ["elasticsearch:9200"] index => "apm-%{[beat][version]}-%{[processor][event]}-%{+YYYY.MM.dd}" } } ここでも、1日につきトランザクションやスパンなどの1イベントタイプごとにインデックスが1件作成されます。これは、デフォルトのAPMサーバー設定が生成するときと同様です。 Logstash Kafka出力プラグインのその他の方法は、[ドキュメント](/guide/en/logstash/6.4/plugins-inputs-kafka.html)で紹介しています。 ## Give it a try APMサーバーには、LogstashやKafkaを使用したAPMデータ送信に対する柔軟性があります。 ぜひお試しになり、[ディスカッションフォーラム](https://discuss.elastic.co/c/apm)にご意見をお寄せください。 皆さんのアイデアも、いつでも歓迎しています。どうぞ自由に[ソースコード](https://github.com/elastic/apm-server)をご覧になり、問題を報告したりリクエストしたりしてください。

    Canvas:メトリック要素とマークダウン要素

    $
    0
    0

    KibanaでCanvasの要素を使用してみる

    Canvasは現在、workpad(ブログ「KibanaでCanvasを使い始める」を参照)に追加できる約20の組み込みの要素を提供しています。このブログでは、そのうちの2つ、メトリックとマークダウンのみをご紹介します。

    メトリック:

    1つのデータ値とラベルを表示する簡素化されたテキストボックス

    blog01.3.png

    マークダウン:

    handlebars.js {{variables}}およびマークダウン構文を使用して動的なデータを表示する、フル機能のテキストボックス

    注:すでにCanvasを所有しており、サンプルデータがインストールされている場合は、レビューセクションをスキップしてチュートリアル本文(メトリックの使用)に進んでください

    クイックレビュー

    まだ「KibanaでCanvasを使い始める」ブログを読んでいない場合は、これにアクセスして記載の手順を実行することを強く推奨します。今回のこのブログでは前回説明したコンセプトを基に構築すること、および読者がすでに以下の状態であることを想定しているからです。

    1. ElasticsearchおよびKibanaを使用可能(バージョン6.4以降)
    2. Canvasをインストール済み

    Canvas Workpadの作成

    1. サイドバーの[Canvas]タブをクリックします
    2. [Create workpad]をクリックします
    3. 新しいworkpadに一意の名前をつけます

    サンプルデータのインストール

    このチュートリアルでは、Elastic提供のサンプルデータセット、具体的にはsample flight dataを使用します。

    注:このデータセットはKibanaバージョン6.4以降でのみ利用可能です。

    Kibanaインスタンスにアクセスします。

    1. サイドバーでメインの[Kibana]ホームページをクリックします
    2. 「Add Data to Kibana」セクションの下部にあるリンク[Load a data set and a Kibana dashboard]をクリックします
    3. [Sample flight data]タイルで[Add]をクリックします

    blog01.gif

    クイックリファレンス

    下の表は、先ほどインストールしたサンプルデータセットの情報を示しています。太字の下線が引かれている項目はこのアクティビティの後のほうで使用しますが、その他の項目については自由に使ってみてください。

    kibana_sample_data_flights
    AvgTicketPrice
    Carrier
    DestCityName
    DestCountry
    FlightDelayType
    FlightTimeMin
    OriginCityName
    OriginCountry
    Dest
    DestAirportID
    DestLocation
    DestRegion
    DestWeather
    DistanceKilometers
    DistanceMiles
    FlightDelay
    FlightDelayMin
    FlightNum
    FlightTimeHour
    Origin
    OriginAirportID
    OriginLocation
    OriginRegion
    OriginWeather
    _id
    _index
    _score
    _type
    dayOfWeek
    hour_of_day
    timestamp

    メトリックの使用

    基本から開始

    フライトの遅延総時間(分)を導き出し、メトリック要素で表示しましょう。そのためにはSQLクエリを使用して、サンプルデータセットのFlightDelayMinフィールドから総時間を求めます。

    1. [Add Element]をクリックします
    2. [Metric]を選択します
      1. ヒント:初めて要素を作成すると、デモ用データが入った状態で表示され、すぐに各種の操作ができるようになっています。
    3. 右の編集パネルで[Data]タブを選択します
    4. [Change your data source]をクリックします
    5. [Elasticsearch SQL]を選択します
    6. SQLクエリエディターに、次のように入力します
    SELECT
        SUM(FlightDelayMin) AS delay
    FROM
        kibana_sample_data_flights
    

    詳細説明:SQLクエリは、インデックスkibana_sample_data_flightsからキー FlightDelayMinのすべてのJSON値を選択します。このデータは「delay」という名前の「column」に返されます。

    1. [Save]をクリックします

    メトリック要素には警告マークが表示されています。これは、要素が誤ったデータを指しているからです。

    1. 右の編集パネルの上部で[Display]タブを選択します
    2. 「Numbers」セクションで、次のように設定します
    • Measurement:Value
    • Field:delay
  • メトリックのラベルを次のように変更します。「Total Delay in Minutes」
  • blog03.gif

    項目のカスタマイズ

    任意の期間におけるフライトの遅延総時間を表示できるように、時間フィルターを設定します。

    1. [Add element]をクリックします
    2. [Time Filter]を選択します

    メトリック要素には警告マークが表示されています。時間フィルターはworkpadのすべての要素にすぐに適用されますが、この警告マークはその時間フィルターがまだ正しく設定されていないことを示しています。

    1. 時間フィルターをworkpadの空白の場所に移動します
    2. 時間フィルター要素のデフォルトの時間フィールドは@timestampですが、ここでは適切ではありません。時間フィルターの編集パネルで、列の値を timestamp にします(つまり@マークを削除します)
    3. [Set]をクリックします
    4. 時間フィルターをクリックし、以下の期間から選択します
    • 最近24時間
    • 最近7日間
    • 最近2週間

    注:サンプルデータは4週間分あります。サンプルデータがインストールされた日を中心として、そこから過去のデータが2週間分、未来のデータが2週間分あります。

    blog04.gif

    高度な内容

    次に、フライト遅延時間の平均を求めてみましょう。ここで表示を見やすくするためには、背後で動作するコードを少しカスタマイズすることが必要になります。

    1. 作成した最初のメトリックが選択されていることを確認します
    2. 画面の右上隅にある[Duplicate]ボタンをクリックします
    3. 新しい時間フィルターをworkpadの空白の場所に移動します
    4. メトリックのラベルを次のように変更します。「Average Delay in Minutes」
    5. [Data]タブを選択します
    6. SQLクエリエディターに、次のように入力します
    SELECT
        AVG(FlightDelayMin) AS delay
    FROM
        kibana_sample_data_flights
    
    1. [Save]をクリックします
    2. 数値のすべてが見えるようにメトリック要素を拡大します
    • 次のような数値が表示されます。47.33517114633586
    • 四捨五入したほうがいいのは明らかです
  • 右下隅の[Expression editor]をクリックします。するとコードエディターが開きます。ここで、選択した要素の表示形式を指定するコードを修正できます。
  • 表現エディターのコードの3行目に、 「math」関数が記述されています。修正する命令行はこれです
  • blog03.png

    1. ElasticはCanvasドキュメントで、使用可能な数学関数のリストを提供しています
    2. round(a,b)関数を使います
    • aは四捨五入する値
    • bは小数点以下の桁数
  • 表現エディターで3行目を変更して、下記のように四捨五入関数を含めるようにします
    1. 3行目:| math "round(delay,0)"
  • 表現エディターの右下隅にある[Run]をクリックします
  • blog05.gif

    マークダウンの使用

    基本から開始

    フライト総数を導き出してマークダウン要素に表示します。そのためには、サンプルデータセットのFlightNumフィールドに対してSQLコマンドを実行します。

    1. [Add Element]をクリックします
    2. [Markdown]を選択します
      1. ヒント:初めて要素を作成すると、デモ用データが入った状態で表示され、すぐに各種の操作ができるようになっています。
    3. 右の編集パネルで[Data]タブを選択します
    4. [Change your data source]をクリックします
    5. [Elasticsearch SQL]を選択します
    6. SQLクエリエディターに、次のように入力します
    SELECT
        FlightNum
    FROM
        kibana_sample_data_flights
    
    1. [Save]をクリックします
    2. [Display]タブをクリックします
    3. 以下のものを除き、「Markdown content」エディターからすべてを削除します
    **{{rows.length}} rows**
    

    注:マークダウン要素は、その名前が示すとおり、マークダウン構文を完全にサポートします。例:**##```、など。マークダウン構文に慣れていない方のために、上記の例では太字にするテキストを**で囲んでいます。

    1. [Apply]をクリックします
    2. これでマークダウン要素にはデータセットの列の総数、つまりフライトの総数が表示されます。テキストを次のように更新します
    Total number of flights: **{{rows.length}}**
    
    1. [Apply]をクリックします
    2. マークダウンエディターの画面右上隅にある[+]をクリックします
    3. ドロップダウンメニューで[Text Settings]を選択します
    4. テキスト設定で、次のように調節します
      1. フォントサイズ:36
      2. アラインメント:中央揃え
    5. テキストが見やすくなるようにマークダウン要素のサイズを調整します

    blog06.gif

    項目のカスタマイズ

    次に、いくつのフライトがどのような理由で遅延したかについて調べてみましょう。そのためには、FlightDelayTypeフィールドを使用します。

    1. [Add Element]をクリックします
    2. [Markdown]を選択します
    3. 右の編集パネルで[Data]タブを選択します
    4. [Change your data source]をクリックします
    5. [Elasticsearch SQL]を選択します
    6. SQLクエリエディターに、次のように入力します
    SELECT
        FlightDelayType,
        COUNT(FlightDelayType) AS count
    FROM
        kibana_sample_data_flights
    GROUP BY
        FlightDelayType
    
    1. [Save]をクリックします
    2. [Display]タブをクリックします
    3. 以下のものを除き、「Markdown content」エディターからすべてを削除します
    {{#each columns}}
     **{{name}}**
    {{/each}}
    
    1. 詳細説明:
    2. これはhandlebar.js構文です。SQLクエリで返された各列には、列の名前が出力されていますが、FlightDelayType列の各行の値を出力する必要があります。次の手順でこれを修正します。
    1. 「Markdown content」エディターで、次のように置き換えます
    • columnsrowsに置き換える
    • nameFlightDelayTypeに置き換える
  • [Apply]をクリックします
  • これで遅延タイプのリストができます。各タイプにカウントを追加しましょう。「Markdown content」エディターで、現在の内容を下記のコードに置き換えます
  • {{#each rows}}
    - {{FlightDelayType}} -- {{count}}
    {{/each}}
    
    1. 上記のコードの説明
    2. 1行目:各行に対し...
    3. 2行目:リスト項目であることを示すために「-」を入力し、2つの変数を「--」で区切って入力します
    4. 3行目:改行
    5. 4行目:ループを終了させます
    1. [Apply]をクリックします

    blog07.gif

    高度な内容

    先ほど作成したマークダウン要素では、行の1つが次のようになっています。

    No Delays -- 2856

    これは遅延について示しているのではなく、実際にはその逆で、定刻どおりに出発したフライトを示しています。この行を削除し、実際に遅延したフライトのみを表示するようにしましょう。そのためにはfilterrowsと呼ばれる、Canvasの関数を使用します。
    blog02.7.png
    1. 先ほど作成したマークダウン要素(すべての遅延タイプを表示)が選択されていることを確認します。
    2. 画面の右下隅にある「Expression editor」をクリックします。するとコードエディターが開きます。ここで、選択した要素の表示形式を指定するコードを修正できます。
    3. 表現エディターでは以下に類似した記述になっているはずです。
    filters
    | essql 
      query="SELECT
        FlightDelayType,
        COUNT(FlightDelayType) AS count
    FROM
        kibana_sample_data_flights
    GROUP BY
        FlightDelayType"
    | markdown "{{#each rows}}
    - {{FlightDelayType}} -- {{count}}
    {{/each}}"
    
    1. まずfilterrows関数でデータをパイプし、その後、マークダウン要素にパイプします。10行目に改行を挿入し、| markdown関数のすぐ上にfilterrows関数を追加します。行頭にパイプ(縦線)|を入れるのを忘れないようにしてください。
    ...
    GROUP BY
        FlightDelayType"
    <b style="background-color:#ffae5b"><i>| filterrows {}</i></b>
    | markdown "{{#each rows}}
    - {{FlightDelayType}} -- {{count}}
    ...
    
    1. FlightDelayType列に含まれている値に基づいて行をフィルターします。そのためには、getCellと呼ばれる別の関数を使用する必要があります。これによって、所定の列の各行の値が出力されます(「getCell」関数についてのドキュメントを参照)。
    | filterrows { <b style="background-color:#ffae5b"><i>getCell “FlightDelayType”</i></b> }
    
    1. 次に、anyと呼ばれる関数に、各行から値をパイプします。これは、 チェック条件に基づいてtrueまたはfalseを返します(「any」関数についてのドキュメントを参照)。
    | filterrows {getCell “FlightDelayType” <b style="background-color:#ffae5b"><i>| any {}</i></b> }
    
    1. 最後に、チェック条件について「No Delay」 に等しくないという値を返すために、neqと呼ばれる関数を使用します(「neq」関数についてのドキュメントを参照)。
    | filterrows {getCell “FlightDelayType” | any { <b style="background-color:#ffae5b"><i>neq “No Delay”</i></b> }}
    
    1. 表現エディターの右下隅にある[Run]をクリックします。「No Delay -- 2856」となっていた行が表示されなくなります。

    blog08.gif

    その他の便利なリソースリンク

    お疲れ様でした。Canvasのメトリック要素およびマークダウン要素を使用する例をいくつか見てきました。ぜひ他の要素もworkpadに追加して、Canvasのフル機能をお試しください。

    Canvasのチュートリアルはこの他にもあります。ぜひご活用ください。

    Elastic Stack 6.5.0 リリース

    $
    0
    0
    6.5.0 がリリースされました。 今回もマイナーバージョンのリリースですが、マイナーなものはありません。6.5 では、複数のユースケースに当てはまるスタックレベルの基本的な機能から、特定のユースケースに関連したすぐに利用可能なソリューション固有の機能まで、多数の新機能が導入されています。 [ダウンロード](/downloads)したり、[Elastic Cloud](/jp/cloud/elasticsearch-service/signup) でクラスターを起動して、新しい機能をお試しください。 ここでは、いくつかの機能についてご紹介します。詳細については、製品リリースの個別のリリースブログを必ず確認してください。では、いくつか紹介していきましょう。 ### インフラストラクチャとログ UI ユーザーの多くの方が、IT インフラストラクチャから運用ログとメトリックを取り込んで調査するために、Elastic Stack を使用しています。ユーザーが運用データをより容易に把握できるようにする、新しい Kibana アプリをご紹介しましょう。新しいインフラストラクチャ・ソリューションを使用すると、皆さんのインフラを概要レベルで俯瞰するところから、個別のホスト、ポッド、コンテナーののログとメトリック・アクティビティまでを容易に移動できます。 付随するログ UI は高度なログビューアーで、コンソールで`tail -f`を実行した場合と同様に、コンソールと同様にログのストリーム表示を行います。アプリの詳細については[Kibana リリースブログ](./kibana-6-5-0-released)をご覧ください ### APM 詳細は[APM のリリースブログ](/blog/elastic-apm-6-5-0-released) をトレースしてください。 - とあるリクエストに含まれる全てのマイクロサービスをトレースできる分散トレーシング - Java & Go 用のエージェント (ご要望の多かった言語) のGAリリース - APM 監視を使用すると、Elastic APM の状態を Kibana 監視アプリから追跡できます - 新しい NDJSON ベースの入力プロトコルにより、メモリのフットプリントが改善されました ### Elasticsearch ここで紹介するのは概要(aggregate view)です。詳細については[詳細のリリースブログ](/blog/elasticsearch-6-5-0-released)をご覧ください。 - クロス・クラスター・レプリケーション: クラスター間でインデックスをレプリケーションする、自己完結型の新しいメカニズム - ODBC ドライバー(Alpha): ElasticsearchへODBCをサポートしてるツールで接続 - Java 11 サポート-Elasticsearch 6.5から、 Oracle からリリースされている最新 LTS Java をサポート - G1 ガベージコレクター (G1GC) : 本リリースよりサポート - Lookup realm: あるレルム (例:Kerberos)を使用して認証して、別のレルム(例.LDAP)を使用して認可 - Machine learningが基礎となるモデリングアルゴリズムに関して2点を改善しました。(a)パーティション個別のスコアリングと (b) 複数のバケットを範囲とした異常検知です。 ### Kibana 詳しい内容は[Kibana のリリースブログ](./kibana-6-5-0-released)をご覧ください。ここでは、いくつかを簡単に紹介します。 - Canvas: Elasticsearchのデータを最新ピクセルの情報グラフィックスタイルを作成できます。Canvasは別のテクノロジプレビューとして提供されていいましたが、バージョン6.5 から Elastic Stack に含まれる形で提供を開始 - Spaces: Kibana オブジェクト (例: ビジュアル化やダッシュボード用) を別々の "空間" に整理し、RBAC を使用して、どのユーザーがどの領域にアクセスできるかを制御します。 - Kibana でのロールアップサポートでは、ロールアップジョブを構成および管理するための新しい管理 UI と、ロールアップインデックスをビジュアル化する機能が含まれます - 「Data visualizer for files」により、詳細な分析の準備としてファイル内のデータ構造を把握 - 全てのユーザーにより簡単にKibanaを触っていただくために、サンプルデータセット、ダッシュボード、Canvasのワークパッドを追加 ### Logstash 詳細については[Logstashのリリースブログ](/blog/logstash-6-5-0-released)をパース(grok)してください。 - 6.2 でベータリリースされた SNMP 入力プラグインがGAリリース - App Search出力プラグインを使用することで、Elastic App Searchにデータを供給するための一元的な ETL ツールとしてLogstash を利用できます。 ### Beats 詳細については[Beatsのリリースブログ](/blog/beats-6-5-0-released)を‘Go’(ご)覧ください。 - Beats の集中管理では、UI または API のいずれかを使用して、Beats のデプロイを一元的に登録、構成、および管理できます。 - Functionbeatが新しいBeatとしてBeatsファミリーに追加されました。これは、サーバーレスプラットフォームのファンクションとしてデプロイでき、Elasticsearchにクラウドのインフラデータを流し込めます。 ### ES-Hadoop 詳細については[ES-Hadoopのリリースブログ](/blog/es-hadoop-6-5-0-released)に'Map'してあります。 - マッピングの競合が発生した場合に、一般的なタイプにフィールドを想定する、Field type promotion機能が追加 - 7.0リリースのためのいくつかの準備として変更を追加 ### 今すぐ入手しましょう! [Elasticsearch download](/downloads/elasticsearch)[Kibana download](/downloads/kibana)[Logstash download](/downloads/logstash)[Beats download](/downloads/beats)a [ES-Hadoop download](/downloads/hadoop)[APM Server](/downloads/apm)

    Kibana 6.5.0 リリース

    $
    0
    0

    Kibana リリースの時間です! 6.5 のリリースには、スペース、ロールアップのサポート、およびCanvasなど、数多くの新しい影響の大きな機能が含まれています。また、新しいインスペクター機能やConsoleの改善など、中程度か小さな機能も備えています。

    Kibana 6.5.0をダウンロード
    Kibana 6.5.0 release notes
    Plugin API changes

    詳細については上記リリースノートに記載がありますが、中でも注目の機能は以下の通りです:

    • スペースで作業を整理する
    • データをCanvasに表示する
    • Kibanaからロールアップジョブを作成する
    • 2つの新しいサンプルデータセット
    • Consoleの改善
    • Spy パネルに代わる新しいインスペクター機能

    スペースで作業を整理する

    スペースは、最も要求の多かった機能の1つです。スペースを使用すると、保存されたオブジェクトを意味のあるカテゴリに整理できます。たとえば、sales の領域にはすべての sales のビジュアルを、ログ領域にはすべてのログ記録オブジェクトを入れます。スペースは必要に応じていくつでも作成でき、いつでもスペースを変更したり、保存したオブジェクトをスペース間で移動したりすることが可能です。セキュリティを有効にすると、どの役割およびユーザーがどのスペースにアクセスできるかを、RBAC を使用して制御できます。

    スペースを作成、編集、および削除するには、Management > Spaces を使用します。または、プログラムで作成する場合は Kibana の Spaces API のように使用できます。  iOS からの画像 =

    Canvasでプレゼンテーション(ベータ版)

    Canvasは、データを1ピクセルの完璧なデザインで表示するための新しいスペースで、 Kibana、6.5 でテストすることができます。新しいワークパッドを使用すると、静的なコンテンツ (テキスト、イメージ、および図形) とデータ駆動型の要素 (グラフ、テーブル、画像など) を組み合わせることによって、データに関するストーリーを作成することができます。既定では、各動的要素はサンプルデータソースに接続されるので、独自のデータに接続する前に、実際にテストを試すことができます。Canvas はクエリの為に、Elasticsearch: es docs、SQL、およびTimelineの複数の言語をサポートしています。

    Canvasツールには、リッチスタイル機能があり、ユーザーは静的要素と動的エレメントの両方の色とスタイルを変更できます。Canvas は、UI を使用して要素のコンテンツやスタイルを変更したり、要素の階層を深くしたり、css スタイルを作成する式を編集したりできるように設計されています。つまり、Canvasには、ライブデータの表示に必要なすべてのものが用意されています。image2.png

    ロールアップジョブを作成および管理する

    Kibana には、ロールアップジョブの作成、開始、停止、および削除を行うための新しい管理 UI があります。ロールアップは、Elasticsearch および ロールアップ を作成および管理するための API が6.4 以降で使用可能になっています。ロールアップインデックスは、履歴データを集計し、それを将来の分析のためにコンパクトにに保存するため、ストレージの一部を使用してこのデータをクエリ、集計、および視覚化できます。ロールアップジョブは、ロールアップインデックスのデータを集計する定期的なタスクです。UI に移動するには、Management に移動し、Elasticsearch のRollup Jobsをクリックします。image9.png

    可視化におけるロールアップデータの表示 (ベータ)

    Kibanaには、ロールアップされたデータを視覚化するベータ機能があります。ロールアップインデックスまたは混合ロールアップと生のインデックスを使用して、すべてのデータをまとめて視覚化するインデックスパターンを作成できます。ほとんどのビジュアル表示は、Timeline、Visual Builder、および Vega の視覚エフェクトを除いて、データのロールアップをサポートしています。また、ロールアップされたデータと未処理の情報に基づいて、視覚エフェクトを使用するダッシュボードを作成することもできます。最後に、ロールアップされた生データの両方が Discover で利用可能です。image24.png

    2 つの新しいサンプルデータセット

    新しいユーザーエクスペリエンスに合わせて調整された2つの新しいワンクリックのサンプルデータセットがあります。ビジネス分析に興味がある場合は、電子商取引のデータセットに、コスト、収益、価格など、製品に関連する情報を視覚化するものが含まれている場合は、それらをインストールします。web サイトのトラフィックを分析する場合は、web ログのサンプルデータセットを確認してください。

    サンプルデータにアクセスするには、Kibana ホームページに移動し、[Load a data set and a Kibana dashboard] をクリックします。また、従来のダッシュボードには、各サンプルがCanvasワークパッドでパッケージ化されています。電子商取引のサンプルのワークパッドには、同じデータに対して2つの異なるスタイルがあります。ワークパッドは、新しいユーザーがCanvasを学習するための手段として便利です。 image11.png

    Consoleの強化

    このリリースでは、Consoleのオートコンプリート機能が、テンプレートエンドポイントで利用可能なクエリの追加の DSL タイプ(#19178を参照)およびテンプレート(#20141を参照)に拡張されています。また、Tools ドロップダウンメニューの特定のエンドポイントのドキュメントへのリンクも追加しています。ドキュメントは、ショートカットキーの CTRL/CMD +/からも使用できます。#19715も参照ください。

    最後に、構文を強調表示してGrokデバッガーを拡張しました(#18572を参照).

    Spy パネルに代わる新しいインスペクター機能

    このリリースでは、以前の Spy パネルが新しいインスペクターツールに置き換えられています。新しいインスペクターでは常に、特定の要素の検査対象となる正しいデータが表示されます。古い Spy パネルとは対照的に、インスペクターの状態は一時ビューとして表示され、URL には格納されません。Spy パネルを使用して、基になるデータを表示する場合は、ビジュアル化と同じ集計を使用してテーブルを作成することをお勧めします。インスペクターは次のように開くことができます。

    • ダッシュボード - パネルのコンテキストメニューを使用してインスペクターを表示します。
    • ビジュアルエディター - 画面の最上部にある [Inspector] ボタンを使用します。

    みなさん、楽しい毎日を過ごせますように。
    Kibanaより


    業務コンテンツを整理して安全に保つKibanaの"space"

    $
    0
    0

    Kibanaの"space"で業務コンテンツ整理する

    バージョン6.5より、新たに"space"機能が加わりました。"space"を使うと、ダッシュボードや可視化、その他の保存済みオブジェクトをカテゴリ別に整理することができます。各spaceは独立しています。1つのspaceに入れたオブジェクトが、他のspaceに出てくることはありません。

    Kibanaを開くと、アクセスできるspaceが一覧で表示される

    Kibanaを開くと、アクセスできるspaceが一覧で表示される

    はじめて使う

    Kibanaには自動で作成される"Default"というspaceがあります。以前のバージョンからアップグレードした場合、保存済みのオブジェクトはここに入っています。

    Kibanaで開いているspaceは、いつでも画面左のナビゲーションバー下部に表示されます。ここから直接spaceの管理UIを操作して、新しいspaceを作成することもできます。 [Create space]ボタンをクリックします。

    spaces-gif.gif

    spaceの管理画面。ここでspaceを作成、編集、削除できる。

    次に作成したspaceに名前をつけ、アバターを好みに応じて調整します。

    [Create space]画面。

    [Create space]画面。

    URL識別子の注意点

    このステップで作成する識別子は、Kibanaで使用するURLの一部になります。spaceを作成する際にURLをカスタマイズすることができますが、作成後は変更できません。

    開いているspaceを把握する

    Kibanaのナビゲーションバーを確認することで、現在開いているspaceをいつでも確認できます。spaceのアバターをクリックするとメニューが表示され、別のspaceに移動することもできます。

    いつでも1クリックでspaceセレクターにアクセスできるので、手軽にspaceを切り替えることができる。

    いつでも1クリックでspaceセレクターにアクセスできるので、手軽にspaceを切り替えることができる。

    spaceを削除する

    spaceを削除するには、メニューから[Management] > [Spaces]画面に進みます。次にこの画面で、削除するspaceの横のゴミ箱アイコンをクリックします。

    spaceを削除すると、そのspaceに含まれるすべてのオブジェクトが削除され、復元することはできません。この点に注意してください。

    Kibanaでspaceを削除する際に表示される確認画面

    Kibanaでspaceを削除する際に表示される確認画面

    space間でオブジェクトを移動する

    import/export機能を使用して、spaceに保存したオブジェクトを別のspaceへ移動することができます。詳しい手順は、ブログ記事「spaceを移動する」をご参照ください。

    spaceのアクセスを安全に保つ

    ゴールドまたはプラチナライセンスでご利用の場合、各spaceのアクセス権を付与するロールを制御することができます。この機能を使うには、画面で[Management] > [Roles]に進みます。

    spaceへのアクセス権限を定義する概念は"Minimum Privilege"と呼ばれ、3つのオプションがあります。

    Minimum Privilege

    説明

    all

    ユーザーは、Kibanaのすべてのspaceに読み/書き(read/write)のアクセス権を持ちます。さらにユーザーは、Kibanaのすべてのspaceを作成、編集、削除することができます。将来追加されるspaceに対しても同じ権限を持ちます。

    read

    ユーザーは、Kibanaのすべてのspaceに読み取りのみ(read-only)のアクセス権を持ちます。将来追加されるspaceに対しても同じ権限を持ちます。

    none

    ユーザーは、Kibanaのすべてのspaceにアクセス権を持ちません。

    Minimum Privilegeを設定した後に、特定のspaceに対するアクセス権をカスタマイズすることができます。

    spaceを安全に保つ活用事例

    例:すべてのspaceに完全なアクセス権を付与する

    Minimum Privilegeを"all"に設定することで、すべてのspaceに対するアクセス権が与えられます。この設定では、特定のspaceへのアクセス権をカスタマイズすることはできません。

    Minimum Privilegeを"all"にするとKibanaへの完全なアクセス権が設定される

    Minimum Privilegeを"all"にするとKibanaへの完全なアクセス権が設定される

    例:すべてのspaceに読み取りのみのアクセスを設定し、"Marketing"spaceに完全なアクセスを付与する

    Minimum Privilegeを"read"に設定すると、すべてのspaceに対して読み取りのみのアクセス権が与えられます。この設定では、必要に応じて特定のspaceに"all"アクセスを設定することができます。一方、特定のspaceに対してアクセスを禁止することはできません。

    Minimum Privilegeを"read"にすると、すべてのspaceに対して読み取りのみのアクセス権が設定される。さらに"Marketing"spaceに完全なアクセス権を追加で設定することが可能。

    Minimum Privilegeを"read"にすると、すべてのspaceに対して読み取りのみのアクセス権が設定される。さらに"マーケティング"spaceに完全なアクセス権を追加で設定することが可能。

    例:"Executive"spaceだけに読み取りのみのアクセスを付与する

    Minimum Privilegeを"none"にすると、すべてのspaceにアクセスできません。この設定では、"Executive"spaceに読み取りのみのアクセスを追加で付与することができます。

    kibana-secure-spaces.png

    すべてのspaceの権限を表示する

    あるロールがKibanaのspaceで持つすべてのアクセス権を表示するには、[View summary of spaces privileges]リンクをクリックします。

    kibana-view-space-privileges.png

    まとめ

    Kibanaに加わったspaceは、パワフルな機能です。ダッシュボードや可視化を、これまでにない方法で整理できるようになりました。設計から新しくなったこのロール管理インターフェースをKibanaで活用することで、アクセスを安全に保つことができます。ブログ記事「Kibanaのspaceを移行する方法」もぜひ合わせてご覧ください。

    Kibanaのspaceに移行する

    $
    0
    0
    ## spaceに移行する [Kibana 6.5](/jp/downloads/kibana)より、ダッシュボードや可視化、その他の保存済みのオブジェクトを[spaceを使用して整理](/jp/blog/introducing-kibana-spaces-for-organization-and-security)できるようになりました。さらにセキュリティ機能を使用して特定のspaceにアクセス権を持つロールを制御することもできるようになりました。これにより、Kibanaの同じインスタンスを多数のユーザーで共有しつつ、各ユーザーが保存済みオブジェクトのサブセットを使用できます。 spaceをサポートするKibanaにバージョンをアップグレードすると、既存の保存済みオブジェクトはすべて"Default"というspaceに入っています。その後、以下に紹介する方法を使用してspace間でオブジェクトを移動することができます。 ## 保存済みオブジェクトをspace間で移動する 保存済みオブジェクトを1つのspaceから別のspaceに移動するには、Kibanaの[Import/Export]UIを使用します。[Import/Export]UIを使用して保存済みオブジェクトを移動する場合、関連する保存済みオブジェクトが自動的に移動しない点に留意してください。ダッシュボードとすべての依存するオブジェクトをspace間で移動させる場合は、"ダッシュボードをspaceからspaceへ移動させる"を参照してください。 たとえばあるインデックスパターンを1つのspaceから別のspaceに移動させる場合、[Management] > [Saved Objects]を開き、移動させる保存済みオブジェクトを選択してください。[Export]をクリックすると、出力したJSONの保存先を選択できます。 ![Export Saved ObjectI](https://images.contentstack.io/v3https://www.elastic.co/assets/bltefdd0b53724fa2ce/bltb8587ed72d5ce82b/5c304d635a7621286e3e90a1/Screen_Shot_2018-11-02_at_11.01.51_AM.png) 次にspaceセレクターで、別のspaceを選択します。 ![Change Space](https://images.contentstack.io/v3https://www.elastic.co/assets/bltefdd0b53724fa2ce/blt500b0284e731608b/5c304c63aab458d30b3141ec/change_space.png) spaceの変更操作を終えたら、[Management] > [Saved Objects]に戻ります。保存済みオブジェクトは各spaceごとに完全に独立しています。先ほどエクスポートしたインデックスパターンはここでは表示されていません。先ほどエクスポートしたインデックスパターンをインポートするには、[Import]をクリックして、前回JSONを保存した場所を表示します。 ![Import Saved Object](https://images.contentstack.io/v3https://www.elastic.co/assets/bltefdd0b53724fa2ce/bltb6677f6e223b6dbd/5c304d5cc05f480270a742da/Screen_Shot_2018-11-02_at_7.18.34_AM.png) これでインポートしたインデックスパターンが表示されるようになりました。 現在2つのインデックスパターンがありますが、どちらもElasticsearchの同じインデックス用のものです。各spaceで保存されたオブジェクトは独立しており、いずれかのインデックスパターンに変更を加えても、もう一方のインデックスパターンに変更が適用されることはありません。元のspaceにインデックスパターンを置いておきたくない場合、削除することもできます。コピー先のspaceにインデックスパターンがあるので、問題ありません。 ## spaceに複数テナントを統合する Kibanaのユーザー同士を隔離する目的で複数のテナントを持ち、それぞれのElasticsearchインデックスでKibanaを使用していた場合は、[Export/Import]UIで1つのテナントに統合し、spaceによる"住み分け"を行うことができます。1つのテナントからすべての保存済みオブジェクトをエクスポートするには、[Management] > [Saved Objects]に進み、ヘッダーのチェックボックスをクリックして全オブジェクトを選択し、[Export]をクリックします。 ![Export all Saved Objects](https://images.contentstack.io/v3https://www.elastic.co/assets/bltefdd0b53724fa2ce/blt6b9b91359f54fc7d/5c304d5761a626fb0b630098/Screen_Shot_2018-11-02_at_10.56.53_AM.png) 次に、JSONの保存先をたずねる画面が表示されます。 エクスポート先のspaceがまだ作成されていない場合は、保存済みオブジェクトをエクスポートしてからエクスポート先となるKibanaのインスタンスに移動し、エクスポートするspaceを作成して選択します。[Management] > [Saved Objects]に進み、[Import]を選択して保存したJSONファイルを指定します。この操作で、選択した保存済みオブジェクトをspaceにインポートすることができます。 ## spaceから別のspaceへ、ダッシュボードを移動する 個別の保存済みオブジェクトを移動させる場合は、Kibanaの[Import]/[Export]UIを使用するだけでした。しかし、ダッシュボードと、その関連の可視化や保存済みの検索、インデックスパターンなどをすべて移動させたい場合、この方法は最適とは言えません。ダッシュボードを別のspaceに移動させる場合は、[Dashboard Import/Export APIs](/guide/en/kibana/current/dashboard-import-api.html)を使用します。 ### ダッシュボードのエクスポート ダッシュボードをエクスポートする場合、はじめにダッシュボードのIDを特定する必要があります。エクスポートするダッシュボードを開き、URLを確認します。URLの中で、`/app/kibana#/dashboard/`と`?`の間にある識別子がIDです。以下のURLで、強調表示されている部分がダッシュボードIDです。 http://localhost:5601/s/marketing/app/kibana#/dashboard/d203dd90-deac-11e8-869e-d73106bbd5ad?_g=() ダッシュボードのspaceについても、URLを使用して識別子を確認することができます。spaceの識別子は、URLの`/s/`と`/app/kibana#dashboard`の間にあります。URLに`/s/`が入っていない場合は、Defaultのspaceということになります。APIも含め、すべてのKibanaのURLのspace識別子は`/s/{spaceID}`という形式を用い、相互に区別しています。ただし、Defaultのspaceでは例外で、このようなプリフィックスが入りません。以下のURLで、強調表示されている部分がspaceの識別子です。 http://localhost:5601/s/marketing/app/kibana#/dashboard/d203dd90-deac-11e8-869e-d73106bbd5ad?_g=() ダッシュボードのIDがわかったので、以下と類似のCURLコマンドを`{spacePrefix}/api/kibana/dashboards/export?dashboard={dashboardID}`に対して使用して`GET`リクエストを実行します。これで`marketing`スペースからID`d203dd90-deac-11e8-869e-d73106bbd5ad`のダッシュボードをエクスポートし、ダッシュボードと依存するオブジェクトをexport.jsonファイルに保存できます。 curl -u elastic:changeme http://localhost:5601/s/marketing/api/kibana/dashboards/export?dashboard=d203dd90-deac-11e8-869e-d73106bbd5ad > export.json 同様に、次のCURLはDefaultのspaceからID`d203dd90-deac-11e8-869e-d73106bbd5ad`のダッシュボードをエクスポートし、export.jsonファイルに保存します。 curl -u elastic:changeme http://localhost:5601/api/kibana/dashboards/export?dashboard=d203dd90-deac-11e8-869e-d73106bbd5ad > export.json ### ダッシュボードをインポートする さて、最も難しい作業が無事に終わりました。これで新しいspaceにダッシュボードをインポートすることができます。まずインポート先のspaceのURLに含まれる識別子を特定し、URLに表示されるspaceプリフィックスを構築します。spaceセレクターを使用してダッシュボードの移動先となるspaceを選択し、URLをエクスポートの際と同じ要領で確認します。 これで、先ほど保存したexport.jsonを使用し、 <`{spacePrefix}/api/kibana/dashboards/import` に対する`POST`リクエストを実行する準備が整いました。次のCURLコマンドで、ダッシュボードを"sales"spaceにインポートできます。 curl -H “Content-Type: application/json” -H “kbn-xsrf: true” -u elastic:changeme http://localhost:5601/s/sales/api/kibana/dashboards/import --data-binary @export.json 同じ要領で、"Default"spaceにダッシュボードをインポートする場合は次のCURLコマンドを使用します。 curl -H “Content-Type: application/json” -H “kbn-xsrf: true” -u elastic:changeme http://localhost:5601/api/kibana/dashboards/import --data-binary @export.json ダッシュボードのインポートが完了し、元のspaceにダッシュボードを保持する必要がないと感じる場合は、削除することができます。 ## はじめましょう Kibanaのspaceは、ダッシュボードや可視化を整理したり、グループ化する際に非常に役立ちます。より多くのユーザーでKibanaを使用できるようにしたり、ワークフローを実装するなどさまざまな目的に使えます。お気に入りのspace活用法を見つけて、ぜひ[フォーラムで共有](https://discuss.elastic.co/c/kibana)してください。

    Canvas: データ表要素とデバッグ要素

    $
    0
    0

    Canvasは現在、workpadに追加できる約20の組み込みの要素(一覧についてはブログ「KibanaでCanvasを使い始める」を参照)を提供しています。このブログでは、そのうちの2つ、データ表およびデバッグ要素のみをご紹介します。

    image16.png

    データ表

    高度に柔軟かつ動的な表です。初期状態のままで、スクロール、ページネーション、カスタムCSSがサポートされます。

    image2.png

    デバッグ

    背後で動作するJSONデータへのアクセスを提供し、発生する問題をより正確に分析できます。

    ここでは具体的に、非常に馴染みのあるデータ表である空港のフライト発着表を作成するためにCanvasを使用します。
    下記がCanvasで作成する表の完成例です。

    要件とレビュー

    読者の環境が以下の条件を満たしていることを前提に、ブログ「KibanaでCanvasを使い始める」で説明した概念に基づき作成します。

    1. ElasticsearchおよびKibanaが稼働中(バージョン6.4以降)
    2. Canvasをインストール済み(CanvasはKibanaバージョン6.5以降に組み込み)

    サンプルデータのインストール

    このチュートリアルでは、Elastic提供のサンプルデータセット、具体的にはsample flight dataを使用します。

    注:このデータセットはKibanaバージョン6.4以降でのみ使用できます。

    Kibanaインスタンスにアクセスします。

    1. サイドバーでメインの[Kibana]ホームページをクリックします
    2. Add Data to Kibana」セクションの下部にあるリンク「Load a data set and a Kibana dashboard」をクリックします
    3. Sample flight data]タイルで[Add]をクリックします

    クイックリファレンス

    下記の表は、先ほどインストールした、フライトのサンプルデータセットの情報を示しています。太字の下線が引かれている項目は、このアクティビティの後のほうで使用しますが、その他の項目については自由に使ってみてください。

    kibana_sample_data_flights
    AvgTicketPrice
    Cancelled
    Carrier
    DestCityName
    DestCountry
    FlightDelayType
    FlightTimeMin
    OriginCityName
    OriginCountry
    Dest
    DestAirportID
    DestLocation
    DestRegion
    DestWeather
    DistanceKilometers
    DistanceMiles
    FlightDelay
    FlightDelayMin
    FlightNum
    FlightTimeHour
    Origin
    OriginAirportID
    OriginLocation
    OriginRegion
    OriginWeather
    _id
    _index
    _score
    _type
    dayOfWeek
    hour_of_day
    timestamp

    空港の発着表の作成

    作成

    最初にworkpadを作成し、次にデータ表にデータを追加します。

    Canvas Workpadの作成

    1. Kibanaインスタンスにアクセスします
    2. サイドバーの[Canvas]タブをクリックします
    3. Create workpad]をクリックします
    4. 新しいworkpadに一意の名前をつけます

    データ表要素の作成

    1. Add element]ボタンをクリックします
    2. Data Table]要素を選択します
      1. ヒント:初めて要素を作成すると、デモ用データが入った状態で表示されるため、すぐに各種の操作ができます。
    3. 右の編集パネルで[Data]タブを選択します
    4. Change your data source]をクリックします
    5. Elasticsearch SQL]を選択します
    6. SQLクエリエディターに、次のように入力します
    SELECT
      DestCityName AS Destination,
      timestamp AS Time,
      Carrier AS Airline,
      FlightNum AS Flight,
      FlightDelayType AS Status,
      Cancelled
    FROM
      kibana_sample_data_flights
    

    注:このサンプルデータセットには空港のゲート番号のフィールドが含まれていません。このブログの後のほうで、ランダムに番号を生成し、その列を作成します。

    1. Save]をクリックします
    2. 以下のようなデータ表ができているはずです

    image12.png

    コード

    これでデータが入力されたデータ表ができましたが、望んでいる形式にはなっていません。背後で動作するコードを表示し、調整する必要があります。

    Time列の形式の調整

    1. データ表が選択されていることを確認します
    2. 画面の右下隅にある[Expression editor]をクリックします
    3. 式エディター内に次のコードが見つかるはずです
    filters
    | essql
      query="SELECT
      DestCityName AS Destination,
      timestamp AS Time,
      Carrier AS Airline,
      FlightNum AS Flight,
      FlightDelayType AS Status,
      Cancelled
    FROM
      kibana_sample_data_flights"
    | table
    | render

    分類 -- このコードには次の4つのメインセクションがあります。

      1. フィルター: Time Filter要素をこのworkpadに追加すると、このデータ表要素に入力されたデータには最初に時間フィルターが適用されて、フィルターで除外されなかったデータのみが表示されることになります。この行を消去すると、データ表要素はworkpadに追加されるどのフィルター要素にも影響を受けることがなくなり、状況によっては便利です。
      2. データソース: Elastic SQLデータソースを使用しているため、ここでもSQLクエリの表示と編集ができます。
      3. 要素: この行は、workpadに表示する要素のタイプを定義します。試してみる場合は、「table」を「shape」に変更し、次に右下隅の[Run]をクリックして、どうなるか見てみましょう。元に戻すことを忘れないようにしてください。
      4. レンダリング: 要素の表示の見た目をカスタマイズできます。このブログの後のほうで、データ表をよりスタイリッシュにするために、カスタムのCSSをレンダリング関数に追加します。
    1. table」要素の関数で表示する前に、データを修正する必要があります。そのために、「essql」データソース関数と「table」要素の関数の間に、「mapColumn」という新しい関数を追加します。 この関数「mapColumn」は単に任意の列の値を修正するためのものです。ここで修正しようとしている列は「Time」列です。そのため、12列目に次のコードを追加します。
    ...
    FROM kibana_sample_data_flights"
    <b style="background-color:#ffae5b"><i>| mapColumn Time fn={}</i></b>
    | table
    ...
    1. Canvasには、「formatdate」関数など、利用可能な多くの組み込みの関数が用意されています。ここでは時間を「hh:mm A」の形式で表示します。そのために、コードの12行目に以下を追加します。
    ...
    FROM kibana_sample_data_flights"
    | mapColumn Time fn={ <b style="background-color:#ffae5b"><i>formatdate “hh:mm A”</i></b> }
    | table
    ...
    1. 式エディターの右下隅にある[Run]をクリックします
    2. すると、エラーになりました。デバッグが必要です

    デバッグの時間(この手順をスキップしないでください)

    後ですぐにコードに戻りますが、まずはCanvasでのデバッグ方法を見てみましょう。

    エラーの特定

    1. 表要素の警告シンボルをクリックします。
    2. 下図のように、エラーの原因が表示されるはずです。

    image17.png

    1. mapColumn」関数がタイムスタンプデータを「number」にキャストしようとしているようです。これは、使用している「formatdate」関数が、数値形式のタイムスタンプ(UTCミリ秒など)を要求しているからです。
    2. 実際には、どのようなタイムスタンプ形式になっているのでしょうか。それを解明するために、「debug」要素を追加しましょう。

    デバッグ要素の追加

    1. Add element]をクリックします
    2. Debug]要素を選択します
    3. 右の編集パネルで[Data]タブを選択します
    4. Change your data source]をクリックします
    5. Elasticsearch SQL]を選択します
    6. SQLクエリエディターに、次のように入力します
    SELECT
      DestCityName AS Destination,
      timestamp AS Time,
      Carrier AS Airline,
      FlightNum AS Flight,
      FlightDelayType AS Status,
      Cancelled
    FROM
      kibana_sample_data_flights
    1. [Save]をクリックします
    2. デバッグ要素では、[Time]フィールドのタイプが「date」になっており、最初のエントリーは次のようになっています:2018-11-05T00:00:00.000Z
      image9.png
    3. ありがたいことに、Canvasには 「date」タイプをUTCミリ秒の数値に変換できる機能が組み込まれています。
    4. データ表を再度選択し、下記のとおり式エディターでコードに「date」関数を追加します。
    | mapColumn Time fn={<b style="background-color:#ffae5b"><i> date | </i></b>formatdate “hh:mm A” }
    1. Run]をクリックします
    2. データ表に適切な形式でタイムスタンプが表示されます。

    image6.png

    ヒント:毎回、デバッグ要素を追加する必要はありません。どの要素の式エディターでも、コード | render as="debug"を追加して、その要素のJSONを見ることができます。ただし、作業中の参照用として、専用のデバッグ要素を準備しておくと便利です。

    では、通常のプログラムに戻りましょう。

    コードの続き

    次に、「Gate」列を追加しましょう。このデータセットにはゲートのデータが含まれていないため、Canvasに組み込まれている強力な機能を使用してランダムに生成します。

    ゲートのデータの追加

    1. 列を追加する最も簡単な方法は、SQLクエリにエントリーを追加することです。単純に「FlightNum」データを追加し、新しい列の名称を「Gate」にします。
    2. 右側のエディターパネルで[Data]タブをクリックし、SQLエディターで次の行を追加します。
    SELECT
      DestCityName AS Destination,
      timestamp AS Time,
      Carrier AS Airline,
      FlightNum AS Flight,
      <b style="background-color:#ffae5b"><i>FlightNum AS Gate,</i></b>
      FlightDelayType AS Status,
      Cancelled
    FROM
      kibana_sample_data_flights
    1. Save]をクリックします
    2. 式エディターで、1行目の下にもう1つ「mapColumn」関数を追加します。今回は「Gate」列を修正します。
    ...
    | mapColumn Time fn={ date | formatedate “hh:mm A” }
    <b style="background-color:#ffae5b"><i>| mapColumn Gate fn={}</i></b>
    | table
    ...
    1. 実際のゲート番号を取得するには、1~100の間の数字をランダムに生成する必要があります。ありがたいことに、Canvasには活用できる数学関数がいくつか組み込まれています。 ここで「random」関数を使用しますが、この関数では小数点以下の桁数の多い数字をランダムに生成するため、求めているものにはなりません。そこで、2つ目の関数を追加します。ランダムに生成した数字を四捨五入する「round」関数です。コードは次のようになります。
    | mapColumn Gate fn={ <b style="background-color:#ffae5b"><i>math "round(random(0,100),0)"</i></b> }
    1. Run]をクリックします
    2. これで、新しい「Gate」列にはすべて、ランダムに生成されたゲート番号が表示されるはずです。

    image5.png

    列の結合

    値が「true」のときは常に「Cancelled」ステータスが表示されるように、「Cancelled」列を「Status」列と組み合わせる必要があります。

    1. データ表要素が選択されていること、および式エディターが開いていることを確認します
    2. mapColumn」関数をもう1つ追加する必要がありますが、今回は「Status」列に追加します
    ...
    | mapColumn Gate fn={math "round(random(1,100),0)"}
    <b style="background-color:#ffae5b"><i>| mapColumn Status fn={}</i></b>
    | table
    ...
    1. 次に、「Cancelled」列のフィールド(または「cell」)が「true」になっているかどうかを確認する必要があります
    | mapColumn Status fn={<b style="background-color:#ffae5b"><i>if {getCell "Cancelled" | eq true}</i></b>}
    1. そして、条件がtrueの場合に「Status」列の値が文字列「Cancelled」になるように設定します
    | mapColumn Status fn={if {getCell “Cancelled” | eq true}<b style="background-color:#ffae5b"><i> then=”Cancelled” </i></b>}
    1. ここで[Run]をクリックすると、「Cancelled」を「Status」列にマッピングできます。ただし、true以外の場合については「Status」の値が「null」値になります。 image4.png
    1. 最後に必要な作業は、「Status」列の値が「Cancelled」ではない場合に、元の値を維持するようCanvasに指示することです。
    | mapColumn Status fn={if {getCell “Cancelled” | eq true} then=”Cancelled”<b style="background-color:#ffae5b"><i> else={getCell "Status"}</i></b>}
    1. Run]をクリックします
    2. これで、「Status」列を「Cancelled」列と組み合わせることができました。

    image8.png

    列の削除

    これで「Status」列に、必要な情報をすべて含めることができたので、「Cancelled」列を表示する必要がなくなりました(背後では機能している必要があります)。そのため、「Cancelled」列を削除します。

    1. データ表要素が選択されていること、および式エディターが開いていることを確認します
    2. Canvasには、列を含めるまたは除外するのに使用する「columns」という関数があります。ここでは「Cancelled」列を除外します。次のとおり、コードを1行追加します。
    ...
    | mapColumn Status fn={if {getCell “Cancelled” | eq true} then=”Cancelled” else={getCell “Status”}}
    <b style="background-color:#ffae5b"><i>| column exclude=”Cancelled”</i></b>
    | table
    ...
    1. Run]をクリックします
    2. 背後ではその列のデータを使用していますが、データ表要素に「Cancelled」列が表示されなくなっているはずです。

    image10.png

    カスタマイズ

    これで望むとおりのデータがすべて揃いました。次は、workpadの表示の見た目をカスタマイズしてみましょう。

    背景色の設定

    1. workpadで色が何も選択されていないことを確認します
    2. ページ右側の編集パネルで[Page Background]カラーピッカーをクリックし、値を「#0276fd」に設定します

    image15.png

    ページネーションの削除

    1. データ表要素を選択します
    2. ページの右側の編集パネルで、[Display]タブを選択します
    3. Table Style]パネルの[+]ボタンをクリックします
    4. ドロップダウンから[Pagination]を選択します
    5. 切り替えボタンをクリックしてオフにします

    image18.png

    表の行数の設定

    1. 再度、[Table Style]パネルの[+]ボタンをクリックします
    2. ドロップダウンから[Rows per page]を選択します
    3. ページごとの行数を25に増やします
    4. 実際には18行にするので、データ表要素の式エディターを開き、「perPage」の値を18に変更します
    | table paginate=false perPage=<b style="background-color:#ffae5b"><i>18</i></b>
    1. Run]をクリックします
    2. 18行すべてが表示されるようにデータ表要素を広げます

    表テキストのスタイル設定

    1. 再度、[Table Style]パネルの[+]ボタンをクリックします
    2. 今回は[Text Settings]を選択します
    3. テキストを太字に、色をホワイトに設定します

    表ヘッダーのスタイル設定

    1. 表の他の行よりも目立つように、表のヘッダーのスタイルを設定します。すでに[Table Style]パネルでできることは見てきたので、ここではカスタムCSSを使います
    2. そのためには、[Element Style]パネルの[+]ボタンをクリックします
    3. ドロップダウンメニューから[CSS]を選択します
    4. CSSエディターの内容を消去し、次のコードをCSSエディターにペーストします
    canvasDataTable__th { text-decoration: underline; background-color: #d0e9ff; color: black;}
    1. Apply stylesheet]をクリックします
    2. これで表のヘッダーには、薄いブルーの背景色とブラックの下線が引かれたテキストが表示されるはずです

    表の行のスタイル設定

    1. 表の行の色が交互になるよう設定するために、ここでもカスタムCSSを使用します
    2. 次のコードをCSSエディターにペーストします
    .canvasDataTable__tbody>:nth-child(even) {
    background-color: #2a2a50;
    }
    
    .canvasDataTable__tbody>:nth-child(odd) {
    background-color: #5f67af;
    }
    1. Apply stylesheet]をクリックします
    2. workpadの幅に合うようにデータ表要素の幅を調整します
    3. 下図のように、行の色が交互になるように表示されるはずです

    タイトルの追加

    1. Add element]をクリックします
    2. Markdown]要素を選択します
    3. 画面右側の[Markdown content]エディターにあるすべてのテキストを削除します
    4. Markdown content]エディターに「Departures」と入力します
    5. Apply]をクリックします
    6. Markdown]要素のサイズを調整し、画面の中央に揃えます
    7. 右側の編集エリアにある [Markdown]パネルで、[+]ボタンをクリックします
    8. ドロップダウンメニューから[Text Settings]を選択します
    9. テキストを次のとおりに設定します
      1. サイズ:48
      2. フォント:太字
      3. アラインメント:中央揃え
      4. 色:ホワイト
    10. これで、実際に空港で見るものによく似たworkpadが完成したはずです。

    完成したコード

    下記は、式エディターでのデータ表の完全なコードです。

    filters
    | essql
      query="SELECT
      DestCityName AS Destination,
      timestamp AS Time,
      Carrier AS Airline,
      FlightNum AS Flight,
      FlightNum AS Gate,
      FlightDelayType AS Status,
      Cancelled
    FROM
      kibana_sample_data_flights
    "
    | mapColumn "Time" fn={date | formatdate "hh:mm A"}
    | mapColumn "Gate" fn={math "round(random(1,100),0)"}
    | mapColumn "Status" fn={if {getCell "Cancelled" | eq true} then="Cancelled" else={getCell "Status"}}
    | columns exclude="Cancelled"
    | table paginate=false perPage=18
     font={font family="'Open Sans', Helvetica, Arial, sans-serif" size=14 align="left" color="#FFFFFF" weight="bold" underline=false italic=false}
    | render
     css=".canvasDataTable__th { text-decoration: underline; background-color: #d0e9ff; color: black;}
    .canvasDataTable__tbody>:nth-child(even) {
    background-color: #2a2a50;
    }
    .canvasDataTable__tbody>:nth-child(odd) {
    background-color: #5f67af;
    }"

    その他の便利なリソースリンク

    お疲れ様でした。Canvasのデータ表要素およデバッグ要素を使用する例をいくつか見てきました。ぜひ他の要素もworkpadに追加して、Canvasのフル機能をお試しください。

    Canvasのブログ記事はこの他にもあります。ぜひご活用ください。

    バナー画像:MPD01605による「Miami Airport Screen」はCC BY 2.0 によって許可を得ています。

    検索順位を自在に操る

    $
    0
    0

    検索順位を決める要素

    Elasticsearchは、スケーラブルで高速なリアルタイムの検索・分析エンジンです。文字列、数値、日時、地理情報など、指定された条件にしたがってインデックスされたドキュメントを検索し、一致するものを利用者に返します。数値、日時、地理情報であれば、「価格が1000円」以上、「今週入荷した商品」、「東京都庁から100km以内」などといった条件をもとに検索ができ、条件に一致するドキュメントのスコアは全て同一です。文字列を条件に指定した場合には、検索対象の文字列の長さや、条件に一致した句の数や頻度などに応じて、それぞれのドキュメントのスコアは異なり、順位付けがなされます。

    ただ、検索機能をアプリケーションに実装する場合、検索順位を制御したい場合が多々あります。「1000円以上の商品を安い順」「今週入荷した商品を新しい順」「東京都庁から近い順」に並べるといった場合です。それらのうち、複数の条件を組み合わせたい場合もあるでしょう。Elasticsearchを使用して、どのように実装したら良いでしょうか。

    フルーツのオンラインショッピングサイトを想定し、以下のような商品テーブルを用意します。

    arrival_date name origin.prefecture origin.location price promotion
    2018-12-02 Tsugaru Apple Aomori 40.82,140.73 310 2
    2018-11-29 Shinano Apple Nagano 36.65,138.17 280 10
    2018-12-04 Fuji Apple Akita 39.69,139.78 150 1
    2018-12-04 Mikkabi Mandarine Orange Shizuoka 34.97,138.38 80 1
    POST items/doc/_bulk
    {"index":{}}
    {"arrival_date":"2018-12-02","name":"Tsugaru Apple","origin":{"prefecture":"Aomori","location":"40.82,140.73"},"price":310,"promotion":2}
    {"index":{}}
    {"arrival_date":"2018-11-29","name":"Shinano Apple","origin":{"prefecture":"Nagano","location":"36.65,138.17"},"price":280,"promotion":10}
    {"index":{}}
    {"arrival_date":"2018-12-04","name":"Fuji Apple","origin":{"prefecture":"Akita","location":"39.69,139.78"},"price":150,"promotion":1}
    {"index":{}}
    {"arrival_date":"2018-12-04","name":"Mikkabi Mandarine Orange","origin":{"prefecture":"Shizuoka","location":"34.97,138.38"},"price":80,"promotion":1}
    

    商品の「入荷日(arrival_date )」、「商品名(name)」、「生産地(origin.location)」、「価格(price)」、「販促度(promotion)」フィールドを用意しました。利用者は「商品名」のみで検索しますが、「入荷日」が新しいもの、フラッシュセール用の「販促度」が高いものが、より上位に表示されるように試みてみます。

    注意:本項に使用しているインデックスやクエリはこちらで入手できます。予期した通り動作させるためには、適切に「入荷日(arrival_date )」などを調整する必要があります。クエリのnow2018-12-06とすることもできます。

    好ましくない方法 - スクリプトスコア(Script Score)

    まずはじめに思いつくのは、ユーザが検索したキーワードに該当するドキュメントから、「入荷日(arrival_date)」と「販促度(promotion)」を要素としてスクリプトにより点数付けし、各ドキュメントのスコアを上書きするものです。これは、Function Scoreクエリの、Script Scoreを用いて実現できます。

    アプリケーションは、Elasticsearchに以下のようなクエリをリクエストすることができます。

    GET items/_search
    {
      "query": {
        "function_score": {
          "score_mode": "sum",
          "query": {
            "match": {
              "name": "apple"
            }
          },
          "script_score": {
            "script": "doc['promotion'].value - (new Date().getTime() - doc['arrival_date'].value.toInstant().toEpochMilli()) / 1000000 / 60"
          }
        }
      }
    }
    

    script_scoreで、「入荷日(arrival_date)」から現在の経過日数を求め、「販促度(promotion)」から引いています。「販促度(promotion)」が高く、より新鮮な商品が上位に表示されることになります。

    実際に多くElasticsearchユーザーが、このような方法を用いています。では、なぜ好ましくないのでしょうか。それは、Elasticsearchはスクリプトを実行するために、マッチクエリーで一致したドキュメント全ての、「入荷日(arrival_date)」フィールドと、「販促度(promotion)」にアクセスし、それぞれのドキュメントでスクリプトを用いて計算を行い、求められた値にしたがって検索順位を並べ替える必要があるからです。プロファイルAPIを用いて観察してみると、scoreに多くの時間(本例では267,863ナノ秒)が割かれていることがわかります。

    {
      "took" : 0,
      "timed_out" : false,
      "_shards" : {
        "total" : 1,
        "successful" : 1,
        "skipped" : 0,
        "failed" : 0
      },
      "hits" : {
        "total" : 3,
        "max_score" : 2.0,
        "hits" : [
          {
            "_index" : "items",
            "_type" : "doc",
            "_id" : "2",
            "_score" : 2.0,
            "_source" : {
              "arrival_date" : "2018-11-29",
              "name" : "Shinano Apple",
              "origin" : {
                "prefecture" : "Nagano",
                "location" : "36.65,138.17"
              },
              "price" : 280,
              "promotion" : 10
            }
          },
          {
            "_index" : "items",
            "_type" : "doc",
            "_id" : "3",
            "_score" : 0.0,
            "_source" : {
              "arrival_date" : "2018-12-04",
              "name" : "Fuji Apple",
              "origin" : {
                "prefecture" : "Akita",
                "location" : "39.69,139.78"
              },
              "price" : 150,
              "promotion" : 1
            }
          },
          {
            "_index" : "items",
            "_type" : "doc",
            "_id" : "1",
            "_score" : -2.0,
            "_source" : {
              "arrival_date" : "2018-12-02",
              "name" : "Tsugaru Apple",
              "origin" : {
                "prefecture" : "Aomori",
                "location" : "40.82,140.73"
              },
              "price" : 310,
              "promotion" : 2
            }
          }
        ]
      },
      "profile" : {
        "shards" : [
          {
            "id" : "[3AvCgesDSpqiSKQR2y_qPA][items][0]",
            "searches" : [
              {
                "query" : [
                  {
                    "type" : "FunctionScoreQuery",
                    "description" : "function score (name:apple, functions: [{scriptScript{type=inline, lang='painless', idOrCode='doc['promotion'].value - (new Date().getTime() - doc['arrival_date'].value.toInstant().toEpochMilli()) / 1000000 / 60', options={}, params={}}}])",
                    "time_in_nanos" : 366579,
                    "breakdown" : {
                      "score" : 267863,
                      "build_scorer_count" : 7,
                      "match_count" : 0,
                      "create_weight" : 4120,
                      "next_doc" : 16184,
                      "match" : 0,
                      "create_weight_count" : 1,
                      "next_doc_count" : 6,
                      "score_count" : 3,
                      "build_scorer" : 78395,
                      "advance" : 0,
                      "advance_count" : 0
                    }
                  }
                ],
                "rewrite_time" : 3536,
                "collector" : [
                  {
                    "name" : "CancellableCollector",
                    "reason" : "search_cancelled",
                    "time_in_nanos" : 286452,
                    "children" : [
                      {
                        "name" : "SimpleTopScoreDocCollector",
                        "reason" : "search_top_hits",
                        "time_in_nanos" : 275455
                      }
                    ]
                  }
                ]
              }
            ],
            "aggregations" : [ ]
          }
        ]
      }
    }
    

    減衰(Decay)関数を検討する

    Function Scoreクエリでは、指定した値から遠ざかるほどスコアが下がる、Decay Functionを利用できます。指定した原点から遠ざかるほど、検索スコアが下がり、複数の条件を指定したり、減衰度を調整することができます。以下のようなクエリで実現することができます。

    GET items/_search
    {
      "query": {
        "function_score": {
          "score_mode": "sum",
          "query": {
            "match": {
              "name": "apple"
            }
          },
          "functions": [
            {
              "linear": {
                "arrival_date": {
                  "origin": "now",
                  "scale": "7d",
                  "offset": "0d"
                }
              }
            },
            {
              "linear": {
                "promotion": {
                  "origin": "10",
                  "scale": "10",
                  "offset": "0"
                }
              }
            }
          ]
        }
      }
    }
    

    まず、「商品名(name)」にappleが含まれるものを検索します。さらに「入荷日(arrival_date)」が現在より遠ざかるほど、直線的(Linear)にスコアが下がります。そして同様に、「販促度(promotion)」が10から遠ざかるに連れて、スコアが下がり、これら3つのスコアを足した(sum)ものをスコアとします。スコア自身はscript_scoreとは異なりますので、検索の順位は異なる可能性がありますが、「入荷日」が新しいもの、フラッシュセール用の「販促度」が高いものを上位にするという要件を満たせることがわかります。

    さらに、プロファイルAPIを使用すると、より少ないコスト(計算時間)のscoreで(本例では24,824ナノ秒)、レスポンスが得られることが確認できます。

    {
      "took" : 0,
      "timed_out" : false,
      "_shards" : {
        "total" : 1,
        "successful" : 1,
        "skipped" : 0,
        "failed" : 0
      },
      "hits" : {
        "total" : 3,
        "max_score" : 0.58585125,
        "hits" : [
          {
            "_index" : "items",
            "_type" : "doc",
            "_id" : "2",
            "_score" : 0.58585125,
            "_source" : {
              "arrival_date" : "2018-11-29",
              "name" : "Shinano Apple",
              "origin" : {
                "prefecture" : "Nagano",
                "location" : "36.65,138.17"
              },
              "price" : 280,
              "promotion" : 10
            }
          },
          {
            "_index" : "items",
            "_type" : "doc",
            "_id" : "3",
            "_score" : 0.5511543,
            "_source" : {
              "arrival_date" : "2018-12-04",
              "name" : "Fuji Apple",
              "origin" : {
                "prefecture" : "Akita",
                "location" : "39.69,139.78"
              },
              "price" : 150,
              "promotion" : 1
            }
          },
          {
            "_index" : "items",
            "_type" : "doc",
            "_id" : "1",
            "_score" : 0.5164573,
            "_source" : {
              "arrival_date" : "2018-12-02",
              "name" : "Tsugaru Apple",
              "origin" : {
                "prefecture" : "Aomori",
                "location" : "40.82,140.73"
              },
              "price" : 310,
              "promotion" : 2
            }
          }
        ]
      },
      "profile" : {
        "shards" : [
          {
            "id" : "[3AvCgesDSpqiSKQR2y_qPA][items][0]",
            "searches" : [
              {
                "query" : [
                  {
                    "type" : "FunctionScoreQuery",
                    "description" : "function score (name:apple, functions: [{org.elasticsearch.index.query.functionscore.DecayFunctionBuilder$NumericFieldDataScoreFunction@84ef9e63}{org.elasticsearch.index.query.functionscore.DecayFunctionBuilder$NumericFieldDataScoreFunction@7ed62d90}])",
                    "time_in_nanos" : 148424,
                    "breakdown" : {
                      "score" : 24824,
                      "build_scorer_count" : 7,
                      "match_count" : 0,
                      "create_weight" : 55157,
                      "next_doc" : 2485,
                      "match" : 0,
                      "create_weight_count" : 1,
                      "next_doc_count" : 6,
                      "score_count" : 3,
                      "build_scorer" : 65941,
                      "advance" : 0,
                      "advance_count" : 0
                    }
                  }
                ],
                "rewrite_time" : 3466,
                "collector" : [
                  {
                    "name" : "CancellableCollector",
                    "reason" : "search_cancelled",
                    "time_in_nanos" : 37957,
                    "children" : [
                      {
                        "name" : "SimpleTopScoreDocCollector",
                        "reason" : "search_top_hits",
                        "time_in_nanos" : 30003
                      }
                    ]
                  }
                ]
              }
            ],
            "aggregations" : [ ]
          }
        ]
      }
    }
    

    減衰(Decay)関数を地理情報に応用する

    減衰(Decay)ファンクションが適用可能なのは、数値や日付時刻だけに限らず、地理情報にも適用できます。ある地点から遠ざかるほどスコアが下がるという検索は、タクシーの配車イベントのチケット販売デーティングアプリケーションなど、様々なケースで容易に応用できます。フルーツのオンラインショッピングサイトにおいて、生産者直送の地産地消を推進するのであれば、以下のようなクエリで、購入者から地理的に近い商品を勧めることもできます。

    GET items/_search
    {
      "query": {
        "function_score": {
          "score_mode": "sum",
          "query": {
            "match": {
              "name": "apple"
            }
          },
          "linear": {
            "origin.location": {
              "origin": "35.68,139.69",
              "offset": "0",
              "scale": "300km"
            }
          }
        }
      }
    }
    

    まとめ

    検索順位を柔軟に、かつ自在に制御するヒントは得られましたでしょうか。パフォーマンスの観点からは、なるべくスクリプトによるスコア計算は、避けることが望ましいですし、Elasticsearchが提供している減衰(Decay)ファンクションは、より低コストで検索順位を制御できる機会を提供しますので、第一の候補として検討してください。

    また、アプリケーション検索に特化した当社のサービスである、Elastic App Searchを用いると、GUIを用いて関連性をチューニングすることができます。条件に応じた検索結果をその場でリアルタイムに確認できたり、アプリケーション開発者の手を煩わせることなく検索順位を制御することができます。この他にも便利なAPIや検索UIのリファレンスなども提供していますので、アプリケーション開発の工数を著しく削減します。ぜひお試しください。

    CanvasとElasticsearchを活用した空港セキュリティオペレーション監視

    $
    0
    0

    Crimson Macawは英国を拠点とするコンサルティング企業です。本記事は、マンチェスター・エアポート・グループ向けに実施したプロジェクト事例をご紹介します。このプロジェクトはロンドン・スタンステッド空港のセキュリティオペレーション向けにリアルタイムダッシュボードを実装するというものでした。

    ダッシュボードの目的は、乗客のフローとセキュリティパフォーマンスを制御室とセキュリティスタッフによりわかりやすく表示し、リアルタイムデータに基づいてすばやく判断を下せるようにすることです。そのため、複数のオンプレミスシステムと外部データソースからデータを投入し、いくつもの巨大なスクリーンに可視化して表示する必要がありました。

    データ投入の課題

    データのストレージレイヤーにElasticsearchを導入すると決まった後は、どのデータを、どのように投入するか決定する必要があります。この事例では、利用できる情報のソースが多岐にわたっていました。オンプレミスのデータベースシステムとAmazon S3バケットに頻繁に投入されるファイル、さらに外部のAPIデータソースがあります。一例が、英国の鉄道運行企業ナショナル・レールのデータです。このケースでは、STOMP(Streaming Text Oriented Messaging Protocol)インターフェイスを使用してデータをElasticsearchに読み込ませています。

    そこには初期の段階で解決しなければならない課題がありました。

    • データベースから取得するデータのを毎分1回以上の頻度でポーリングする必要がある
    • STOMPから来るデータはgzipで圧縮されている

    データベースを毎分1回以上の頻度でポーリングする

    1つ目の課題は、既存のlogstash-input-jdbcプラグインに簡単なパッチをあてて解決することができました。パッチを作成するまで、スケジュールはcron形式でしか表現できませんでした。パッチにはrufus-schedulerという名称で知られるJob Schedulerを使用しました。Job Schedulerは供給スケジュールをcronと秒数のどちらでも表現できます。唯一の変更はcronに代わって反復メソッドを使用するための1行のコードです。

    if @schedule @scheduler = Rufus::Scheduler.new(:max_work_threads => 1) @scheduler.cron @schedule do @scheduler.repeat @schedule do execute_query(queue) end

    これを活用するためのパッチはGitHubで公開されています

    gzipで圧縮されたメッセージを処理する

    STOMPインターフェースから来る圧縮済みメッセージを扱うには、データを解凍し、Logstashでデータをフィルターする必要があります。gzipで圧縮されたメッセージからデータ行を読み取る既存のcodecも存在しますが、このケースではgzipを解凍したメッセージが複数行のXMLとなります。これを克服するため、私たち実装チームは独自のプラグイン — logstash-codec-gzip — を作成しました。こちらもGitHubで公開されています。

    Canvasを使用してデータを可視化する

    チームはElastic Cloud上にあるマネージドのElasticsearchにあるデータをKibanaで可視化してみました。ところが、思うような表示になりません。より細やかなレベルでの制御が必要だろうと考えていた2018年5月、私たちはマンチェスター・エアポート・グループのBI責任者と共にロンドンで開催されたAWSサミットを訪れ、そこでCanvasの存在を知りました。Elasticの担当者によれば、Canvasは私たちが望んでいる表示により適しているという話でした。

    「データをKibanaで可視化するのに、ローレベルで必要な制御がないので困っています」
    「Canvasのことはご存知ですか?」
    「いいえ」
    「新しい可視化ツールです。今はテクニカルプレビューの段階ですが、そのケースに最適だと思いますよ」

    Canvasのインストールとファーストインプレッション

    CanvasはKibanaのプラグインとして利用でき、他のKibanaプラグインと同様にインストールできました。当時テクノロジープレビューだったCanvasはElastic Cloudでは利用できませんでした。私たちはTerraformを使用し、完全にスクリプト化してマンチェスター・エアポート・グループが使用するAWSにKibanaをホストさせました。

    Canvasはシンプルな表現言語をもち、各要素の可視化方法を制御することができます。それは、1つのコマンドが次にパイプされ、部分式が括弧内の式で宣言されるような形で実行されるshellプログラミングに似ています。

    列車の到着時刻を表示するCanvasダッシュボード、試作第1号(現在のバージョンは下を参照)

    何日か触ってCanvasに慣れたところで、私たちはスタンステッド空港に到着する列車の時刻を可視化することができました。このダッシュボードは、テキスト部分にマークダウン要素を、フッターのアイコンと画像にImage Repeatを使用して作成しています。

    見栄えもよく、個々の要素も制御することができましたが、1つだけまだ足りない点がありました。このユースケースでは、より細かな制御が必要なのです。

    • タイムゾーンに基づいてタイムスタンプをフォーマットする(データはUTCで格納されているが、夏時間に合わせる必要があるため)
    • 既知のしきい値に基づいてテキストや画像の色を変更する

    Canvasを拡張する

    Canvas向けにプラグインを記述する方法は、Kibana向けプラグインの場合にかなり似ています。プラグインはNode.jsで記述されており、使用するレジストリに機能や新しい要素を追加して、Canvas UI内で選択することもできます。このケースでは、必要な制御水準を達成するため3つのプラグインを作成しました。

    タイムスタンプのフォーマットにタイムゾーンを使用する

    最初に作成したプラグインは、内蔵のformatdateを簡単に拡張したものです。

    import moment from 'moment';
    import 'moment-timezone/builds/moment-timezone-with-data';
    export const formatdatetz = () => ({
      name: 'formatdatetz',
      type: 'string',
      help:'Output a ms since epoch number as a formatted string according to a given timezone',
      context: {
        types: ['number'],
      },
      args: {
        _: {
          types: ['string'],
          help:'MomentJS Format with which to bucket (See https://momentjs.com/docs/#/displaying/)',
          required: true
        },
        timezone: {
          types: ['string'],
          help:'The timezone',
          required: true,
          default:'UTC'
        }
      },
      fn: (context, args) => {
        if (!args._) return moment.utc(new Date(context)).tz(args.timezone).toISOString();
        return moment.utc(new Date(context)).tz(args.timezone).format(args._);
      },
    });
    

    このformatdatetz pluginはCanvasにインストールして使用するもので、GitHubで公開されています。インストールも簡単です:

    ./bin/kibana-plugin install https://github.com/crimsonmacaw/nodejs-canvas-plugin-formatdatetz/releases/download/v1.0.2/canvas-plugin-formatdatetz-1.0.2.zip
    

    テキストと画像の色を制御する

    このケースで、テキストと画像の色を制御にマークダウンを使用することはできませんでした(Canvas内にCSSを提供することはできますが、マークダウン構文はどのスタイルを適用するかについてHTMLクラス属性設定をサポートしていません)。

    最もシンプルなアプローチは、HTMLで直接コーディングできて、マークダウン要素にも同様の方法を使用でき、ハンドルバー表現のデータバインディングができるプラグインを作成することでした。SVG画像は直接HTMLに埋め込むことができます。実装チームは同じレベルの制御を適用し、Elasticsearchから取得したデータに基づいて動的に画像を変更することができるようになりました。

    可視化を作成する

    必要なプラグインを作成すると細かな制御が可能になり、表の中で行ごとに色を変えるといったこともできるようになりました。

    ユーザーワイヤフレームに基づくセキュリティハブダッシュボードの初回デザイン(現行のダッシュボードは下の画像の通り、大きく異なっています)

    複数のデータを1つの画面に可視化できており、あとはプレースホルダにデータを入れるだけですが、何かしっくりこない感じがします。そしてこんなリクエストが届きました。

    「もう少しおしゃれにできますか?」

    即座にインターネットにインスピレーションを求めに行きました。"かっこいい"、"ダッシュボード"というキーワードでPinterestDribbbleといったプラットフォームを検索したところ、良さそうなダッシュボードデザインのアプローチが見つかりました。そして方向性を修正した結果…

    同じセキュリティハブのダッシュボード。ダークテーマを採用し、ゲージとグラデーションカラーを導入(ダッシュボードとしては未完)。

    画面に多数の要素が追加されています。シンプルなHTMLと複雑なSVG画像を組み合わせて作成したプラグインが広い範囲で使われ、要素を動的に生成しています。

    フィードバックはポジティブでした。しかし設計に参加しなかったユーザーは、ダッシュボードを見ただけでは各メトリックの意味がわかりませんでした。

    「いい感じですね!でもこの棒グラフはどういう意味ですか?」

    "空港セキュリティの現場ですばやく判断を下せるようにする"、という原点に立ち帰ってみると、デザインを美しくすることが情報を可視化する最適な方法であるとは限りません。何も説明がなくても、何が表示されているか瞬時にわかるようなダッシュボードにする必要があるのです。

    インタラクティブなアプローチ

    Canvasには豊かな表現言語が備わっています。私たちは関係者とダッシュボードのライブ編集について複数回のワークショップを開催し、方向性を探りました。こうしてCanvasついて説明する前や、以前使われていたレポートをベースにしたワイヤフレームから大きく前進し、ダッシュボードに最適に情報を表示するにあたり、新しい発想によるアプローチが見つかりました。ダッシュボードの最新バージョンをエンドユーザーに見せ、フィードバックをもらって修正する、という作業を続けました。

    最終版のダッシュボード

    関係者が力を合わせ、クリエイティブシンキングを実践して完成したダッシュボードが下の画像です。

    「Crimson MacawがElasticsearchとCanvasを使って制作したスタンステッド空港のダッシュボードは、以前は別々のシステムに入っていたデータをリアルタイムに、モダンに一括表示してくれます。現場のプロセスは、かつては不可能だと思われた部分で大幅に効率化されました」– マンチェスター・エアポート・グループ、BI & Analytics責任者、スチュアート・ヒューストン

    ダッシュボードはプレゼンテーション用にランダムなデータを表示しています。データのランダム化にあたり、Canvas向けのrandomise plugin(ランダム化プラグイン)を作成、使用しています。

    セキュリティハブ

    このダッシュボードは空港セキュリティを出入りする人の数が基準を満たしているかや、個々のレーンの情報など、空港セキュリティの現在の状況を示します。セキュリティレーンを示す図形は空港セキュリティの実際のレイアウトに基づいており、オペレーションスタッフはこのダッシュボードを見て実際のレーンをすぐに理解することができます。

    セキュリティポッド

    このダッシュボードはトレンド(傾向)情報を表示します。空港のさまざまなエリアで、事前に予測した搭乗者数と待ち時間に対し、実際にセキュリティエリアに進む人の数をプロットしています。

    出発便情報

    一般的なFIDS(フライト情報表示画面)によく似ていますが、今後のフライトについて事前予測された搭乗者数に対し、空港セキュリティに入場した人の数を比較した情報を追加表示しています。

    到着列車情報

    スタンステッド空港を利用する搭乗客の多くが電車を利用しており、電車の遅延は空港セキュリティに流入する人の数にも大きな影響を及ぼします。1本の列車が数百人の搭乗客を乗せており、一時的な運転見合わせや遅延の解消後には複数本の列車が一気に到着することもあります。

    このためダッシュボードには通常の列車運行情報に加え、タイムラインで列車の到着時刻を表示しています。Canvasでの表現を手探りしていた最初のダッシュボードに比べると、大きく進歩していることがお分かりいただけると思います。

    まとめ

    Canvasはデータをリアルタイムに、美しく可視化する優れたツールです。(本稿執筆時点で)Canvasはベータであり、今後もいくつかの機能が追加される予定ですが、中核となる機能性をプラグインで拡張できる点はElasticプロダクトがソフトウェアに対してとるアプローチと共通しています(注:本稿はCanvasの一般公開前に執筆されました)。

    多くのBIツールはグラフや表機能に限られ、ゲージやその他の可視化はまだあまりありません。さらにCanvasのダッシュボード作成手順はシンプルです。つまりデータエンジニアやデータ可視化スペシャリストのイマジネーションが及ぶ限り、自由にダッシュボードを作成することが可能です。


    ロバート・ブルース | 英国マンチェスターを拠点とするクラウド/データITコンサルティング企業Crimson Macawの創業パートナー、エンジニアリングディレクター。データエンジニアリングとWeb業界で20年以上の経験を持ち、現在はクラウドテクノロジー分野を強みとする。

    Viewing all 419 articles
    Browse latest View live