〜DWH外観図〜こんにちは、今年の1月に会員事業部から技術部データ基盤グループへ異動した佐藤です。先日、京まふ2019前夜祭イベントに参加するために人生で初めてピカピカ光る棒を買いました。新卒で入社してから2年ほど分析作業をしていた身から、データ活用基盤を作る側へ立場を変えました。今回は新たに身を移したデータ活用基盤の外観を説明したいと思います。2017年にも同内容の記事が投稿されていますので、当時との違いを中心に説明していきます。以下が2019年10月現在におけるクックパッドのデータ活用基盤の全体像です。Serverが大きな変更点となっています。2017年の図にDmemoはありませんでしたが、記事本文にある通り当時から活用していました。図が煩雑にならないよう、レシピサービスを中心にまとめていますが、クックパッド社が運営する全サービスについて同様のワークロードでRedshiftにデータを集約させています。図では省略しましたが、Firebaseなどの外部サービスから得られるデータもRedshiftに集めています。一つ一つの処理をみていきましょう。flow)クックパッド社内でサービスのマスターデータを管理するDBとして利用するDBMSは主にMySQL・PostrgreSQL・DynamoDBがあります。多いのがMySQLで、最近DynamoDBが増えつつあります。MySQLについてはpipelined-migratorという独自開発の専用システムを利用しています。こちらは管理コンソール用の専用Webサイトが社内ネットワーク上にあり、テーブル取り込みの様子を確認できます。ボタンひとつでRedshiftに取り込むテーブルやDBの追加・削除が手軽にできるようになっています。Service(以下DMS)を利用しています。pipelined-migratorがまだ現段階ではMySQLにしか対応しておらず、かつ社内でPostgreSQLの利用が比較的少ないため、一時的にDMSを利用しています。PostgresSQL対応版も開発中であり、今後PostgreSQLからのテーブル取り込みもpipelined-migratorに一本化していく予定です。DynamoDBについてはまだ実績が少ないのもあり、定型化しているものの手作業でインポートしています。Firehose経由で、S3に追加データを吐き出します。Spectrumでクエリアクセスができるようになります。DynamoDBデータの取り込みフローpipelined-migratorはbricolageとmys3dumpを組み合わせて作られています。Loadシステムと昨年末に書かれた記事に登場したPrismの両方が使われています。Spectrumを中心にして構築するようにデータ移行作業を実施中です。Loadシステムからのログ取り込みはゆくゆくは退役する予定です。LoadからRedshift内部へのロードとPrismからRedshift外部(Spectrumでアクセス可能なS3バケット)の2経路が同時に存在していますが、次にまたDWH外観図を書く頃にはPrismに一本化されていることでしょう。サービス開発者側から「新規にログを取り始めたい」となった場合、以下の手順でロードを行います。*.strdefというYAML形式のファイルにログ定義を書くtech/dwhというDWHが管理するリポジトリへ上記ファイル追加PRを出してもらうログ関係者&DWHチームメンバーがログ定義に関するレビューをするアプリケーションから送られてきてS3にログが到達したしたことを確認し、strdefファイルの適用を行うサービス開発者に1~3までを行ってもらい、DWHでは3~4を担当します。してみるといちいちログをとるのに手順が多く、面倒に思われるかもしれません。このフローで運用している背景には、ログを取りたいと思った人にstrdef定義を通してきちんとログ設計をしてもらいたいという意図があります。これはDWHに限らない話ですが、ロギングが始まってしまえばログは修正できません。プログラムのリファクタ感覚でカラム名や型定義は変更できないのです。してもやむを得ず発生することはありますが、問題を先送りにした場合はツケが回ってきます。ログ取り自体は気軽に行えるが、その設計にはきちんと考える時間を取りましょうという思いがあって、こういった手順となっています。Load・Prismのどちらもコンソールが用意されており、ログが順次ロードされていく様子を確認できます。Loadの実装はbricolage-streaming-preprocssorとbricolage-streaming-loaderとして公開されています。Spectrum活用が進んできましたが、Redshift内部の処理に関しては既にだいぶ完成していたため新たに手を加える必要はありませんでした。2017年当時と同様、bricolageを用いて書かれたSQLバッチをKuroko2というジョブ管理システムで定期実行しています。Redshift内部のデータアーキテクチャについても従来通りの入力層・論理DWH層・論理データマート層の3層区切りとなっています。2年間運用してきたことでこれら各層に格納されているデータは充実してきており、2年前と比べて3層ともに成長しています。Redshift内部の加工処理はbricolageとKuroko2を組み合わせて作られています。Desktopでアドホックな分析作業を行っているかもしれません。これら各ツールは全て内部テーブルと同じようにSpectrumテーブルへアクセスできるため、各自分析者が自分の使いたいツールを自由に選べる状態になっています。分析者は後述するDmemoやSlackにおけるデータ分析お悩み相談チャンネル、#data-analysisを駆使して社内のデータを分析しています。日々、#data-analysisやissue上で分析用SQLのレビューが行われています。Serverに移行されました。移行に至った理由は過去の記事にも書かれた通り、Redashのキューまわりの実装に難があったためです。Serverに移行した今では各部署で活用されており、エンジニア以外にも職種を問わず広く利用されています。Desktopではライセンスが別契約となるため、実際にダッシュボードを作りたい人はライセンス申請が必要となります。この申請フローは定型化されており、ヘルプデスクへ申請を出すだけでライセンスキーが割り当てられるようになっています。Redashは諸事情がありまだ完全退役とはなっていませんが、アクセス&更新がなされているダッシュボードはほぼありません。登場したDmemoも現役で活躍中です。Dmemoは毎晩Redshiftにアクセスし、DWH内部にある最新の全テーブル情報を取り込みます。取り込んだDB・スキーマ・テーブル・カラムの各階層ごとに説明を書くことができ、その履歴も残せます。Dmemoに十分情報が蓄積されていれば、PR上でのやり取りやデータ分析についてSlack上で聞かれたときなどにDmemoのURLを貼って一言二言伝えるだけでスムーズにデータに関する情報伝達が行えるようになります。Dmemo操作例(Techlife用にローカル開発環境上でダミーデータを用いて撮影したものです)新しく入社した社員やインターン生にデータに触れてもらうときに一旦DmemoのURLを共有しておくとその後の話が円滑に進むようになります。ログに関する何かしらのインシデントが発生した際には「v1.0.0のアプリケーションではIDがズレている」等々のメモを書いておくことで、後でログデータを集計して奇妙な結果が出たときに即座に気づくことができるようになります。viewにも対応しました。DmemoはこちらのGithubリポジトリで公開されています。バッチ処理用バルクエクスポートこちらも2017年の記事と変わらず、Queueryとredshift_connectorが使われています。他のサービスからも利用できるようなDWHを構築しておくことで、データ活用基盤が分析のみならず様々なサービスやプロダクトにまで活用されるようになります。過去にTechlifeでご紹介したデータ活用基盤を利用したシステム運用の記事を下記に載せておきます。Redshiftから外部システムへのバルクエクスポートはQueueryとredshift_connectorが使われています。上記がデータ活用基盤の外観図となります。これで完成ではなくこれからも開発を続けていく必要があります。最後に、DWHに残っている主な課題について述べたいと思います。Loadと外部テーブルへロード(S3へのParquet変換)する新方式のPrismの両システムが並列で稼働しています。Loadでのロードを廃止するためには内部テーブルに依存している全ジョブの停止・外部テーブルへの移行が必要となります。186のジョブと284テーブルを一つ一つ検証した上で移行と削除を行っていく作業は自動化ができない、泥臭い手作業となります。その中で歴史的経緯に基づく仕様を発見したり、現状のジョブが間違っていたり等が発見されていきます。この移行作業についてはDWH総出で丁寧に移していく他無く、地道にやっていくことになります。Serverの運用も依然として作業コストがかかっており、なんとかすべき課題です。ServerはTableau社側から新しいバージョンが提供されるたびにアップグレードしていく必要がありますが、ダッシュボードのポータルサイトという重要なサービスであるためこの作業は慎重に行う必要があります。アップグレード作業の際には事前に社内アナウンスを出し、メンテナンス時間を確保して行っています。過去にアップグレード作業に失敗し、Tableauサポートと連絡をとりつつアップグレードをするということもありました。Server運用における1つ目の課題です。TableauはSlackとの連携が弱いという弱点があります。一応、メール通知とZapierという外部のオートメーション化サービスを組み合わせることで自動通知を実現できますが、こちらにも実は問題があります。現在クックパッドでは専用botでの通知運用をしつつ、Tableau公式によるSlack連携機能がくる日を待ちわびています。ライセンス管理についても課題があります。先にはダッシュボード用BIツールの項目で「ヘルプデスクへ申請を出すだけでライセンスキーが割り当てられる」と書きましたが、定型化したとはいえここは裏側で手作業が発生しています。根本的な負荷削減にはなっていないため、できる限りライセンス付与の作業負荷がなくなるよう自動化をしたいところです。データ活用の推進データ活用基盤が整いつつある今、基盤業務のその先のデータ分析の啓蒙活動に比重を置くフェイズに突入しつつあります。今までも社内でSQL勉強会が開かれたり等、各所でデータ分析の民主化は進んできていました。草の根運動に頼るだけでなく、DWHが組織として継続的にデータ活用を推進していく必要があります。こちらに関しては具体的な方策やマイルストーンもありませんが、来期からの一番の課題となることでしょう。まとめ今回は以前お伝えしてから2年経ったデータ活用基盤の全体像をお話しました。一度に書ききるには多すぎるため、前回との差分を中心に書きましたのでぜひ2017年に公開した記事と比較してみてください。私達、技術部データ基盤グループは「クックパッドの全社員がデータに基づいた意思決定を行えるようにする」を目標に日々の業務に取り組んでいます。分析者の望む最強のデータ分析環境を提供したい方、余計な手間をを要せず分析作業にのみ集中できる最高のデータ分析環境に浸ってみたい方、ぜひ私達と一緒にデータを駆使してより良いサービス作りをしてみませんか。今年1月に研究開発部から分離して発足しましたスマートキッチン事業部の山本です。開発をすすめています。クックパッド社内に工房(Fab)を作りましたスマートキッチンサービスOiCyは、レシピ情報と家電機器の連携で生み出されるサービスで、サービス開発に加えてサービスと連携する家電機器が必要になります。そのため、家電メーカーとの連携をすすめていますが、同時に自前での家電機器開発も行っています。恵比寿のクックパッドオフィス内に立ち上げました。工房には、3Dプリンタやレーザーカッターなどの加工設備が設置されており、業務内外を問わず社員の利用が可能になっています。工房生まれの自前(改造)家電たちの紹介この工房で生まれた、クックパッド自前(改造)家電の一部が、先日開催されたスマートキッチンサミットジャパン2019(SKSJ2019)で公開されました。Waterは、水の『硬度』と『分量』をレシピに合わせてボタン一つで出してくれる、電動ウォーターサーバーです。スマートフォンのアプリ上でレシピを閲覧すると、そのレシピに書かれている水の『硬度』と『分量』(※)が自動的に装置に転送されます。ユーザーは装置上のボタンを押すだけで、閲覧しているレシピで使うための適切な水を得ることができます。『硬度』と『分量』は、ジョグダイヤルを回して手動で調整することもできます。※現状ではクックパッドのレシピ全てに硬度に関する記述があるわけではありません。本機は、2つのチューブポンプを用いて、『硬水』と『軟水』2つのボトルから水を排出する装置です。使用したチューブポンプは3.5ml刻みで排出量を制御、最速で1分間に1.4Lの水を排出することができます。制御用のマイコンシステムにはM5Stackを使いました。理由は、技適が取れていてかつとても安価、ネット上に参考にできる情報が豊富にあって、ライブラリも充実しているからです。周辺デバイスへの信号は、モーターの速度制御をするPWM信号のみM5StackのGPIOから直接出していますが、それ以外はI2C接続したGPIOエクスパンダを経由してやり取りをしています。GPIOエクスパンダ側で、信号の変化を割り込み制御をする予定でしたが、WiFiのライブラリと同時使用するとファームにリセットがかかるという現象があり、イベント直前で時間がなかったためこの問題解析は保留して、割り込みなしのポーリングで、ジョグやモーターの回転を拾う処理になっています。モーターの回転は、チューブポンプの回転部分とポンプ外装の間に隙間があるので、100円ショップのネオジウム磁石をそこに接着、ポンプ外側に設置した磁気センサから非接触で回転検出をしています。この方法では回転方向は分からないのですが、チューブポンプは負荷が非常に大きくギア比の大きなモーターが付いており、外部から強制的に回すことはほぼ不可能です。そのためポンプ回転部分はモータードライバに入れている信号の向きにしか回らないため、特に回転方向を検出する必要はありません。磁石の貼り付け位置を、チューブポンプのローラー部分にすることで、水の排出綺麗に途切れるところで正確にモーターを止められる”位置制御にも利用しています。OiCyWaterのメカ構造チューブポンプはモーター部分が長く突き出した構造をしていて筐体へのおさまりが悪いため、ベルトとプーリーを用いてモーター部分をポンプ本体とタンデム構造にし、2つのチューブポンプを向かい合わせに対向させるメカ構成にしました。2つのチューブポンプ、2つのモーターは2mm厚のステンレス製の背骨に固定されて、チューブポンプを回す強力なモータートルクに負けない強靭な剛性を持たせました。工房のレーザーカッターでは、金属の切り出しはできないため、この背骨部分の制作のみ外注先に頼んで特急で作っていただきました。ペットボトルを下向きに指すジョイント部分については、弁のついたペットボトルキャップと交換する部分はペット用の給水器の部品を流用、刺さる側の部品は3DプリンタをつかってABS樹脂で成形しました。2Lの水の水圧がかかっても水漏れをしない構造を作るのには試作検証改良を繰り返す必要がありましたが、3Dプリンタが手元にあることは短期間での開発にとても役立ちました。WiFiを通じて自動的に装置に転送されるようにしたものが、OiCyサービス対応WiFi電子レンジ(開発名:SIGMA)です。電子レンジは、強電系に非常に高圧な回路と大容量コンデンサを搭載しており、改造には危険を伴います。専門的な知識のない場合には絶対に真似しないようにお願いします。今回の改造は、できる限り装置の深い制御部分に手を入れず、UI部分を乗っ取る形でHackしました。することで、強電系の回路に一切触れずに欲しい機能を実現することができました。電気量販店で、改造しやすそうな電子レンジを探すところから、開発は始まります。改造用の電子レンジを選択する上でのポイントは、液晶表示やタッチパネルなどを用いてるものは、現在の状態を正確に把握するための難易度が高いため避けます。LEDのみ、物理スイッチのみでUIが構成されていて、かつスイッチに複数の機能が割り当てられていないものが好適です。Waterと同様に、制御用のマイコンシステムにはM5Stackを使いました。この電子レンジは、UIが、LEDと2つのジョグスイッチだけで構成されていたので、これらの入出力と扉の開閉センサをロジック回路処理(時分割表示のLED信号の復調回路)を噛ませてGPIOエクスパンダに接続し、M5Stackからは全体が一つのI2Cデバイスとして見えるようにしました。外装は、操作パネル部分のジョグやLEDをすべて外し、レーザーカッターで加工した3mm厚の乳白色のパネルで覆い、表面上からはM5Stackの表示パネルとボタンのみしか見えない構造になっています。スマホからのレシピ情報転送以外に、M5Stackのボタン操作によるレンジ設定変更が可能です。加熱のスタートやキャンセルはドアの開閉で行い、ボタン操作は不要です。IHプレート(開発名:OMEGA)です。改造用のIHプレートを選ぶポイントも電子レンジとほぼ同じです。リバースエンジニアリングの結果、この機器は本体部分とUI部分をクロック同期式の変則的な双方向シリアル通信で構成されていることが分かったので、UI基板を取り外し、代わりにロジック回路処理(入出力信号の分離)を噛ませてGPIOエクスパンダに接続して、M5Stackからは全体が一つのI2Cデバイスとして見えるようにしました。外装は、UIパネル幅に対してM5Stackの方が奥行方向に長いため、張り出した顎の部分を3Dプリンタで成形して、表面処理をした上で塗装したものを取り付けてあります。パネル部分は、電子レンジと同様にレーザーカッターで加工した3mm厚の乳白色のパネルで覆って統一感を持たせてあります。社内に工房がある強み製品やサービス、機能など、我々がこれから作ろうとしているものが、本当に顧客にとって価値があるのか?モノができてから実際にユーザーに提供してみたら、期待した価値がなく失敗・・・のでは時間と資本を大きくロスしてしまいます。そこで、我々は、Googleのスプリントに則って、3〜5日で課題から仮説を導きだし、ソリューションを立て、プロトタイプを作り、ターゲットユーザに当てて仮説検証を行う、という方法をよく用いています。佐藤彩香スマートキッチン事業部でも、短いものでは3日程度で、ハードウェアのプロトタイプを作って、実際にユーザーに使ってもらって、顧客価値を検証しています。今回紹介した3つの家電デバイスは、各2週間程度の開発期間がかかっていますが、顧客価値検証用に現場で実際に使用し、継続的に改良が行われています。いった機器の開発改良は、外部のリソースに頼っていてると短時間での開発は難しく、価値検証に時間がかかってしまいます。使いたいときにいつでも加工・製作に使える『場』と『機材』が社内にあることは、超高速ハードウェアプロトタイピングでは極めて重要です。この『場』と『機材』を活かしきれる、メカ設計〜加工〜回路設計〜回路製作〜ファームウェア設計実装〜実機デバッグといった一連のプロトタイプ開発を一人で一貫してできる、フルスタックエンジニア人材を絶賛募集中です。まとめ『その程度のプロト、俺がやれば1週間でできる!』『3日でできる!』というプロトタイプエンジニアスキルをお持ちの猛者のかたは、是非我々のプロジェクトにJoinしてください。職種:プロトタイプエンジニア(スマートキッチン)同時に、こんなイカれたデバイスを操作するiOSアプリを書きたいという、キワモノ好きのiOSエンジニアとデバイスとアプリをユーザーとつなぐ素敵なUI/UXデザインを担当するデザイナーも絶賛募集中です。機械学習関係のプロジェクトで数多く生成される一時オブジェクトおよびそれらのオブジェクトを保持するファイル(一時ファイル)を管理する取り組みについて解説します。本稿の前半はデータを分析するプロジェクトの一般的なフローと起こりがちな問題(コードの品質管理)について解説します。後半はプログラム上で生成されるオブジェクト群をファイルに自動でキャッシュを管理するツール(Hideout)を使って、コードを整理整頓しやすくする施策について紹介します。データを分析するプロジェクトの一般的なフローまずデータを処理するプロジェクトや機械学習プロジェクトの典型的なフローについて考えてみます。単純に機械学習器を取得した入力に対して適用するプロジェクト、次にもう少し複雑な事例、アプリケーションで利用するデータを生成するプロジェクトのフローについて見てゆきます。単一の機械学習器を適用するプロジェクトデータ分析するプロジェクトの典型例として機械学習器を入力データに対して適用するプロジェクトを考えます。学習用のデータのように静的に変化しないデータはレポジトリに同梱されることもありますが、Webサービスのデータが対象の場合、推論用のデータの多くは日々変化するため、データベース(DWH)から動的に取得します。機械学習を適用するプロジェクトは取得したデータを多段に変換しながら出力となる判別結果を生成してゆきます。以下の図は一般的な機械学習を利用したプロジェクト検証スクリプトのフローです。単一の機械学習器を適用するプロジェクト上記のプロジェクトでは必要なデータを取得、学習、推論(テスト)と連続して処理がおこなれています。各処理ごとにデータは変換され、生成されます(例えば学習後にはモデルオブジェクトが生成されます)。バッチ処理(こちらを参照)はちょうどこのような内容になっています。このバッチでは一部のデータを切り出して処理しているのですが、それでも取得、学習、推論(テスト)ステージでかなりの時間がかかっています。データを多くのオブジェクトを生成しつつ多段で加工してゆくことも一般的です(End-to-Endの学習で一度に処理してしまう場合もありますが)。Baseの生成プロジェクトがあります。これまで紹介した2つのタイプのプロジェクト(単一の機械学習器を適用するプロジェクト、アプリケーション用データを生成するプロジェクト)のどちらのプロジェクトタイプでも、まず一つ以上の入力データを抽出します。データは入力データ、必要なリソース(辞書)、機械学習器が出力したアノテーション結果などがあります。その後のデータ変換、集約処理が多段に続きます。各処理では一時オブジェクトを入力として別のオブジェクトを生成します。実行はそれぞれ時間がかかります。このことがデータ分析プロジェクトを中長期メインテナンスする場合に品質上の問題を引き起こします。データ処理スクリプトに対する修正要求とコード品質問題データを分析、加工するプログラムでも普通のプログラムと同じように機能追加の要求にさらされ修正され続けます。E2Eテスト(機械学習の学習、Inferenceなど)を走らせます。しきれないことがどうしても発生するため、一部のデータを使ってプログラムを実行して変更が問題を発生していないかも確認したくなります。このような検証目的の実行時に扱うデータの規模は大規模ではなくても、各ステージごとの処理に十秒から数分かかってしまいます。結果、微細な修正をした後にコードに問題がないかを確認するだけでも結構な時間を消費してしまいます。実行に時間がかかりコードを修正をするコストが大きくなるため、コードを修正するサイクルが大きく(試行できる回数が少なく)なり、コードを整理するハードルが高くなってしまいます。このような状況ではプログラムの検証実行や、テストに時間がかかりすぎるためコードの品質をキープしづらくなります。検証時の実行に時間がかかってしまう問題に対するする解決策として、以下のような対処方法が考えられます。一時ファイルの手動追加データの取得、生成時間を省略するために、データベースから切り出した入力データや機械学習器が出力したモデルファイルのような一時データを保持するファイル(一時ファイル)をレポジトリや、ローカルディレクトリに同梱しているプロジェクトを見かけます。データ分析プロジェクトの一時ファイルは、モデル、データベースから抽出した辞書リソース、前処理済みの入力データなどがあります。以下のプロジェクトでは入力ファイルに前処理を適用したファイル(preprocessed_input1.txt)と、機械学習器が生成したモデルファイル(validation_model1.dat)をレポジトリに同梱しています。validation_model2.dat...もちろんこれらの一時ファイル群は本来はレポジトリに含まれるべきではありません。それでも、こういった一時ファイルを利用することでプログラムの動作検証の速度を向上できます。このように安易に加工済み入力ファイルやモデルファイルをレポジトリに同梱してしまうと問題が発生します。問題の一つは加工済み入力データの生成方法がコードから分離してしまい、プロジェクトが進むにつれデータの加工方法と乖離してしまう点です。入力データも含め、プログラムで扱うデータやオブジェクトはコード修正とともに変化してゆきます。モデルファイルのような生成されたデータを一時ファイルから読み出して検証的に実行している場合、コードの修正によってデータがファイルから読み出しているものから変化し本来は実行時に問題が発生していることがあります。残念ながら一時ファイルを利用して検証実行している場合、このような問題に気がつくのは難しいです。いうのも修正した部分(たとえば検証用に切り出した小規模データでの学習処理)はキャッシュファイルを使うと実行されず、テストやローカル環境での実行は中途半端にうまく動作してしまうのです。テストがレポジトリに添付されたモデルファイルを利用してしまっている場合には、CI環境でもコードの修正にともなうバグを検知できません。このような状況で問題が発覚したときにはコミットすでにがかなり積まれてしまい、問題箇所を同定するのが難しくなっていることがあります。一つの問題は、レポジトリを中長期メインテナンスすると発生します。本来は一時的な目的でVCSレポジトリに追加されたはずの中間オブジェクトを保持するファイル群は、役割を全うした後も消されることなく(消し忘れ)レポジトリにとどまり続けることがあります。このような消し忘れファイル群はプロジェクトの開発時には問題にならないのですが、時間経過(半年、一年)を経るとエンジニアは生成方法を記憶していないため特に引き継ぎ時に大きな問題になります。必要な一時ファイルを活用するためのもう少しましな解決方法に、関数へのキャッシュ処理の追加があります。検証時の実行速度を向上して開発速度を高めました。以下はMRRの生成プロジェクトで利用されているメソッドの一部です。ingredient_id_mapこの関数は、キャッシュファイルがあればロードしたものを返し、なければ生成したうえで、(キャッシュ)ファイルに保存します。この関数を使うことでローカル環境で(2回目の実行以降)オブジェクトを生成するコストは低減できます。大きめのオブジェクトを生成する関数にキャッシュファイルを生成する処理を付与することでテストや検証目的に実行していたプログラムの実行時間が、数分から10秒程度に減少できました。これによりコードを積極的に整理できるようになりました。このやり方にも問題があります。処理内容とは関係のない内容で関数を埋めてしまうのにも抵抗があります。コードの一部のコンポーネントに限られます。各変換処理にキャッシング処理をベタ書きした状態では対応が難しいです。いう簡素なツールを作って利用しています。データ分析プロジェクト用、ファイルキャッシュHideoutはオブジェクトを生成するタイミングでキャッシュファイルもあわせて生成するツールです。キャッシュファイルをロードしてオブジェクトを返し、なければ指定された生成用関数を呼び出します。関数はオブジェクトを生成するのに時間がかかります(人工的なサンプルですが)。キャッシュするには以下のように記述します。10})funcにはオブジェクトを生成する関数、func_argにはfuncを実行するのに必要な引数を辞書として渡します。HideoutはデフォルトではキャッシュがOffになっています。デフォルトではキャッシュはされず単にfuncに指定された関数を実行してオブジェクトを生成します。キャシュをOnにしてオブジェクトを使いまわしたい場合には環境変数、HIDEOUT_ENABLE_CACHEにTrueを設定します。ローカルで検証しているときにはコマンドを実行するターミナルで環境変数を指定します。生成される中間オブジェクトの一部をキャッシュしています。Makefileをワークフローの管理に使用しています。Base生成用のターゲットを登録してあります。ローカルにおける検証では以下のようにキャッシュをOnにして実行しています。指定した上で実行すると数秒で終わります。HIDEOUT_ENABLE_CACHE=TrueHideoutにおいてキャッシュ設定はデフォルトではOffになっているので、CIやプロダクション環境で誤ってキャッシュファイルが生成されることはありません。Requestをこまめに作り細かくコミットをプッシュすると、キャッシュが効いていない環境でテストが走るため、思わぬ不具合に気づけて便利です。本稿の前半で紹介したようにデータ処理をするプロジェクトには複数のデータソースを複数のステージで多段に加工するものがあります。複数のステージから成るプロジェクト上記の図ではデータを抽出した後「Preliminary1」や「Preliminary2」、「Transform」というステージがあります。ソースコードの一部でしかありません。このようなとき修正が必要な一部のステージだけキャッシュファイルをロードする処理をオフにしたいことがあります。HideoutはHIDEOUT_SKIP_STAGESという環境変数を提供しています。Offにしたい場合が考えられます。キャッシュをしないステージを指示します。Hideoutにおいて指定するステージ名はhideout.resume_or_generateのlabelオプションで付与します。10})今後Hideoutを利用するユーザはプログラム中の関数ではなく、キャッシュファイルを生成している部分に適用する部分に処理を追加します。これはキャッシュする部分を追いやすくするためで、インターフェース名もHideoutが利用される箇所がわかりやすくなるように長く(resume_or_generate)なっています。最近、同僚から「デコレータでやったほうがシンプルなんでは」というコメントを頂きました。そこで今後デコレータのインターフェースも提供してみたいと考えています。まとめ本稿はデータ分析をするプロジェクトにおける一時オブジェクトを保存したファイル(一時ファイル)の扱いについて解説しました。レポジトリに追加するとプロジェクトの保守性が下がります。そこで本稿の後半では、このようなプロジェクトを保守するのに役立つキャッシュツール、Hideoutについて紹介し、一時ファイルを利用しつつもレポジトリをクリーンに保つ方法について解説しました。使ったセキュリティログ検索基盤の構築サービス特性にあった検索システムの設計戦略クックパッド採用説明会「クックパッドはサービスの作り手を採用したいんです。/*}*/スターをつけました引用をストックしましたストック一覧を見る閉じる引用するにはまずログインしてくださいログイン閉じる引用をストックできませんでした。再度お試しください閉じる限定公開記事のため引用できません。