エブリーエンジニアブログ エブリーエンジニアブログ

DELISH KITCHEN のサービスとバックエンドシステムのお話

自己紹介

はじめまして。DELISH KITCHENバックエンドチームのマネージャーをやっている内原です。

本日はDELISH KITCHENにおける、バックエンド観点でのシステム紹介を行います。この紹介によりDELISH KITCHENの開発に興味を持ってもらえると嬉しいです。

はじめに

DELISH KITCHENのサービス全体像とバックエンドシステムの構成や仕様などを紹介します。

ご覧の通り、複数のマイクロサービスが様々なミドルウェアを利用しつつ、DELISH KITCHENサービスの提供を実現しています。

DELISH KITCHENのサービス全体像

サービス全体像

DELISH KITCHENの一番主要な機能は、レシピ動画を提供することでお客様の料理体験をよりよいものにすることです。

これだけ聞くと、単に動画を配信しているだけのサービスのように思われるかもしれませんが、実際には料理にまつわる様々な事柄をサポートするシステムで、多くの機能を提供しています。

DELISH KITCHENを提供しているプラットフォーム

料理を作ろうと思った時や買い物をしている時、なんとなく流行りのレシピを知りたいと思ったときなど、色んなシチュエーションでご利用いただけるように、以下のプラットフォームでDELISH KITCHENを提供しています。

  • iOS/Android アプリ
  • WEB
  • 小売店でのデジタルサイネージ
  • Amazon Echo

DELISH KITCHENが提供しているサービス

単に料理を作る際に役立つだけではなく、特売情報をお知らせしたり買い物リストと連携することでお買い物をサポートします。

DELISH KITCHENが提供している主なサービスは以下の通りです。

  • 人気、特集、新着、パーソナライズされたリコメンドなど、能動的なレシピ提案
  • カテゴリ内検索、キーワード検索など、受動的なレシピ提案
  • 各地域の小売店特売情報と、特売商品を用いたレシピ提案
  • レシピのお気に入り管理
  • レシピのレビュー
  • レシピ材料の買い物リスト管理
  • プレミアム会員向け機能やプレミアム会員限定レシピの提供
  • DELISH KITCHENポイントによるポイント交換、ポイントがもらえるクーポン機能
  • 機種変更時や複数端末での同期用にメールアドレス/SNSによるログイン機構
  • プッシュ通知

DELISH KITCHENのバックエンドシステム全体像

複数のシステム構成

DELISH KITCHENは複数のマイクロサービスで構成されており、それぞれが別のシステムとして独立しています。

個々のシステムにおいては共通している部分も多いですが、提供している機能や使用しているサービスには差異があります。

共通の基盤/利用サービス

インフラ構成図

DELISH KITCHENの各サービスで共通的に利用している基盤や外部サービスは以下の通りです。

  • Golang, echo
  • インフラ
    • AWS ECS
    • AWS RDS
    • AWS AutoScaling
    • AWS ElastiCache
    • AWS S3
    • AWS CloudFront
    • AWS Route53
  • ログ/分析
    • fluentd
    • redash
    • TreasureData
    • Databricks
  • 開発/運用
    • github
    • CircleCI
    • terraform
    • ansible

共通APIサーバ

iOS/Android/WEB/サイネージなど、クライアント向けに提供しているAPIサーバです。お客様に対して提供される機能は、すべてこのAPIサーバを経由しています。

各種内部向けAPIサーバへの中継もここで行われます。

WEBシステム

DELISH KITCHEN WEB

WEBにおけるDELISH KITCHENサービスを提供しています。

レシピなどのデータは共通APIサーバを参照しています。共通APIサーバと通信する構成であるため、BFF(Backends For Frontends)として稼働しています。

検索システム

DELISH KITCHEN 検索

レシピ情報の検索を提供するサーバです。

検索エンジンには Elasticsearch を利用しています。

特売情報システム

DELISH KITCHEN 特売情報

特売情報を提供するサーバです。

データとしては店舗、特売商品、チラシなどを扱っています。

別途、店舗側にて特売情報を入稿するためのtoC向けシステムも存在しますが、今回は省略します。

サイネージシステム

DELISH KITCHEN サイネージ

