Taste of Tech Topics

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

社内技術イベントLTxRT紹介 ~仕事でElectronアプリ開発をした結果を発表しました

こんにちは
最近JavaScriptが一番詳しい言語になってきたmaron8676です。

先日Electronについて業務で使用する機会があり、その結果のフィードバック会を行いました。
f:id:acro-engineer:20180524074506j:plain:w300
図1. フィードバック会の様子

Electron は、JavaScriptやHTML/CSS関連で数年前に出てきた技術なのですがなかなか面白いことができそうです。
そこで今回は、フィードバック会でも話したElectron の紹介をしていきます。

Electronとは

HTML/CSS/JavaScriptでクライアントアプリを作るためのランタイムです。
Electronは、Visual Studio CodeGitHub Desktop、Slackなどなど、よく知られたアプリにも使われています。
HTML/CSSをアプリ画面としてレンダリングしたり、画面に対する処理(JavaScript)を実行するためのChromiumと、
JavaScriptからOSのAPIを使用するためのNode.jsから構成されています。
f:id:acro-engineer:20180524080801p:plain
図2. Electronの構成

機能としては、クライアントアプリで必要になることを大体行うことができます。
例えば、以下のようなことができます。

  1. ローカルファイルへのアクセス
  2. メニューバーの表示
  3. コンテキストメニューの表示や編集
  4. 複数ウィンドウの表示
  5. トレイによる表示
  6. 他のプログラムを起動
  7. 自動アップデート

Electronのいいところ

Webアプリ開発と比較したいいところ

  1. ブラウザ依存がない
    組み込みのChromiumで固定されるため、クロスブラウザ対応が不要になります。
  2. OSの機能を使用できる
    ユーザ設定をローカルに保存したり、通知を出すことができます。
  3. Node.jsのライブラリを画面から呼べる
    Electronアプリは以下のようなプロセスで構成されていて、クライアント処理にあたるレンダラープロセスからサーバ処理にあたるメインプロセスをimportされているかのように実行できます。

f:id:acro-engineer:20180524082034p:plain
図3. Electronのプロセス構成

従来のデスクトップアプリ開発と比べたいいところ

  1. Webアプリとの連携
    HTML/CSSの画面とJavaScriptの内部処理によって、アプリ画面にWebアプリを埋め込むことができます。元々Webアプリとしてあったものを利用するなどして作る量を減らせます。
  2. Webアプリ開発での知識を生かしやすい
    Webアプリで使用されるJavaScriptでそのまま開発できるため、従来のデスクトップアプリ開発を勉強するより、新しく覚えることが少なくて済みます。

よくないところ(難しいところ)

  1. 並列処理の実現が面倒
    JavaScriptがシングルスレッド言語のため、並列処理を行いたい場合は、WebWorkerやServiceWorkerを利用するなどの工夫が必要です。
  2. Native Module(Cで書かれたモジュール)の使用に必要な手順が複雑
    特にWindowsではCをビルドできるようにするための準備が複雑でした 詳細は以下にまとめてあります
    WindowsでElectronからNative Moduleを使えるようにする
  3. ビルドやモジュール読み込みでつまりどころが多かった
    exe化にはelectron-builderを使用していましたが、Native Moduleではexe化により圧縮されるファイルからの読み込みがうまくいかなかったり、
    ビルドしたときにディレクトリ構成が変わって、特殊な読み込みをしているモジュールがそのままでは読み込めなかったりといった問題がありました。

発表してみて

発表にあたり復習するなど準備しましたが、それでも発表中の質問で新たに気づくことがあったり、新たな利用法を提案してもらえたりあるので面白いですね。
これからの話としては、HTML/CSSを使ってアプリ画面を作ったり、Webアプリではできなかった機能を追加したりなどいろいろ考えられそうです。

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


  • ビッグデータHadoop/Spark、NoSQL)、データ分析(Elasticsearch、Python関連)、Web開発(SpringCloud/SpringBoot、AngularJS)といった最新のOSSを利用する開発プロジェクトに関わりたい。
  • マイクロサービスDevOpsなどの技術を使ったり、データ分析機械学習などのスキルを活かしたい。
  • 社会貢献性の高いプロジェクトや、顧客の価値を創造するようなプロジェクトで、提案からリリースまで携わりたい。
  • 書籍・雑誌等の執筆や、対外的な勉強会の開催・参加を通した技術の発信、社内勉強会での技術情報共有により、エンジニアとして成長したい。

 
少しでも上記に興味を持たれた方は、是非以下のページをご覧ください。
データ分析案件で時系列データの異常検知に挑戦したいエンジニアWanted! - Acroquest Technology株式会社のエンジニア中途・インターンシップ・契約・委託の求人 - Wantedlywww.wantedly.com

Convolutional Neural Networkを使う自然言語処理論文読破に挑戦!(前編)

皆さんこんにちは、@です。

画像処理の分野の方はお馴染みかと思いますが、画像処理では、Convolutional Neural Network(CNN)をよく利用されています。

このニューラルネットワークアーキテクチャは画像処理の分野で非常に大きな成果をあげており、近年ではより、様々な分野に使われています。
例えば、CNNは音声や自然言語処理の分野でも時々、登場し、応用されています。