小売店舗に設置しているサイネージ端末が利用するサーバです。

個々のサイネージに対し、レシピ/広告を指定した配信設定が可能です。レシピ情報は共通APIサーバを参照しています。

別途、店舗側にて配信設定を管理するためのtoC向けシステムも存在しますが、今回は省略します。

ポイントシステム

DELISH KITCHEN ポイント

デリッシュポイントという、DELISH KITCHEN内でお得に使えるポイントを管理するサーバです。

ポイントを別商品に交換するにはドットマネーを利用しています。

クーポンシステム

DELISH KITCHEN クーポン

デリッシュポイントをもらうことができるクーポンサービスを提供するサーバです。

外部のクーポンサーバとやり取りをしています。

課金システム

プレミアムサービスを利用可能とするため、ストア決済、キャリア決済を実現するサーバです。

プレミアムサービスはサブスクリプション形態であるため、アプリ外で購読状態を管理しています。

プッシュ通知システム

DELISH KITCHEN プッシュ通知

アプリ向けにプッシュ通知を提供するサーバです。

サーバの実態としてはmercari社製のgaurunを利用しています。

最後に

上記のように、DELISH KITCHENは多くのシステムで構成されたサービスです。

開発、運用で使用しているインフラ技術、外部サービスも多岐に渡りますので、興味を持ってもらえると嬉しいです。

ここまでお読みいただき、ありがとうございました。

DELISH KITCHENのAndroidアプリの今と変遷

はじめに

DELISH KITCHENでクライアントグループのマネージャーをやっている今井です。 クライアントチーム初のブログということで、DELISH KITCHENの Androidアプリの今の構成の話と、 アプリを作って4年が経とうとしてる中での変遷を紹介していきます。

なお、このブログは全体の構成の雰囲気を掴んでもらうことを目的にしておりますので、 細かい設計の話や採用技術の細かい特徴の紹介は割愛させていただきます。 それらはまた別の機会に紹介できればと思います。

現在の構成

ここでは現在のプロジェクトの構成とアプリで採用しているアーキテクチャの紹介をしていきます。

プロジェクトの構成

DELISH KITCHENのAndroidアプリではMultiModuleを採用しており、 大きく app core features の3種類のModuleに分かれています。

  • app いわゆるメインモジュールです。feature間をつなぐためのRouterの実装や、 ライブラリの初期化等を行っております。 歴史上の理由でここにもまだまだfeature要素が残ってしまっていますが、 徐々にfeatureモジュールに切り出しています。

  • core 各モジュールの共通で使う拡張関数やユーティリティクラスなどを入れています。 モジュール間の遷移に使ってるRouter等もここでInterfaceを定義しており、 実態はappモジュールで実装、DIで各モジュールに配布しています。

  • features 実際にfeaturesというモジュールがあるわけではなく、 機能ごとにfeatureモジュールとして分割しています。 各featureモジュールではcore以外のmoduleのimportを禁止しており、 強制的に参照不可にすることで依存をなるべく減らしています。

アーキテクチャ

アーキテクチャとしてはMVVM+レイヤードアーキテクチャを採用しています。

No Image

図の通りですが、Android Architecture Component(以下、AAC)を全面採用し、 MVVM+レイヤードアーキテクチャを構成しています。 ViewModelはそのままAACのViewModelを採用しており、 ViewModelからViewへのデータの公開はLiveData、 ViewからActionの受け付けはシンプルにメソッドコールにしています。 通信部分はKotlin Coroutineで繋いでいます。

この構成にいたるまでいろいろ変遷してきているので、 その一部を次で紹介します。

変遷

この4年間でKotlinがGoogleに正式にサポートされたり、AACやJetpackが登場したり Android界隈で大きくデファクトが変わってきました。 DELISH KITCHENのAndroidアプリではそれに対して比較的柔軟に採用技術を変更してきました。 その中で大きく変更があった3点を紹介します。

1. MonoModuleからMultiModuleへ

コード量が増えてきてビルド時間が長くなってきたので検討し始めました。 副産物的な感じでしたが、参照をあえて出来なくすることで依存関係を意識せざるを得ない状況になり、チーム全体の依存に対する意識が向上しました。また、その事に頭を使わなくて良くなったのでとても良かったです。 分割し始めた当初はInstant AppやDynamic Feature Moduleも検討していました。