私自身が今まで興味があったのもあり、CNNを使った自然言語処理の論文を調べてみました!

少し長くなったので、前後編に分割してご紹介します。
今回はCNNを使った文書分類について記載します。

Convolutional Neural Network

Convolutional Neural Network(CNN)は画像処理でよく使われるニューラルネットワークのモデルです。

f:id:acro-engineer:20180318155516p:plain:w600
http://yann.lecun.com/exdb/publis/pdf/lecun-98.pdfより引用)

自然言語処理における畳み込みのメリットは次の通りです。

  1. 時間方向に畳み込みを行うため、時間方向の特徴を得られる。
  2. (RNNと異なり)計算を並列化できるため、高速である。
  3. 文脈上、遠い関係にある情報間の関係も学習できる。

今回、調べた論文を読んでみると、精度が改善されただけでなく、
性能も改善されている論文も多く見られます。

参考:Convolutional Neural Netwoks で自然言語処理をする

CNNと文書分類

Convolutional Neural Networks for Sentence Classification

f:id:acro-engineer:20180318132325p:plain:w600

この論文は学習済の既存の単語を埋め込みベクトル(100 billion words of Google News)を結合し、複数のフィルタサイズでの畳み込みを用いています。

畳み込みの構造で得られた結果に対して、Max Poolingを行い、文書を分類しています。
このニューラルネットワークアーキテクチャで7個中4個のタスクで当時のState of the artを更新し、成果を上げました。

この結果は、既存の学習済の埋め込みベクトルを用いたため、CNNの設計が良かったことだけでなく、教師なしの良い特徴を得ることが重要であることを示しています。
逆に言えば、得られている特徴の質が悪いと、CNNの結果も悪くなるとも言えます。

http://www.aclweb.org/anthology/D14-1181

A Sensitivity Analysis of (and Practitioners’ Guide to) Convolutional Neural Networks for Sentence Classification

f:id:acro-engineer:20180318164430p:plain:w500

CNNを用いた感情分析の実験を行っています。
その感情分析を行いつつ、CNNのパラメータチューニングにも触れられています。

1つ前の論文で紹介した「Convolutional Neural Networks for Sentence Classification」では、CNNを使い、精度向上ができたといった結果が得られました。

しかし、CNNはハイパーパラメータが多く、どのパラメータを調整するのが良いのか非常に難しいです。
本論文では、パラメータを変化させた場合の精度の実験を行い、どのパラメータを重点的にチューニングをするのかが良いのかの検証を行っています。
論文中では、畳み込む複数のフィルタサイズ、word2vecのモデルの重要性について議論されています。

http://www.aclweb.org/anthology/C16-1229

Character-level Convolutional Networks for Text Classification

f:id:acro-engineer:20180318132339p:plain:w600

先程まで単語単位でCNNへ入力をしていました。
本論文では、文字(アルファベット)+一部の記号の埋め込みベクトルをCNNの入力しています。
今回は、分類におけるデータ拡張の工夫として、シソーラス(同義語集)を使った語彙拡張も利用しています。
LSTM, Bag of Wordsなど従来の手法と比較して精度が向上しているタスクが4種類あります。

https://arxiv.org/abs/1509.01626

Combination of Convolutional and Recurrent Neural Network for Sentiment Analysis of Short Texts

f:id:acro-engineer:20180426231007p:plain:h300

CNNとRecurrent Neural Network(RNN)を使った短いテキストの感情分析を行っています。
短いテキストは伝えたい情報の細部を省略していることもあり、テキスト上の情報が少なくなる傾向があります。

局所特徴を取得することのできるCNN、そして、長期的な依存関係を獲得できるRNNを組み合わせ、2つのアルゴリズムの特性を活かすニューラルネットワークを構築しました。

word2vecで得られた単語の特徴量を用いて、畳み込みます。
畳み込みで得られた出力に対して、LSTMやGRUを使い、最後に分類を行います。
この手法により、MR, SST1 and SST2のデータセットでState of the artを取得しました。

Language Modeling with Gated Convolutional Networks

f:id:acro-engineer:20180318132535p:plain:h500

CNNにゲートを付与した構造が新規性に該当する部分です。
この構造をGated Linear Unit(GLU)と表現しています。
次の(1)と表現されている式が提案手法部分に該当します。
埋め込みベクトルに対して、Residual Networkに近しいゲート構造を構築しています。

f:id:acro-engineer:20180318154942p:plain:h30

\sigmaはsigmoid関数を示しています。

本提案手法を用いて、WikiText103 benchmarkでState of the artを獲得し、更にGoogle Billion Wordsと呼ばれるデータセットで評価しています。
これにより、従来のネットワークより収束が高速であること、そして、精度も高い手法であることを実験しました。

https://arxiv.org/abs/1612.08083

Very Deep Convolutional Networks for Text Classification

f:id:acro-engineer:20180318134647p:plain:h500 f:id:acro-engineer:20180318134656p:plain:h500

画像処理では非常に深いニューラルネットワーク(ResNetなど)が利用されています。
自然言語処理の分野では、そこまで深いネットワークが従来まで使われていませんでした。
VDCNNと呼ばれるResNetでも利用されているShort-cut構造を使い、ニューラルネットワークを深くしたアーキテクチャを提案しました。

従来のテキスト分類のデータセットを比較し、State of the artを超えています。
本論文ニューラルネットワークの構造の場合は、層が深いニューラルネットワークの方が精度が高い、そして、Short-cutの有無を比較し、Short-cut構造の効果があるといった実験結果が出ています。

https://arxiv.org/abs/1606.01781

Do Convolutional Networks need to be Deep for Text Classification ?

文書分類のCNNが深い必要があるか?といった研究。
従来の浅いニューラルネットワークとDense Netを参考にして、構築した深いニューラルネットワークを比較しています。

複数の文書分類のデータセットに対する実験の結果、
単語埋め込みのベクトルを用いたShallow Wide Networkが良い結果とのこと。
画像系のタスクとは異なり、単純に畳み込み層が深ければ良いといった傾向ではないことがわかります。

https://arxiv.org/abs/1707.04108

最後に

Convolutional Neural Networkは様々な分野で利用されており、自然言語処理の分野における活用の文書分類を紹介しました。
色々な論文を探してみると、様々なCNNのアーキテクチャが出てきて非常に勉強になりました。
次の後半では機械翻訳、その他系列ラベリングなどのタスクを紹介しようと思います。

参考文献

  1. Convolutional Neural Netwoks で自然言語処理をする

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


  • ビッグデータHadoop/Spark、NoSQL)、データ分析(Elasticsearch、Python関連)、Web開発(SpringCloud/SpringBoot、AngularJS)といった最新のOSSを利用する開発プロジェクトに関わりたい。
  • マイクロサービスDevOpsなどの技術を使ったり、データ分析機械学習などのスキルを活かしたい。
  • 社会貢献性の高いプロジェクトや、顧客の価値を創造するようなプロジェクトで、提案からリリースまで携わりたい。
  • 書籍・雑誌等の執筆や、対外的な勉強会の開催・参加を通した技術の発信、社内勉強会での技術情報共有により、エンジニアとして成長したい。

 
少しでも上記に興味を持たれた方は、是非以下のページをご覧ください。
データ分析案件で時系列データの異常検知に挑戦したいエンジニアWanted! - Acroquest Technology株式会社のエンジニア中途・インターンシップ・契約・委託の求人 - Wantedlywww.wantedly.com

社内技術イベントLTxRT紹介 ~うちのアジャイル、実際どうやってるの?~

こんにちは。QAエンジニアの@です。
何度かこのブログでも紹介しましたが、Acroではほぼ毎週木曜日に社内勉強会「LTxRT」を行っています。

今週のテーマは「アジャイル」。先日アジャイルの勉強会に参加してきた若手リーダーからのフィードバックと、社内でスクラム開発を行っている各プロジェクトからの事例の共有がありました。
f:id:acro-engineer:20180524190250j:plain:w300
内容は、

  • ふりかえり会どうやってる?
  • レビューどうやってる?
  • ユーザーストーリー描いてメンバに共有したけど、実際どうだった?

などなど。
参加者からも、「うちのプロジェクトではこうやってるよー」や「スクラムに忠実にやりすぎなくてもいいんじゃない?」など色々な意見が飛び出し、活発な会になりました。
このような場があると、自分のプロジェクトにも使えるかもしれない発見があって楽しいですね!

それでは~。

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


  • ビッグデータHadoop/Spark、NoSQL)、データ分析(Elasticsearch、Python関連)、Web開発(SpringCloud/SpringBoot、AngularJS)といった最新のOSSを利用する開発プロジェクトに関わりたい。
  • マイクロサービスDevOpsなどの技術を使ったり、データ分析機械学習などのスキルを活かしたい。
  • 社会貢献性の高いプロジェクトや、顧客の価値を創造するようなプロジェクトで、提案からリリースまで携わりたい。
  • 書籍・雑誌等の執筆や、対外的な勉強会の開催・参加を通した技術の発信、社内勉強会での技術情報共有により、エンジニアとして成長したい。

 
少しでも上記に興味を持たれた方は、是非以下のページをご覧ください。
モノリシックなアプリケーションをマイクロサービス化したいエンジニア募集! - Acroquest Technology株式会社のWeb エンジニア中途・インターンシップ・契約・委託の求人 - Wantedlywww.wantedly.com

Angular4アプリをAngular6にバージョンアップする際の嵌りどころ

こんにちは、阪本です。

f:id:acro-engineer:20180509102654p:plain:w200

最近、画面系を触ることが多くて、Angularを使ったシステムを3つほど作ったのですが、
LTSであるAngular6がつい最近リリースされたので、
作った中でシンプルなAngular4アプリケーションをAngular6にバージョンアップさせてみました。

前提

バージョンアップ前のAngularのバージョンは4.4.6でした。
Angular Material 2.0.0-beta.12を使っています。

ちなみに対象のアプリケーションは2KL強(クライアントサイド)の申請管理システムで、申請→承認のフローを実行するものです。

バージョンアップ開始