2. Android Architecture Componentの採用とRxの置き換え

リリースから1年くらい経つと、機能が乗ってしまったいわゆるSuperActivity/Fragmentが出現し始めたので、 MVVMやFluxの導入を考えていたところAACが発表されたため即採用しました。 またAPI通信まわりは各レイヤーの繋ぎにとどまっていたRxをKotlinCoroutineとLiveDataに置き換えることで、 AACの恩恵をフルで受けれるような構成に変更しました。

3. Viewへのアクセス周りの変遷

ここが一番紆余曲折あったところです。 ざっくりと KotterKnife → Kotlin Android Extension → Databinding → ViewBinding と変更してきました。 初期はJavaのButterKnifeの流れでKotterKnifeを採用してたものの、 型安全じゃないとかFragmentで使えないなどの理由から、Kotlin Android Extensionに移行しました。 その後すぐにnullableになってしまうのが辛くなったのと、xml上で値を設定できる便利さからDataBindingを採用しました。 DataBinding自体は全然問題なかったんですが、あまり双方向Bindingを生かす場面がなかったのと、 ロジックがxmlにも一部分散することでコードレビューが大変になったので、現在はViewBindingを採用しています。 加えてViewBindingはDataBindingビルドが速かったり、型安全だったりと、しばらくはViewBindingで落ち着きそうです。

(おまけ) Dagger → Koin

人類にはDaggerは早かった(笑) っていうのもありますが、Daggerの機能をそんなに活かしきれていなかったのと、 誰でも比較的簡単にライブラリの挙動が理解できるようにKoinに変更しました。 設計自体に影響が大きくあった訳ではないですが、コードの変更量が膨大で、 変更作業が一番辛かったのでおまけとして紹介させてください(笑)。 そんな中、今年出たDaggerHiltへの変更を検討中だったりもします😇。

まとめ

DELISH KITCHENのAndroidのアプリに関して少しでも知っていただけたら幸いです。 今回ご紹介した設計がベストだとは考えていませんし、まだまだ発展途上です。 アプリの規模にかかわらず、良いものであれば積極採用することはぶらさず、 開発してて楽しい環境を作りながら、より良いアプリをより早く提供できるように努めていければと思ってます。

エブリーのインターンに参加してみた

はじめに

はじめまして。2020年3月からエブリーでインターンをしている田村です。
私はデータエンジニア・データサイエンティストとしてインターンシップに参加し、データ関連部門に配属され、データ業務を担当しています。
今回は、エブリーにインターンとして入社し約4ヶ月間で感じたことをまとめていこうと思います。

目次

1.エブリーのインターンに参加した経緯

2.インターンを通して学んだこと

1.エブリーのインターンに参加した経緯

私は機械学習を主とする統計分野に興味があり大学院に進学したのですが、査読した論文を検証できるデータを保持するインターン先を探す中で、DELISH KITCHENを運営しているエブリーと出会いました。 面談の前にオフィスツアーをしたのですが、まず驚いたのは東京タワーの見える六本木グランドター38階のオフィスです。
食のメデイアを運営していることから、本格的なキッチンスタジオがあり、フードスタイリストの方が日々料理動画を撮影しています。

f:id:kthimuo:20201008145828j:plain

作業エリアは集中できる雰囲気なことや、CTOとのカジュアル面談時に大量のデータを扱うことが出来そうだと期待してインターンとして入社することに決めました。

2.インターンを通して学んだこと

私がデータエンジニアとしてインターンの業務を通じて学んだことを書いてみます。  

・DIKW

まず、初日にデータチームのマネージャーに教えられたことはDIKWモデルというデータがどのように事業に貢献するかというモデルです。詳しい記事はこちらをご覧ください。

・Arm Treasure Data / Databricks / Redashなどのデータプラットフォーム

DELISH KITCHENのログデータの分析だけでも膨大な量で、これらのビッグデータを処理できる計算基盤が必須です。
所属しているデータ部門では、Databricksと呼ばれるApache Sparkをバックエンドとした分析プラットフォームを用いて、データクレンジングなどの前処理や機械学習の処理を実装しています。
またこちらの記事でもあるように、sql,scala,pythonなどの複数の言語を組み合わせて処理を書けるためこれらの言語の基本文法はマスターできました。学校ではPythonを利用した研究開発だけを実装しており、Python以外の言語に触れる機会が無かったのですが、SQLが特に重要だと教えられ、今では自分のやりたい事は大体実現できるようになりました。
インターン生でもエブリーの全てのデータに自由にアクセスでき、分析する基盤まであるのはとても良い環境だと思います。

・他部門との連携

私の所属するデータ関連部門では、エブリーが運営している複数のメディアから発生するデータ分析依頼や要望を引き受けています。
「●●を知りたい」などの抽象的な課題を具体的な課題に落とし込んだ後、どんなデータを提供したら良いのか、どんな見せ方をしたらいいのかを考え、Redashのダッシュボードを提供したり統計的な手法で知見を伝えたりします。
他部門の業務を経験が浅いインターンが他部門の業務や課題を理解するのは難しいですが、エブリーではインターン生も他部門の議事録や組織図をconfleneceやカオナビで把握できます。

・リモート環境

コロナの影響でエブリーでは3月からインターンも含めリモートワークを推奨しています。
私もリモートでのインターンは初めてで、移動時間がなくなったり服を選んだりする手間がなくなったりメリットが多いなと思いました。意思疎通が対面よりもスムーズにできないという問題がありますが、私のチームでは毎日30分程のミーティングを行い、課題の共有やコミニケーションを行うようにしています。
会議に参加できなくても録画しておけば後から見直せるので便利です。
最近では半年に1回の社員総会もリモートで行いこちらに詳しい記事があります。

最後に

エブリーではデータ関連部門以外でもエンジニアのインターンを募集しています。
メディアの運営に携わってみたい、アプリの開発に携わってみたいという方はこちらをご覧ください。

MLflowとOptunaを使ってMLOps環境を構築してみた

はじめまして。2020年4月からエブリーに新卒で入社した伊藤です。 データエンジニア・データサイエンティストとしてデータ関連部門に所属し、日々データ業務に関わっています。

データ業務の1つである機械学習モデルの開発は、実験環境でモデルの精度を確認した上で本番環境に適用するプロセスを経ます。

今回は機械学習の実装で利用したMLflowとOptunaを組み合わせが、モデルの開発・運用・レビューで高いアジリティを提供できると分かり、導入事例として紹介できたらと思います。

取り組んだ問題

最近のデータ業務で、DELISH KITCHENユーザの過去の行動を分析し、ある特定のアクションが将来どの程度の確率で行われるかを機械学習で予測する、という問題に取り組みました。

ユーザがDELISH KITCHENをどのように使っているのか(レシピのお気に入り登録など)という情報は、集計された状態でデータウェアハウスに蓄積されています1

まずはそれらを抽出し、予測を行うための特徴量データセットとして用意した後、パラメータの調整や特徴量の取り方などを試行錯誤しつつ、実験環境で機械学習モデルを構築しました。

大学の研究やデータコンペティションでは、多くの場合高い精度のモデルができたら一旦区切りとなりますが、企業で開発を行う場合にはこれを実際のビジネス施策でも使う必要があります。

そのためには、実験環境で行った「特徴量の抽出」→「モデルの学習」→「モデルの予測」→「最終結果の出力」という4つの段階が本番環境で1つのパイプラインとして自動化されており、かつ持続的に運用できる状態でなければなりません。

MLOps

ここでMLOpsという概念を紹介したいと思います。

MLOpsとは機械学習のライフサイクルの管理やその環境を指す考え方で、機械学習(Machine Learning)と運用(Operations)を組み合わせた言葉です。

MLOpsの考え方に基づくと、上に挙げた4段階それぞれの品質を持続的に維持・改善しており、かつ全体としても1つのパイプラインとして運用できる環境の構築が重要になります2

特に、ユーザ行動を使う今回のようなケースでは、予測したい行動データが日々更新され、実験では良い結果が出ていたモデルも時間が経つと「古い」モデルとなってしまうため、新しいデータを使ってモデルを定期的に更新していかなければなりません。