いざ、出陣!(何

バージョン変更

まずは、ncuを使って、package.jsonに書かれた各パッケージのバージョンを上げます。

C:\App> ncu
Using C:\App\package.json
[..................] | :
 @angular/animations                         4.4.6  →   6.0.0
 @angular/cdk                        2.0.0-beta.12  →   6.0.0
 @angular/common                             4.4.6  →   6.0.0
 @angular/compiler                           4.4.6  →   6.0.0
 @angular/compiler-cli                       4.3.6  →   6.0.0
 @angular/core                               4.4.6  →   6.0.0
 @angular/forms                              4.4.6  →   6.0.0
 @angular/http                               4.4.6  →   6.0.0
 @angular/material                   2.0.0-beta.12  →   6.0.0
 @angular/platform-browser                   4.4.6  →   6.0.0
 @angular/platform-browser-dynamic           4.4.6  →   6.0.0
 @angular/platform-server                    4.4.6  →   6.0.0
 @angular/router                             4.4.6  →   6.0.0
 core-js                                     2.4.1  →   2.5.6
 rxjs                                        5.4.3  →   6.1.0
 ts-helpers                                  1.1.1  →   1.1.2
 typescript                                  2.0.3  →   2.8.3
 zone.js                                    0.8.17  →  0.8.26
 @angular/cli                                1.3.2  →   6.0.0
 @types/node                                6.0.42  →  10.0.4
 codelyzer                                   3.1.2  →   4.3.0
 jasmine-core                                2.4.1  →   3.1.0
 jasmine-spec-reporter                       2.5.0  →   4.2.1
 karma                                       1.2.0  →   2.0.2
 karma-chrome-launcher                       2.0.0  →   2.2.0
 karma-jasmine                               1.0.2  →   1.1.2
 karma-remap-istanbul                        0.2.1  →   0.6.0
 protractor                                  4.0.9  →   5.3.1
 ts-node                                     1.2.1  →   6.0.3
 tslint                                      5.6.0  →  5.10.0
 webdriver-manager                          10.2.5  →  12.0.6

The following dependency is satisfied by its declared version range, but the installed version is behind. You can install the latest version without modifying your package file by using npm update. If you want to update the dependency in your package file anyway, run ncu -a.

 moment   2.19.2  →   2.22.1

Run ncu with -u to upgrade package.json


C:\App>

何やらたくさんバージョンアップされます。恐ろしや。。
思い切って、 ncu -u でバージョンを反映させます。

C:\App> ncu -u
Using C:\App\package.json
[..................] - :
 @angular/animations                         4.4.6  →   6.0.0
(中略)
 moment   2.19.2  →   2.22.1
Upgraded C:\App>

package.jsonが書き換わりました。
なお、TypeScriptは2.8.3にバージョンアップしていますが、
Angular6ではTypeScriptは2.7.xまでしか対応していないため、2.7.2に手で変更する必要があります

package.jsonのTypeScriptのバージョンを変更したら、新しいバージョンのパッケージをインストールします。

C:\App> npm update
npm WARN deprecated nodemailer@2.7.2: All versions below 4.0.1 of Nodemailer are deprecated. See https://nodemailer.com/status/
(中略)
================================================================================
The Angular CLI configuration format has been changed, and your existing configuration can
be updated automatically by running the following command:

  ng update @angular/cli
================================================================================
(中略)
C:\App>

途中、メッセージが出てくる通り、
Angular6では、設定ファイルの記述の仕方が変わっているため、
ng update @angular/cli で設定ファイルの更新が必要です。

C:\App> ng update @angular/cli
            Updating karma configuration
            Updating configuration
            Removing old config file (angular-cli.json)
            Writing config file (angular.json)
            Some configuration options have been changed, please make sure to update any npm scripts which you may have modified.
DELETE angular-cli.json
CREATE angular.json (3523 bytes)
UPDATE karma.conf.js (1074 bytes)
UPDATE src/tsconfig.spec.json (324 bytes)
UPDATE package.json (1466 bytes)
UPDATE tslint.json (2971 bytes)
(中略)
npm WARN optional SKIPPING OPTIONAL DEPENDENCY: fsevents@^1.0.0 (node_modules\karma\node_modules\chokidar\node_modules\fsevents):
npm WARN notsup SKIPPING OPTIONAL DEPENDENCY: Unsupported platform for fsevents@1.2.3: wanted {"os":"darwin","arch":"any"} (current: {"os":"win32","arch":"x64"})

angular-cli.jsonが削除され、代わりにangular.jsonになりました。
package.jsonには@angular-devkit/build-angularが追加されています。
追加されたパッケージは自動でインストールされます。

とりあえず、パッケージ自体のバージョンアップは完了です。

RxJSの破壊的変更対応

今回のバージョンアップの一番面倒なところが、これです。(Angular本体とちゃうんかい!)
Angularのバージョンアップに伴い、RxJSも5.4から6にバージョンアップ。
importを軒並み書き換え&コードも書き換えが必要です😖

ちなみに、rxjs-compatパッケージをインストールすれば、書き換えずに動作するらしいですが、
ここでは頑張って最新の書き方にしていきます💪

Observable

Angularとは切っても切れないObservable。
Angular4で使われていたRxJS 5.4では

import { Observable } from 'rxjs/Observable';

だったのが、RxJS 6では

import { Observable } from 'rxjs';

に。
rxjsから直接importするように変更されています。

Observable以外にも、BehaviorSubject等がrxjsからのimportに変わっています。

of / merge / throw

Observable.of のように、Observableのstaticメソッドで呼び出していたのが、RxJS 6では独立しました。

■RxJS 5.4

import 'rxjs/add/observable/of';
import 'rxjs/add/observable/merge';
import 'rxjs/add/observable/throw';

Observable.of(o);
Observable.merge(o1, o2);
Observable.throw(e);

■RxJS 6

import { of, merge, throwError } from 'rxjs';

of(o);
merge(o1, o2);
throwError(e);

例外発生は、throwErrorに名称変更されています。

map / catch

RxJS 5.4では observable.map().catch().subscribe() のような書き方をしていたのが、
RxJS 6では observable.pipe(map(), catch()).subscribe() のように、 pipe で挟むようになりました。
convertprocess はオリジナル関数。

■RxJS 5.4

import { HttpClient } from '@angular/common/http';
import { Observable } from 'rxjs/Observable';

this.http.get('url')
    .map(response => convert(response))
    .catch(error => Observable.of(error))
    .subscribe(response => process(response));

■RxJS 6

import { HttpClient } from '@angular/common/http';
import { Observable } from 'rxjs';
import { map, catchError } from 'rxjs/operators';

this.http.get('url')
    .pipe(
      map(response => convert(response)),
      catchError(error => of(error)))
    .subscribe(response => process(response));

pipe の中に、 mapcathError を複数書けるようになっています。

tap

余談ですが、RxJS 5.4では、戻り値のない関数も map で実行できましたが、
RxJS 6では tap が用意されており、こちらを使用するようになっています。

HTTPレスポンスの内容をログ出力する例を示します。

import { HttpClient } from '@angular/common/http';
import { Observable } from 'rxjs';
import { map, tap, catchError } from 'rxjs/operators';

this.http.get('url')
    .pipe(
      tap(response => console.log(response)),
      map(response => convert(response)),
      catchError(error => of(error)))
    .subscribe(response => process(response));

combineLatest

RxJS 5.4では、最初のObservableの combineLatest を呼んでいましたが、
RxJS 6では独立しました。こちらの方が自然ですね。
ただ、結合した結果はObservableの配列になるので、 map で変換します。
combine はオリジナル関数。

■RxJS 5.4

import 'rxjs/add/operator/combineLatest';

observable1.combineLatest(observable2, (o1, o2) => combine(o1, o2));

■RxJS 6

import { combineLatest } from 'rxjs';
import { map } from 'rxjs/operators';

combineLatest(observable1, observable2)
  .pipe(map(values => combine(values[0], values[1]));

Angular

RxJSの対応が一通り完了したら、あとは大したことはありません。

今回のバージョンアップでは、Angularの内容は全く修正が要りませんでした。
Deprecatedなものを使っていた場合は、削除されている可能性があるため、直す必要があります。

Angular Material

こちらも、今回は何も変更せずに動作しました。
使っているのは matInputmat-selectmat-table くらいですが。

まとめ

RxJSの変更はつらいものがありましたが、それさえ乗り越えれば、最新のAngularを適用するのは楽チンです👍
Angular6はLTSでサポートも2019年10月まで続くので、
古いAngularを使っている場合は、アップデートを検討してみてください。

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


  • ビッグデータHadoop/Spark、NoSQL)、データ分析(Elasticsearch、Python関連)、Web開発(SpringCloud/SpringBoot、Angular)といった最新のOSSを利用する開発プロジェクトに関わりたい。
  • マイクロサービスDevOpsなどの技術を使ったり、データ分析機械学習などのスキルを活かしたい。
  • 社会貢献性の高いプロジェクトや、顧客の価値を創造するようなプロジェクトで、提案からリリースまで携わりたい。
  • 書籍・雑誌等の執筆や、対外的な勉強会の開催・参加を通した技術の発信、社内勉強会での技術情報共有により、エンジニアとして成長したい。

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

www.wantedly.com

Elasticsearchの圧縮方式の比較

こんにちは。
2年目エンジニアのノムラです。
普段はElasticStackを用いた分析基盤の開発等を行っています。

Elasticsearchを使っているとストレージの使用量を節約したいと思う方は多いのではないでしょうか。

Elasticsearchはデータを格納するときにデフォルトでLZ4という圧縮方式でデータ圧縮を行っていますが、
実はLZ4よりも圧縮率の高いbest_compressionという圧縮方式を利用することもできます。

このbest_compressionは圧縮率が高い分、検索時にはLZ4よりも遅くなると言われるのですが、
実際にどれくらいデータサイズに違いがあるのか、検索速度の違いはどれくらいになるのかが
実はよく分かりません。

ということで今回はこの2つの圧縮方式のデータサイズと検索速度への影響を比較してみました。


目次は以下になります

環境情報

OS: Amazon Linux release 2.0 (2017.12) LTS Release Candidate
インスタンスタイプ: t2.2xlarge
ディスクサイズ: 30gb

バージョン情報

elasticsearch 6.2.2
kibana 6.2.2
logstash 6.2.2

準備

今回はapacheログを用いて比較を実施します。
比較のためのデータは apache-loggenを使って1000万件のデータ(2.2gb)を作成しました。
appache-loggenのURLは以下
github.com


データは以下のような形式です。

160.87.30.197 - - [05/Jan/2018:15:01:07 +0900] "GET /category/music HTTP/1.1" 200 113 "/item/finance/777" "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/535.11 (KHTML, like Gecko) Chrome/17.0.963.56 Safari/535.11"

検証のための準備は以下となります。

1.インデックステンプレートの適用

今回は1ノードでの検証になるため、シャード数を1にレプリカ数を0に設定します

curl -XPUT -u user:pass 'localhost:9200/_template/tmpl_00_shard?pretty' -H 'Content-Type: application/json' -d'
{
  "index_patterns": "*",
  "settings": {
    "index": {
      "number_of_shards": "1",
      "number_of_replicas": "0"
    }
  }
}
'
2.LZ4形式のデータ投入

lz4_sampleインデックスにLZ4形式(デフォルト形式)でデータを投入します

$cat apache_logs | bin/logstash -f apache_lz4.conf

apache_lz4.confの設定は以下です。

input{
  stdin{}
}
filter{
  grok { 
    match => [ "message", "%{COMBINEDAPACHELOG}" ] 
  }
}
output{
  stdout{
    codec => dots
  }
  elasticsearch{
    hosts => localhost
    index => "lz4_sample"
    user => "user"
    password => "pass"
  }
}
3. best_compression形式のデータ投入

APIを用いてbest_compression_sampleインデックスの圧縮方式をbest_compressionに設定します

curl -XPUT -u user:pass 'localhost:9200/best_compression_example?pretty' -H 'Content-Type: application/json' -d'
{
  "settings": {
    "index.codec": "best_compression"
  }
}
'

best_compression_sampleインデックスにbest_compression形式でデータを投入します

$cat apache_logs | bin/logstash -f apache_best_compression.conf

apache_best_compression.confの設定は以下

input{
  stdin{}
}
filter{
  grok { 
    match => [ "message", "%{COMBINEDAPACHELOG}" ] 
  }
}
output{
  stdout{
    codec => dots
  }
  elasticsearch{
    hosts => localhost
    index => "best_compression_sample"
    user => "user"
    password => "pass"
  }
}
4.投入されたデータの確認
curl -XGET ‘localhost:9200/lz4_sample/_search

以下の様なデータが投入されていることが確認できます。(best_compression_sampleでも同様です)

{
  "took" : 23,
  "timed_out" : false,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : 10310974,
    "max_score" : 1.0,
    "hits" : [
      {
        "_index" : "lz4_sample",
        "_type" : "doc",
        "_id" : "PsXqDmEBl8mqXpdfS3ci",
        "_score" : 1.0,
        "_source" : {
          "request" : "/category/software",
          "agent" : "\"Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0)\"",
          "auth" : "-",
          "ident" : "-",
          "verb" : "GET",
          "message" : "104.129.152.199 - - [05/Jan/2018:14:56:46 +0900] \"GET /category/software HTTP/1.1\" 200 63 \"/search/?c=Sports+Computers\" \"Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0)\"\r",
          "referrer" : "\"/search/?c=Sports+Computers\"",
          "@timestamp" : "2018-01-19T14:54:46.064Z",
          "response" : "200",
          "bytes" : "63",
          "clientip" : "104.129.152.199",
          "@version" : "1",
          "host" : "HOGE",
          "httpversion" : "1.1",
          "timestamp" : "05/Jan/2018:14:56:46 +0900"
        }
      },
      (略)
    ]
  }
}

データサイズの比較

KibanaのDevToolsからCAT APIを用いてデータサイズを計測します。
f:id:acro-engineer:20180409003727p:plain

best_compression形式で圧縮されたデータの方が、LZ4形式で圧縮されたデータと比較してデータサイズが16%程小さくなっています。

検索速度の比較

KibanaのDevToolsを用いて、検索速度を計測します。
計測はlz4_sampleインデックス、best_compression_sampleインデックスそれぞれ10回ずつ実施しました。

検索クエリは以下

# lz4
GET lz4_sample/_search
{
  "size": 10000,
  "query": {
    "match_all": {}
  }
}
# best_compression
GET best_compression_sample/_search
{
  "size": 10000,
  "query": {
    "match_all": {}
  }
}

結果は以下

圧縮方式 平均 最大 最小
LZ4 1.14s 1.53s 0.87s
best_compression 1.86s 2.11s 1.61s

best_compression形式で圧縮されたデータに対する検索速度は、LZ4形式と比較すると163%と遅くなりました。
データの解凍が遅い分検索処理にも時間がかかっているようです。

LZ4とbest_compressionのデータが両方存在する場合

ここで、実際の利用シーンではLZ4形式とbest_compression形式、両方の形式で圧縮されたデータに跨って、検索するシーンが考えられます。
単純に考えれば、検索対象のドキュメント数が同じ場合、検索速度はLZ4形式のみの検索速度と、best_compression形式のデータのみの検索速度の間になりそうです。
そちらも検証してみました。