さらに、将来の研究でさらに良さそうなモデルが見つかった場合は過去のモデルと比較してより良いものをパイプラインに組み込めるような設計になっていると、より効果的な運用が可能になります。

このようなMLOps環境を実現するため、今回はMLflowとOptunaという2つのツールを組み合わせて活用しました。

MLflow

MLflow3とはDatabricks社が開発した機械学習のライフサイクルを管理するためのプラットフォームです。

MLflowを使うと、学習結果の保存や過去の学習結果との比較が簡単に行えるようになります。

簡単な例としてロジスティック回帰によるアイリスデータセットの分類問題を考えると、実行環境によって設定は多少異なりますが、「ハイパーパラメータ」「予測精度」「学習モデル」の3つが対応した学習結果をおおよそ次のように登録できます。

from sklearn.linear_model import LogisticRegression
import mlflow
import mlflow.sklearn

with mlflow.start_run():
    lr_c = 0.1
    model = LogisticRegression(C=lr_c).fit(x_train, y_train)    
    score = model.score(x_test, y_test)
    
    mlflow.log_param('C', lr_c)
    mlflow.log_metric('Mean Accuracy', score)
    mlflow.sklearn.log_model(
        sk_model=model, 
        artifact_path='mlflow_demo', 
        registered_model_name='lr_iris'
    )

登録された学習モデルはMLflowを通してバージョン管理され、バージョンを指定したロードもできるため、新しいモデルと古いモデルとの性能比較を行ったり、時期や状況に応じたモデルの入れ替えも可能です。

No Image

それぞれのバージョンに対して、パラメータと予測精度が保存されています。

No Image

Optuna

Optuna4は、Preferred Networks社が開発したハイパーパラメータチューニングのためのフレームワークです。

本来ハイパーパラメータチューニングは、パラメータの値を変更した学習結果を確認しながら最適値を見つける、非常に手間の掛かる作業です。

そのため、パラメータそれぞれに候補となる値を用意し、それらの組み合わせを全て試して最適なものを見つける、グリッドサーチと呼ばれる方法が主に使われていました。 しかし、グリッドサーチでチューニングの工程は自動化できるものの、パラメータの種類・候補が多いほど組み合わせが爆発的に増加するため探索に時間がかかってしまう、そもそも候補に含まれない値は探索できない、といった問題がありました。

Optunaでは、探索する値の候補を探索範囲として渡すことが可能です。 また、過去の探索結果に基づいて次に探索すべき範囲を判断するようなアルゴリズムが実装されているため、指定された範囲に含まれる値全てを試さずに、より確からしい最適解を導き出すことができます。 これにより、Optunaを使うとグリッドサーチよりも柔軟で効率的なハイパーパラメータチューニングが実現できます。

もう一度ロジスティック回帰によるアイリスデータセットの分類問題を考えます。 先ほどの例ではハイパーパラメータ C を決め打ちで設定していましたが、ここではOptunaを使い交差検証によるチューニングをしてみます。

from sklearn.linear_model import LogisticRegression
from sklearn.model_selection import cross_val_score
import optuna

def objective(trial):
    lr_c = trial.suggest_loguniform('C', 1e-4, 1e2)
    model = LogisticRegression(C=lr_c)
    score = cross_val_score(model, x_train, y_train, cv=3)
    accuracy = score.mean()
    
    return accuracy
  
study = optuna.create_study(direction='maximize')
study.optimize(objective, n_trials=10)

best_params = study.best_params

最適なパラメータは best_params として辞書形式で得られるので、その後は最適なパラメータでモデルを学習 → MLflowで結果を保存、という流れになります。

今回モデルの学習に用いるユーザ行動は時間的に変化するデータであるため、モデルの品質を持続させるには定期的に新しいデータで再学習する必要があります。 Optunaを使うとデータに応じて適切なハイパーパラメータを自動的に探索・決定できるようになり、 手動による介入を行わずに一定レベルの品質でモデルの再学習を行えます5

MLOps環境の構築

それでは、MLOps環境をどのように構築したのかを紹介したいと思います。 エブリーではデータ分析基盤としてDatabricksを使っているため、Databricks notebookをベースに環境構築を行いました。

tech.every.tv

まず、一連のパイプラインを「特徴量の抽出」「モデルの学習」「モデルの推論」「最終結果の出力」という4つのステップに分け、それぞれを順番に実行できるようなジョブを作成しました。

肝となるのが「モデルの学習」と「モデルの推論」のステップで、ここでMLflowとOptunaを活用します。

「モデルの学習」では、MLflowに登録されている最新の前処理モデルと予測モデルの2種類をロードし、検証用のデータを使ってこれらのモデル性能の検証を行います。 検証結果が良ければそのまま次のステップへ進みますが、もし検証結果が悪いようなら、再学習するためのタスクを呼び出してこれらのモデルをアップデートします。

モデルの再学習では、実験環境には存在しない本番環境の最新のデータを利用したハイパーパラメータチューニング、モデルの学習を行います。

チューニングするパラメータはOptunaに登録されており、探索はOptunaに実装されているアルゴリズムに従って行われるため、データに合わせた柔軟なチューニングが自動で行われます。 これにより、データが更新される度に必要となるハイパーパラメータの検証工程が減り、パイプラインの維持・改良をスムーズにできるようになります。

再学習後に得られたモデルはMLflowでバージョン管理し、必要に応じて過去のモデルとの比較もできるようにしました。

「モデルの推論」ではMLflowを通して最新のモデルをロードし、最新の行動データに対する予測を行います。 1つ前のステップでモデルの性能に関する検証を行っているため、ここで得られる予測は(完全ではないかもしれませんが)ある程度品質が保証されたものになります。

まとめ

以上、実験環境で機械学習モデルを作成するところからMLOps環境に昇華させるまでを、簡単に紹介させていただきました。

ここで紹介したパイプラインは現在バッチとして登録されており、定期的にモデルの更新とユーザ行動の予測が行われています。

現時点で運用を始めて数ヶ月が経ちましたが、現在も当初の予測精度付近で安定しており、構築した環境がモデルの品質維持に役立っているのでは、と考えています。

今回の業務を通して、MLflowとOptunaの有効性を改めて確認できたとともに、エブリーに入社するまではあまり経験してこなかった実運用環境の構築について新しく学べました。

今後は、MLOps環境を運用しつつ、新たなビジネス施策にも貢献できれば嬉しく思います。

ここまで読んでいただきありがとうございました。

データ分析が捗るDatabricksのススメ

はじめに

はじめまして。2020年4月にエブリーに新卒で入社した吉田です。
私はデータエンジニア・データサイエンティストとして入社し、データ関連部門に配属して日々データ業務に関わっています。
私達のチームでは、巨大なデータを集計・分析するための基盤としてDatabricks社のDatabricks を使用しています。
今回の記事では、私達の業務におけるユースケースを交えながら、Databricksの利点や、活用方法を紹介できたらと思います。

Databricksとは

DatabricksはApache Sparkベースの分析プラットフォームであり、データ分析の際に行う

  1. Data Sourceからデータを集約
  2. 分散処理によって高速にデータを整形
  3. 分析
  4. 可視化や集計したデータをData Lakeに保存

といった流れをDatabricks notebookを用いて記述し、Spark clusterを用いた高速な分散処理が可能です。 データ分析によく使われているツールであるJupyter notebookと同じような感覚でビックデータを扱え、インラインでの図表表示などにも対応しています。

またSpark clusterの設定やワークスペース、学習済み機械学習モデル、Jobの管理をWebUIを用いて行え、非常に扱いやすい分析プラットフォームです。

エブリーでDatabricksをどう使ってるか

私達のチームではデータ分析をする際に

  1. Arm Treasure DataやS3、BigQuery、Deltaからデータを抽出
  2. データを加工し、Deltaに保存
  3. Deltaから加工済みデータをTreasureDataに保存
  4. TreasureDataをRedashから読み込み可視化

という流れを行っています。
この2の工程でDatabricksのnotebookを用いています。
No Image

SQLでは複雑なクエリになってしまう処理をDataFrameとして処理すると、コードを簡潔にでき可読性が上がります。

なぜDatabricksなのか

Databricksを扱うにあたり便利な機能を紹介していきます。

豊富なData source

DatabricksではS3上のcsvファイルやBigQuery、TreasureDataのデータ等をSparkを用いて高速に取り込めます。