そこで、先ほどのデータとは別に、ドキュメント数は同じで、LZ4形式とbest_compression形式が半分ずつになるようにデータを投入しました。(データサイズ:計4.2gb)
投入処理については割愛します。
f:id:acro-engineer:20180409012135p:plain

同様にKibanaのDevToolsを用いて、検索速度を計測します。
検索クエリは以下

# 混合
GET apache_*/_search
{
  "size": 10000,
  "query": {
    "match_all": {}
  }
}

結果は以下のようになりました。

圧縮方式 平均 最大 最小
LZ4 1.14s 1.53s 0.87s
混合 1.38s 1.49s 1.28s
best_compression 1.86s 2.11s 1.61s

予想通り、混合したデータに対する検索速度はLZ4形式とbest_compression形式、それぞれの形式の間の値になりました。

まとめ

LZ4とbest_compressionのデータサイズと検索速度への影響の違いは以下のようになります。

圧縮方式 元データ LZ4 混合 best_compression
データサイズ 2.2 gb 4.6gb 4.2gb 3.9gb
検索速度 - 1.14s 1.38s 1.86s

今回はapacheログを用いて圧縮形式の比較を行いました。
他のデータの場合にはまた状況が違ってくると思いますが、一つの例として参考になれば嬉しいです。

それでは!

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


  • データ分析(Elasticsearch、Python関連)、ビッグデータHadoop/Spark、NoSQL)、Web開発(SpringCloud/SpringBoot、AngularJS)といった最新のOSSを利用する開発プロジェクトに関わりたい。
  • マイクロサービスDevOpsなどの技術を使ったり、データ分析機械学習などのスキルを活かしたい。
  • 社会貢献性の高いプロジェクトや、顧客の価値を創造するようなプロジェクトで、提案からリリースまで携わりたい。
  • 書籍・雑誌等の執筆や、対外的な勉強会の開催・参加を通した技術の発信、社内勉強会での技術情報共有により、エンジニアとして成長したい。

 