特にDatabricks社が公開しているオープンソースのストレージレイヤーであるDelta Lakeを用いると、データへの信頼性とパフォーマンスが高まります。 Delta Lakeには

  • ACIDトランザクションによりデータの整合性を確保
  • スキーマの適用によりデータの過不足や不正を検知
  • スナップショット作成によるロールバックや過去データの参照
  • Sparkの分散処理による高速な読みこみ

といった機能が存在します。 これらの利点を、Spark Dataframeへの簡単なAPIによって使用できます。

// 書き込み
sparkDataframe
.write
.format("delta")
.save("delta/path")
// 読み込み
val sparkDataframe = spark.sql("""
select * from delta.`delta/path`
""")

ひとつのnotebook上でscala,python,sql等を混ぜて実行できる

Databricksのnotebookではセルの先頭で%python%scalaといったマジックコマンドを記載すると、notebookに指定した言語とは別に、セル単位で使用する言語を選択できます。
pythonはデータを柔軟に扱え、データ分析において強力な言語ですが、型安全でない、scala等に比べて処理速度に劣るといった欠点が存在します。
そこでノートブック中で高速にしたい処理をscalaで処理し、分析部分をpythonで扱うといった運用が可能です。

履歴管理機能や同時編集機能が便利

Databricksにはnotebookの履歴を管理する機能や、複数人で同時に1つのnotebookを編集する機能が備えられています。
履歴の管理機能ですが、例えば

  • notebookをリファクタリングしていたら重要なセルをまるごと消去してしまった
  • データをいじくり回していたらnotebookがわけわからなくなった

といった場合に、自動的に保存されている履歴から任意の履歴の復元が可能な機能です。
この機能はgitでの管理に関係なく履歴を保存してくれるため、わざわざgitで管理するほどでもない簡単な分析でも気軽に利用できるのが利点です。

次に複数人でのnotebook編集機能ですが、Databricksでは自分が見ているnotebookを他の人が閲覧している場合、閲覧しているユーザ名とそのユーザがどのセルを見ているかがセルに色がつき、わかるようになっています。
この機能を活用すると、複数人でnotebookを見ながら分析方法についての議論等が簡単に行なえます。

Gitによってバージョン管理が可能

DatabricksのnotebookではIpython notebookとは異なりセルの出力結果等がファイルに記載されないため、gitを用いたコードのバージョン管理が可能です。
これにより、一般的なコード開発と同じような

  1. コーディング
  2. P/Rを送る
  3. レビューしてもらう
  4. 修正
  5. 取り込み
  6. 運用

といった流れをデータ分析にも適用可能です。
そのため、クエリミスや不適切なデータ処理を可能な限りなくせ、また、より良い分析方法を協議できます。 それにより、信頼性の高いデータ分析を行えます。 No Image

また、gitホスティングサービスに連携したCircleCIを用いると、notebookのP/Rマージ時に本番環境への自動デプロイや、Job作成が行えます。 No Image

notebookをバッチスクリプトとして扱える

Databricksで作成したnotebookはそのままDatabricks上でバッチJobとして登録できます。

使用するクラスタ構成や、実行するnotebook、スケジュールやリトライ回数等を簡単に設定できます。

notebookをバッチとして登録する利点として、 - 過去の実行結果がnotebookの出力としてセル単位で残る - セル単位で実行され結果が残るため修正が容易

というものがあります。

実行結果がセル単位で残るため、各セルごとの実行時間を比較してパフォーマンスが悪い処理を容易に特定可能で、パフォーマンス改善中の比較データとして過去の実装の結果を参照できます。
私達のチームでは、バッチのアラートをSlackに通知しており、アラート発生 -> セル単位の処理結果を見てエラー箇所を特定しリカバリという流れで安定したバッチ処理の管理を行えています。 No Image

まとめ

以上、エブリーでのDatabricksのユースケースと利点を簡単に紹介させていただきました。 Databricksを使用すると

  • Spark clusterによるスケーラブルな計算基盤
  • Delta lakeによるデータの安全性
  • データ分析の信頼性

を確保できます。
こちらはあくまで一例ですが、Databricksの利点等を知っていただけたのであれば幸いです。