社内技術イベントLTxRT紹介 ~「エンジニアリング組織論への招待 ☓ カイゼン・ジャーニー」のイベントを視聴しました~ #eotkaizenj

こんにちは。@です。
気がついたら4月になり、しばらくしたら突然暑くなって、うっかりスタバで購入した
抹茶フラペチーノがおいしかったです。

本題ですが、先日、LTxRTを開催し、
「エンジニアリング組織論への招待 ☓ カイゼン・ジャーニー」のイベントを会社の寮で視聴していました。

devlove.doorkeeper.jp

※前回のLTxRTはこちら

社内でもこの2冊はエンジニアの組織やチームを改善していく本で
良い本だとよくおすすめされていました。
そこで、今回のこのイベントを皆で見たいといった呼びかけがあり、Zoom越しですが、見たい人で集まりました!

f:id:acro-engineer:20180426202450j:plain:w500

イベントの最初はそれぞれの本について、どんな本か、そして、何が良かったか読者から紹介がありました。
そして、次に著者陣によるパネルディスカッションが行われました。

2つの本の共通点、違うこと、本の使い方など、著者ご自身が
どんなことを考えているのかを説明されており、面白いと思いました。

Zoomで視聴していて、聞き取りづらいなどハプニングがありました。
しかし、視聴が終わった後に本を既に読んだ人から補足をしてもらいつつ、
より細かい感想を共有してもらいながら、ディスカッションをしました。
話してみると実践できていること、まだまだ足りていないことが出てきたので非常に面白かったです。

ちなみに、LTxRTをきっかけにイベントの本をAmazonでポチった参加者も多かったです。
ちょうどGW前なのでGW中に読んで習得してきそうです。

今回も議論が活発で、面白い会になりました!
社内の勉強会も昨年度より多く増え、非常に知的刺激が多くなってきます!

また、次回お会いしましょう!

※今回のイベントの本

カイゼン・ジャーニー たった1人からはじめて、「越境」するチームをつくるまで

カイゼン・ジャーニー たった1人からはじめて、「越境」するチームをつくるまで

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


  • ビッグデータHadoop/Spark、NoSQL)、データ分析(Elasticsearch、Python関連)、Web開発(SpringCloud/SpringBoot、AngularJS)といった最新のOSSを利用する開発プロジェクトに関わりたい。
  • マイクロサービスDevOpsなどの技術を使ったり、データ分析機械学習などのスキルを活かしたい。
  • 社会貢献性の高いプロジェクトや、顧客の価値を創造するようなプロジェクトで、提案からリリースまで携わりたい。
  • 書籍・雑誌等の執筆や、対外的な勉強会の開催・参加を通した技術の発信、社内勉強会での技術情報共有により、エンジニアとして成長したい。

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

モノリシックなアプリケーションをマイクロサービス化したいエンジニア募集! - Acroquest Technology株式会社のWeb エンジニア中途・インターンシップ・契約・委託の求人 - Wantedlywww.wantedly.com

Kibanaのマルチテナント運用について考えてみた(後編)

こんにちは。
@です😊

この記事は
Kibanaのマルチテナント運用について考えてみた(前編) - Taste of Tech Topics
の後編となります。事前にそちらをご一読ください。

さて、前回の記事では
データが入っているindexに対してアクセス制限をかけることで、見せたくないデータを隠すことができました。
しかし、ダッシュボードが編集できてしまうなどの問題がありました。

ここでは、その対策としてkibana_dashboard_only_userを使ってみます。

ダッシュボードの閲覧専用ユーザー

バージョン5.xまでは自分で.kibanaへのアクセスを制限したroleを作る必要がありましたが、バージョン6からは予めkibana_dashboard_only_userというroleが定義されています。
これをkibana_userの代わりに付与してみます。
f:id:acro-engineer:20180121233236p:plain:w700

使える機能がダッシュボードだけに制限された上、編集などもできなくなっています。
良い感じです。
f:id:acro-engineer:20180121234155p:plain:w700

ダッシュボードの存在を隠す

しかし、dashboard_only_userを使うだけでは「B社のダッシュボードが存在すること」がA社の人間にもわかってしまします。
.kibana indexに対する制御をカスタマイズして、この問題を解決してみましょう。

何をするかと言うと、kibana_userの代わりに、roleA_kibanaといったようなロールを作ります。
(roleA_kibanaを作らず、roleA_adminなどにまとめて設定することも可能です)
f:id:acro-engineer:20180204230710p:plain:w700

設定内容としては、「DashboardとVisualizationは"[A社]"がタイトルに含まれる場合しかアクセスできない」というものになっています。
また、Kibanaの設定(config)や、company_aというindex-patternを読む権限もつけています。

※match_phrase_prefixではqueryがanalyzeされるので、予期せぬ名前がヒットしないよう、注意が必要です。
※本気で運用を考えるなら、saved searchやreportingについてもアクセス制御を考える必要がありますが、それに関しては本記事では考慮しません。

f:id:acro-engineer:20180207012532p:plain:w700

これでuserA_adminからはA社のダッシュボードのみが見えるようになりました。

一応、当初想定していた下記の要件を満たすことができました。

  • 「一部のダッシュボードだけを見せたい」
  • 「編集できないようにしたい」
  • ダッシュボードの存在を知られたくない」

...しかし、少しもやもやが残ります。
この方法では、ダッシュボードなどの作成時に命名の制約が生じるし、ロール定義が煩雑になる可能性が高く、スマートな方法とは言えません。

結局どうするのが良いのか?

さて、回りくどく色々と書きましたが、おそらくelasticsearch + kIbanaのマルチテナント運用をおこなう上で最も現実的な解は「Kibanaをテナントごとに用意する」というところに落ち着くのではないかと思います。(異論は認めます)


先ほど、

Kibanaのダッシュボード自体の情報は、.kibanaというindexに保存されている

と言いましたが、kibanaは設定を変更することで、.kibana以外のindex名でダッシュボードなどの情報を保存することができます。


つまり、A社のユーザーが利用するkibanaの情報は.kibana_aに、B社のユーザーが利用するkibanaの情報は.kibana_bに保存するという運用が可能になります。
そうすれば、kibana用のindexに対して細かく制限をかける必要がありません。


設定に必要な手順は、kibana.ymlを編集しkibana.indexの値を書き換えてKibanaを起動するだけです。

# kibana.index: ".kibana"
kibana.index: ".kibana_a"


こうすることで、elasticsearchのクラスタは単一でも、安全にマルチテナント運用が可能です。
この通り、A社のユーザーは、A社の情報だけが見られます。
めでたし、めでたし😇

f:id:acro-engineer:20180207012532p:plain:w700


おまけ(その他考慮すべきこと)

Kibanaは、DevToolsに関しても使用不可にすることができます。
こちらはkibana.ymlに下記の1行を追加することで使用不可にできます。
(古いバージョンでは、Kibana画面のadvanced settingsから設定できたと記憶しています)

console.enabled: false

興味のある方は試してみてください。

まとめ

  • kibanaのダッシュボード情報などは、専用のindexに保持されている
  • X-Pack Securityの機能で権限を制御できる
  • 現実的にはkibanaのインスタンスをテナント毎にわけるのが良さそう

※テナント数自体が膨大になった場合は、別の手段を考えたほうが良いケースもあるかもしれません

以上です。ツッコミ等あれば是非ご指摘ください。
お読みいただき、ありがとうございました。

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

  • ビッグデータHadoop/Spark、NoSQL)、データ分析(Elasticsearch、Python関連)、Web開発(SpringCloud/SpringBoot、AngularJS)といった最新のOSSを利用する開発プロジェクトに関わりたい。
  • マイクロサービスDevOpsなどの技術を使ったり、データ分析機械学習などのスキルを活かしたい。
  • 社会貢献性の高いプロジェクトや、顧客の価値を創造するようなプロジェクトで、提案からリリースまで携わりたい。
  • 書籍・雑誌等の執筆や、対外的な勉強会の開催・参加を通した技術の発信、社内勉強会での技術情報共有により、エンジニアとして成長したい。


少しでも上記に興味を持たれた方は、是非以下のページをご覧ください。
データ分析基盤Elasticsearchを使い倒したいエンジニア募集! - Acroquest Technology株式会社のエンジニア中途・インターンシップ・契約・委託の求人 - Wantedlywww.wantedly.com