株式会社LIFULLのブログ - TECH PLAY

TECH PLAY

株式会社LIFULL

株式会社LIFULL の技術ブログ

664

テクノロジー本部のyoshikawaです。 最近のLIFULLでは、自社が所有するデータの活用を目的に数多くの取り組みが実施されています。 今回はデータの発見可能性(Data Discovery)を向上させるための基盤構築を目指して実施したPoC(Proof of Concept)とそのOSSの選定について紹介します。 当初は「自社データの再利用性を高めたい」という広い意味を持った要件で開始したプロジェクトでしたが、 Data Discoveryがボトルネックになっていると判明し、解決策としての基盤構築に向けてPoCを実施することとなりました。 現場の課題調査からOSSの選定と試験運用まで一連のトピックをまとめていきます。 初期フェーズ: 現場調査と課題抽出 FAIR原則 データ利用の現場から抽出した課題 ボトルネックの特定と解決策の選定 PoCの開始 OSSの選定 Datahubとは Metadata ingestion PoCの評価指標 PoCの結果 Data Discovery Platform導入への期待 Data Discovery Platformはあくまでも必要条件 これからの展開 求人情報 初期フェーズ: 現場調査と課題抽出 昨年秋、「自社データの再利用性を高めたい」という目的とともにプロジェクトがスタートしました。 筆者をはじめ、プロジェクトメンバーにはデータエンジニア的なバックグラウンドを持つ人はおらず、まずは現場調査を通じ探索的に解決策を導出することとなりました。 ディスカッションや調査の際には記録を手続き的なドキュメントとして残すのではなく、 IBIS(Issue Based Information System) という手法と オンラインホワイトボードのMiroを活用することで、議事録作成をDialogue mapping化しDAGとして残しました。 miro.com 現場調査のフェーズは2ヵ月にわたり、なおかつ多くのステークホルダーに対して実施したため、 過去のやりとりと現在の関心事との関連を視覚的に把握しやすい形式で議論を行うことで議論の発散と収束を視覚化できたのは効果的でした。 MiroでのDialogue Mapping: 議論の現在地や目的を可視化 FAIR原則 データの再利用性を高めたいという観点でスタートしたものの、この時点ではデータエンジニアリングの観点が不足していたこともあり最終的な成果の定義に難儀してしまいました。 民間企業だけではなくアカデミックにおいてもデータ活用の問題は存在していると考えリサーチを行ったところ、データ共有の原則であるFAIR原則を発見しました。 biosciencedbc.jp FAIR原則を知り、これまでに自分たちが焦点を当てていたデータの再利用性とは、相互に関連する4つの原則のうち1つに関連するものでしかないと認識しました。 これ以降は、データ活用にまつわる複数の問題を念頭に置きつつ、ディスカッションや後続となるインタビュー調査を実施しました。 データ利用の現場から抽出した課題 データ分析者やAIエンジニア、プロダクト開発を行うアプリケーションエンジニアや企画職などデータに関連する職種の方々に協力いただきインタビュー調査を行いました。 その結果を要約すると、下記のような課題が得られました。 データの格納場所やデータの情報(メタデータ)あるいはデータの存在自体が不明、または特定のチームや個人のナレッジとして埋没している データの派生系が多く、利用価値のあるデータ・起源となるデータなどユニークなデータが発見できない 発見したデータが更新されているのか、誰が管理しているのかが不明で利用開始するまでに問い合わせが発生する いわゆるデータのサイロ化に起因する問題が目につきます。 これらインタビュー調査の結果を踏まえ、あるべき解決策は静的なドキュメンテーションや属人的な助け合いの仕組みの強化ではなく、 「自動で最新の状態に追従可能で、統一された形式に沿って管理・運用されたデータが入手可能な基盤」であると結論づけました。 ボトルネックの特定と解決策の選定 ここまでの調査は現場の開発者・分析者へのインタビューなどを通じてボトムアップ的に行われてきました。 調査で得られた生の課題の集まりに対して優先的に取り組むべき課題と解決策を選ぶために、書籍"The Self-Service Roadmap"にて導入されていた考え方を取り入れました。 The Self-Service Roadmapにおいては、データ活用の主たる指標とも言える"Time to insight"(知見を得るまでの時間)を "Discover", "Prep", "Build", "Operationalize"の4つのフェーズに分割することが提唱されています。 自分たちの調査によって集められた課題は、Discoverのフェーズ、特にデータセットあるいはそのメタデータの検索の課題に該当すると判断しました。 つまり"Data Discovery"こそが開発・分析現場のボトルネックとなっており、優先的に取り組むべき課題であると判明したのです。 PoCの開始 The Self-Service Roadmapにおいてself-service data platformが立ち行かなくなるアンチパターンとして、 問題を理解しないまま技術にだけ投資してしまうことと、一度に多くの問題を解こうとすることが挙げられています。 アンチパターンに陥らないためにも今回のプロジェクトではData Discoveryに焦点を当て、 これを持続的に解決可能な基盤を導入すべく、技術選定とそのPoC(Proof of Concept)から始めていきます。 OSSの選定 近年、海外を中心としてModern Data Stackという言葉とともに最新のデータ基盤周辺技術に注目が集まっています。 日本でも注目されているdbtのブログにて、Modern Data Stackの来歴とともに展望を読み取ることができます。 blog.getdbt.com Data Discoveryの分野だけでなく、Modern Data Stackを構成する技術は多岐に渡り、 解決したい問題領域や抱えるデータセットの量、事業フェーズなどの制約条件に沿って適切な技術を選定する必要があります。 今回の場合は「 "多様なデータソース" に対して "Data Discovery" を向上させるための "基盤(Platform)" の "PoC" を行いたい」という制約に基づき、 LinkedInとAcryl DataによるOSSである "Datahub" を選びました。 datahubproject.io Data Discoveryの向上を目指せるMetadata Platform系のOSSにはAmundsenやApache Atlas、Open Metadataなどがありますが、 PoC期間内での構築しやすさ・運用可能性、利用者(社内開発者・分析者)向けのUXや機能性を考慮した結果、Datahubを選定しました。 OSSの採用以外の選択肢には、社内で利用しているGoogle CloudのData Catalogを充実させるという選択肢もありましたが、 LIFULLのデータセットはAWSやGCPなど複数のインフラで稼働しているため、中立的なDatahubを試用することとなりました。 Datahubとは 公式ドキュメントでは下記のように説明されており、多様で複雑なデータエコシステムにおけるMetadata PlatformとしてData Discovery, Data Observability, Federated Governanceを実現させることが特徴として挙げられています。 Data ecosystems are diverse — too diverse. DataHub's extensible metadata platform enables data discovery, data observability and federated governance that helps you tame this complexity. Data Discoveryという点ではElastic Searchによるメタデータの検索やWebブラウザのようなUI、Datahub独自のシンプルで拡張性のあるメタデータスキーマによって実現されています。 このようにしてプロダクト開発者や分析者などデータ利用者にとってはシンプルな機能を提供しつつも、 Push型のデータ更新アーキテクチャによる最新のデータへの追従やData Lineageの取得によるObservabilityの確保と、 AWSのIAMのようなRBACによりFederated Governanceの実現を目指すことができ、継続的な運用に耐えうるカタログスペックを有しています。 また、DatahubではQuick Start用のDocker Imageやhelm chartsも用意されており、ローカル環境での試用やPoCが容易に実現可能です。 今回のPoC期間中でもhelm chartsを利用し、LIFULLの検証用Kubernetes環境上に1日程度でデプロイできました。 デプロイしたDatahubのトップ画面 Metadata ingestion RDB(MySQL,Postgres,etc),DWH(BigQuery,Snowflake,etc),BI(Tableau, Looker)など多岐にわたるデータソースから、カラムの物理名やスキーマ情報などのmetadataのingestionが可能です。 ingestされたmetadataに対してはUIやAPI経由で編集することが可能で、データに関するナレッジなどTeam Metadataも集約することが実現できます。 PoC期間中ではFederated Governanceの観点を検証しきれませんでしたが、基盤の管理者がingestionを中央集権的に管理・実行するのではなく データソースに近いプロダクト開発エンジニアやデータソース運用者がDatahub上のmetadataのOwnerとなることで、 自分達のTeam Metadataは自分達で管理しつつ横断的なプラットフォームで第三者が入手・検索可能にし、self-serviceなデータ基盤を実現できるのではないかと考えています。 例えば、DDDにおけるユビキタス言語を制定した後はDatahub上に載せて、チーム内外の認識の齟齬を減らせることが期待できます。 Metadata ingestionの実行後イメージ: タグやTermsからmetadataが検索できる PoCの評価指標 Datahubによって実現されるData Discovery Platformが本当に現場のData Discoveryを実現するかを評価することに加え、 大元の課題であったデータ活用の促進を実現できるかを検証するために、いくつか設問を用意しData Discovery Platformの利用者にアンケートをお願いしました。 例えば以下の2つです。 設問1. Datahubで構築したData Discovery Platformは、欲しいデータを発見するまでの時間を短縮するか? 設問2. Datahubで構築したData Discovery Platformは、データを発見してからデータを活用開始するまでの時間を短縮するか? The Self-Service Data RoadmapにおけるDiscoverにおけるメトリクス:"Time to find"への貢献度を設問1で収集し、 Discoverというmilestoneを含めたデータ活用開始までの時間短縮への貢献度を設問2として収集しています。 別途、性能評価やマシンリソースの消費度合い、費用など非機能的な要件の評価も行います。 PoCの結果 社内のデータ基盤エンジニア・データ分析者・アプリケーション開発者・技術マネージャーなどにData Discovery Platformは利用され、アンケートを実施いただけました。 その結果、設問1については9割が好意的な回答で、設問2については好意的な回答が5割、否定的orわからないという回答が5割でした。 Data Discovery Platform導入への期待 設問1で好意的な回答が大半を占めたことから、Data Discovery Platformを意図して構築されたプラットフォームが 現場のData Discovery向上に寄与することが立証できたと言えます。 データ発見という観点で既存の社内ツールや技術基盤に対する競合優位性があったことは確かですが、 今後全社的に運用する場合、ingestするデータセットが増加し玉石混合なmetadataを持ってしまうリスクもあるので注意は必要です。 Data Discovery Platformはあくまでも必要条件 一方、設問2では半数が「いいえ」あるいは「わからない」など好意的とは言えない回答であったことから、 Data Discovery Platformの実現はあくまでデータ活用のための必要条件であり、十分にデータを活用するには他にも解決すべき課題があると考えています。 ただし好意的な回答が少なかった外部要因として、PoC期間に十分なmetadataを用意できなかったという要因もあるので、 ingest自体を効率化するような仕組みを検証していきたいと考えています。 これからの展開 今回のPoCを経てData Discovery Platformの導入が開発現場・分析現場のデータ活用を促進する一歩となることを立証できました。 ただ、あくまでPoCが成功したに過ぎず本格的な稼働に向けては運用面での課題も存在します。 魅力的な技術や目新しい技術の多いModern Data Stackですが、"right tool for the right job"を原則としてこれからの基盤構築を行っていきたいところです。 求人情報 LIFULLではエンジニアの募集をしており、カジュアル面談も実施中です。 募集中の職種など詳細は下記をご覧ください。 hrmos.co hrmos.co
プロダクトエンジニアリング部の佐野です。 LIFULLでは2020年3月頃からリモートワークが主体の働き方になっています。 出社して働いていた頃と比較すると、同じグループのメンバーとは日々業務を進める上でコミュニケーションは取っているものの、他部署のメンバーとのコミュニケーションが少なくなった...という話もちらほらと。 偶発的なコミュニケーションも必要だ!とのことで社内サークル活動を推奨する制度が出来上がりました。 2022年1月末でサークルは74。多い! どこかのサークルに入っている人は747人。めっちゃ多い!! 上記の通り社内サークルは沢山存在していますが、その中でも今回は、私が主催者となって活動している映画サークルについてご紹介します。 映画サークルについて 映画サークルといっても、敷居は限りなく低く(ここ重要)、私の主催しているサークルは基本月1回の活動です(多いと疲れてしまうので)。 リモートワークが主体の働き方に合わせて、活動もオンラインで行っています。 基本メンバーは7名で活動しており、職種・部署はバラバラです。 このサークルで初めて知り合った方が多数で、対面で会ったことのないメンバーも中にはいます。 普段だと、同じ部署や同じ職種の人と知り合うことがほとんどなので、色々な職種・部署のメンバーと気軽にコミュニケーションが取れるのはサークル活動の強みだと感じています。 サークルで観る作品は、Netflixの中からメンバーが面白いと思ったものを観る形をとっています。 Netflixはたくさん作品があるので飽きません。 「映画」とサークル名についていますが、実際には映画に限らずドキュメンタリーなど色々な作品を観ています。 サークル開催 開催日が決まったらオンラインで集合して、速攻番組を観る…というせっかちスタイルではなく、大体の時間帯にオンラインで集合します。 業務ではないのでここはゆるく始めます。 作品を観る前後30分くらいは雑談タイムを設けていまして、その時にみんなで観る作品を雑談しながら決める形にしています。 こんなものを観たい、どんな番組が面白かった、スタートレックが好きだ、等の雑談を和やかにしています。 普段自分では観ない作品も観れますし、みんなの趣味趣向が知れて大変面白いです。 作品との偶発的な出会いが期待できます。 ちなみに作品を見るときは、「再生しまーす」で同タイミングで再生ボタンを押すようにして、各人の環境で作品を観ています。 また、サークル活動にはサークル活動費として会社から補助が出ます。 そのためサークル開催日には予算内で思い思いの飲食物を購入して、サークルでの時間を楽しんでいます。 1月の活動日には、エンジニアの青木さんも飛び入りで参加して和やかに過ごしました。 そのときは、「ミッドナイトアジア」というドキュメンタリーを観ました。 サークルに飛び入り参加してみての感想 今回飛び入り参加させていただいた青木です。 リモートワーク中心となる前は社内ですれ違えば会話していた面々と、 本当に久しぶりにお話しすることができました。 社員数が増えても、業務だけだと接点って増えるわけではないんだな、こういう機会があるのって大事なんだな、と実感しました。 「ミッドナイトアジア」は、まぁ自分では手を伸ばさない作品でサークルならではのチョイスで楽しめました。 まとめ 今回は私が主催する映画サークルについての紹介でしたが、先述した通り多種多様なサークルが存在しています。 ゲームや数学、エンジニアが他職種の方にプログラムを教えるサークルもあります。 サークル活動を通して普段の業務で関わることのない他部署の知り合いも作れますし、コミュニケーションも取りやすくなると思います。 自分で主催するもよし、サークルに入るもよし。 リモートワーク主体の働き方になりましたが、今回紹介したサークル活動以外にもコミュニケーションを取りやすくするための取り組みが盛んに行われています。 1日誰とも会話していない...なんてことも解決するかも!? LIFULLでは一緒に働く仲間を募集しております。 もし興味を持っていただけたら、募集求人やカジュアル面談のページもご覧ください。 hrmos.co hrmos.co
こんにちは、エンジニアの加藤です。LIFULL HOME'Sの注文住宅領域を支えるエンジニアチームのマネジメントを担当しています。 皆さん、技術的負債の解消やリファクタリングなどどのように行っていますか? 長年の開発業務により蓄積された技術的負債は、開発生産性を低下させる要因として多くの方の頭を悩ませているかと思います。 私の所属する部署では開発生産性の向上をミッションとして掲げており、技術的負債の解消はミッションを達成するための重要な要素となっています。 そのような中、私たちのチームでは「リファクタDays」という取り組みを通じ、約半年間技術的負債の解消を含むシステム改善に努めてきたので、今回はそちらについて紹介したいと思います。 技術的負債の解消を行う上での課題 開発生産性を上げるため技術的負債の解消が重要である一方、LIFULL HOME'S 注文住宅の機能開発を担当するエンジニアであるため、常にプロジェクトに配置されておりサービス開発を行う必要があります。 そのため、負債解消とサービス開発を両立させるためには、限られた時間の中でバランスよく実行することが重要となります。 昨期以前は組織で技術的負債の解消計画を立てつつ、実行は担当するプロジェクトの状況を加味しつつ各メンバーの裁量に任せておりました。 しかし、ときにはプロジェクトを優先して負債解消への取り組みを劣後せざるを得ない状況もあり、計画に対し思うように進捗させるのが難しい場面もありました。 上記の結果を踏まえ、一番の課題は負債解消に取り組む時間を十分に確保できないことであると捉え、仕組み化により課題解決を図る方法を検討しました。 リファクタDaysという取り組み プロジェクトと両立させるための仕組み 前述の通り、サービスを成長させるためプロジェクトを遂行することも重要な職務であるため、プロジェクトと両立させることは不可欠です。 そのため、どのように負債解消に取り組む時間を確保するかが重要となります。 プロジェクトを計画する上で、不確定な要素はなるべく排除しておきたいものです。 エンジニアがプロジェクト外の開発をいつどれだけ行うか不明瞭である状態では計画も立てづらく、プロジェクトの遂行にも影響を及ぼします。 これらの影響を抑えるよう、負債解消への取り組みは一定周期ごと一定期間実施することとし、あらかじめ半期分時間を確保することとしました。 また、負債解消に取り組む上でも効率化は重要です。 タスクにより粒度や規模は異なるため、1日で完遂するものもあれば数日に及ぶものもあります。 開発途中で手を止めることは開発効率を低下させる要因となるため、連続した数日間を集中して取り組むことができる期間として確保することとしました。 これらをもとに以下のルールを定め、この期間を「リファクタDays」と名付けました。 3週毎3日間利用し実施 実施日は水、木、金の連続した3日間 開始日の朝11時にキックオフを実施し、期間内で実施するタスクを各自ピックアップする 原則この期間はプロジェクトに纏わる活動(開発・MTGなど)は行わない 原則スケジュールの変更は行わない(休暇・祝日が被る場合も) 目的は開発生産性を上げること 開発生産性を上げるためには技術的負債の解消以外にも様々なアプローチがあります。 例えば、運用業務の効率化やリファクタリングによりソースコードの保守性を高めること、システムコストを削減することで人的リソースのコストに回すなど。 リファクタDaysの目的は開発生産性を向上させることであるため、技術的負債の解消に限定せず上記を含めたシステム改善全般を取り組むべきものとして位置付けています。 周囲の協力を得ることが重要 これらの取り組みを考えても周囲の関係者の理解と協力を得ることなしに実行はできません。 特にプロジェクトをともに遂行するプロダクトマネージャーや企画職のメンバーの協力は不可欠です。 リファクタDaysの目的や効果を伝えるだけでなく、ルールのすり合わせや実施後のヒアリング、実施内容の見える化など様々な取り組みを行いました。 これらにより理解を得られ快く協力してもらえたことが、リファクタDaysを遂行するための大きな後押しとなっています。 リファクタDaysでの効果 現在約半年間リファクタDaysを実施してきましたが、時間確保の課題は解消され、プロジェクトと両立しつつ一定のペースでシステム改善を積み上げることができています。 システム改善数の推移 また、LIFULL HOME'S 注文住宅へのリリース数も昨期半年間と比較して一月あたり平均約1.5倍に増加し、高い水準で安定していることから開発生産性向上への効果も感じられます。 LIFULL HOME'S 注文住宅 月別リリース数 まとめ 技術的負債の解消や開発生産性向上は多くの組織で抱える課題であり、重要な取り組みの一つであると思います。 今回紹介させていただいたリファクタDaysの事例が、皆さんの課題解決に少しでもお役に立てたら嬉しいです。 また最後にLIFULLでは一緒に働く仲間も募集しているので、よろしければこちらも併せてご覧ください。 hrmos.co hrmos.co
プロダクトエンジニアリング部の二宮です。 LIFULL では「エンジニアいつでも相談」という名前で、 GitHub Discussions を使った社内向けの Q&A フォーラムを有志で運営しています 🙌 このフォーラムは「あるシステムについて誰か詳しい人に相談したい」とか「設計についてチーム外にも相談したい」とか、エンジニアリングで困ったことをなんでも聞ける窓口になることを目指しています。最近ではアーキテクトチームや QA チームなどの公式の窓口としても利用でき、質問の内容に応じて適切な部署や人がアサインされる体制も整い始めました。 従来は相談相手を見つけるのにも苦労したり、そもそも窓口が用意されていなかったりすることもあり、社内アンケート調査等でよく情報共有が課題に挙がっていました。そこで、社内向けの Q&A フォーラムを用意することで、その問題の一部を解消しつつあります。 エンジニアいつでも相談の利用方法 まず利用方法を紹介します。エンジニアいつでも相談の GitHub リポジトリが用意されていて、その Discussions にフォーラムが用意されています。 ここで過去の質問を検索・起票できます。詳しい案内はトップのハウスルールが掲載されており、初めての人でもあまり迷わずに操作できると思います。ハウスルールには次のような内容が記載されています。 GitHub Discussion 上で過去の質問の検索を行う 解決した場合、Vote をする 既存の質問で解決しなかった場合、「Q&A🙏 」カテゴリで起票する フォーラムに質問が投稿されると、質問の回答者となるチームに通知されます。GitHub Actions によって、タイトルや内容によって各チームにメンションを付けたり、Slack 通知を飛ばす機能が実装されています。もちろん、それ以外の社員も回答できます。 質問者は、問題が解決したら、回答の中からベストアンサー(Mark as answer)を選んでクローズします。 このように、一般的に想像するフォーラムの機能はそろっており、通知の自動化なども必要に応じてすぐに実装できます。 GitHub Discussions を利用するメリット 過去のツールの変遷 実は、エンジニアいつでも相談は、発足当初から以下のような思いは一貫しています。しかし、ツール面ではいくつかのものを渡り歩いてきました。 社内のドメイン知識や社内ルールが分からず悩んでほしくない 将来的にエンジニアの共助・評価・成長につなげたい 具体的には以下のような変遷がありました。 Google グループをフォーラムとして利用する フォーラムを使わずに有志でチャット上で質問・回答をする GitHub Discussions でストック化を促進 まず、Google グループではなかなか質問自体が集まりませんでした。これは、普段利用しているツールではなく、業務の導線にないからだったと思っています。 (ただし、Google グループは、 GitHub アカウントを持っていない社員からの質問も受け付けられる点でメリットがあると思います。発足当初は職種からエンジニアへの質問も想定していて、現在はそこのコミットメントは諦めた形になります) また今から考えると、アサインや通知の自動化がやりづらく、この状態でスケールさせることも難しかったと思います。 次に「普段利用しているサービス上なら質問・回答がやりやすい」という仮説のもと、専用のチャットルームを用意して、有志でそこで質問・回答するようにしました。これはコンスタントに質問が行われるようにはなったものの、「あれ?どれが回答済みなんだっけ?」というやや混乱した状態にもなっていました。またせっかく回答しても、その場限りでナレッジにならないという歯がゆさもありました。 Discussions を利用するメリット それらと比較して、Discussions を利用することについて、以下のメリットを感じています。 業務で普段利用しているサービスであること Q&A が直接ナレッジとして蓄積できること GitHub Actions で自動化ができ、Pull Request で変更を受け入れられること 内容がオープンであること 1, 2 は、ほかのツールとの比較で自然にわかると思います。3 について補足すると、たとえば「GitHub Actions によって各チームに通知を飛ばす」機能は、Discussions 起票時に以下のようなシェルスクリプトを起動することで実現しています。 if [[ "$CATEGORY" = "Q&A" ]]; then ( regexp="([kK]eel|KEEL|[dD]ocker|[kK]ubernetes|ECS|EKS|[pP]rometheus|[gG]rafana|[vV]irtual[[:space:]]?[sS]ervice|[dD]ev[oO]ps|[vV]1[cC]luster[bB]ootstrap|[sS]pinnaker|[sS]elf([-]|[[:space:]])?[hH]osted([-]|[[:space:]])?[rR]unner|J-?SOX)" if [[ "$TITLE" =~ $regexp ]] || [[ "$BODY" =~ $regexp ]]; then addDiscussionComment "$ID" "KEEL: ${KEEL_TEAM}" fi ) ( regexp="([aA]rchitect|アーキ|設計相談|[bB]ff|BFF|[nN]c[aA]pp|[nN]ext[cC]ore|lhv5|[pP]roject[xX]|PJX|pjx|[fF]ront|ベストプラクティス)" if [[ "$TITLE" =~ $regexp ]] || [[ "$BODY" =~ $regexp ]]; then addDiscussionComment "$ID" "Architect: ${ARCHITECT_TEAM}" fi ) # 以下略 この通知スクリプトに各チームが通知内容を設定するようにしています。チーム側からこれらの修正を Pull Request として送ってもらうことで、運営チームはあまり負荷を感じることなくメンテナンスできます。 また、一度の投稿で、複数のチームに相談できるというメリットもあります。たとえば「何かのプログラムの問題について QA とアーキテクトに相談したい」というとき、以前はそれぞれの jira で起票する必要があったのですが、今では統一されたフォーラム上で一度に相談できます。 今後の展望とまとめ このように、GitHub Discussions を利用することで、あまり負担なく便利な社内フォーラムが用意できます。 当初は何人かで集まって「誰に質問すればよいか分からんから俺らで作ろうぜ」と勝手にやっていただけなのですが、投稿されたほとんどの質問は何らかの形で解決でき、上記のような便利な状態を実現できました。これは、運営メンバー外で質問をチェックや運営へのフィードバックをしてくれている社員も多くいてくれたおかげだと思っています。 また、従来はチーム内で閉じていた技術的な議論がチーム外も巻き込んだ形で行われているなど、想定していた以外のところでもうれしい事例も生まれています。引き続きよりよい開発文化のために貢献できればうれしいです。 最後に、LIFULL では一緒に働くエンジニアの募集をしています。この記事だけでは普段の開発の様子は分からないと思いますが、ぜひほかの記事も読んで興味を持っていただけたらうれしいです。カジュアル面談もあります。 hrmos.co hrmos.co
プロダクトエンジニアリング3Uの二宮です。 LIFULLにはチームビルディングの制度があり、半年〜1年に一度、同じチームのメンバーで半日〜1日単位で交流の機会を設けています。内容も各部署内で決めることができ、多種多様な企画が行われています。クリエイターズブログでも、過去に「 エンジニアのためのチームビルディング!コードで語れ 頭を使って 謎を解け 」や「 独自企画「浅草BINGO鬼ごっこ」でチームビルディングしてみた! 」などが紹介されています。 LIFULLでは新型コロナウイルスの流行をきっかけにリモートワーク主体の働き方になっており、チームビルディングもリモートで行うようになり、自分たちのチームでもいろいろ苦慮しながら実施しました。おそらく他の会社の方もそうなのではないでしょうか? そこで、この記事では私たちのチームではどう企画して、どう実施・今後に活かしていこうと考えたかをまとめました。ぜひ一つの知見として役立てて頂けると嬉しいです🙌 チームの現状と目的 我々のユニットでは、その中にあるグループ(下位チーム)が別々のプロダクトを担当していて、普段の業務での関わりは多くありません。ただ、現在は極端にチーム外とのコミュニケーションが薄くなり、サポートも得られづらい状態なのでなんとかしたいと考えていました。特徴的なエピソードとして、ある新卒に「直属の上司とは実際に会ったことがあるが、2つ上の上司とはネット越しでしか会話したことがない」とか「社内でもグループ外の知り合いがほとんどいない」と言われ、コミュニケーションのやり方や密度が以前と大きく違うことにショックを受けたことがあります。 9月にもチームビルディングを実施したのですが、その時は都合によって限られた時間で自己紹介と簡単なゲームをすることしかできませんでした。また、それからメンバーの入れ替わりもあって、はじめましての人も何人かいました。 ユニット全体では11人在籍していて、各グループは次のようなプロダクトを見ています。 同一プロダクトを見ているチームほど密に連携する必要はないが、各々小さなプロダクトを見ているので悩み事の相談などはできるはずだと考え、以下のゴールと方向性に決めました。 ゴール: 普段からグループ間で相談(実装面、スキル面など)ができるような信頼関係が作られている 方向性: 相談や意見を交わしながら「一緒に共通のゴールを目指す」ようなアクティビティを実施する 実施準備 結果として、1日を使って、次のようなアクティビティを実施することになりました。 アイスブレイク: 共通点探しゲーム メインコンテンツ: オンラインリアル脱出ゲーム×サマーウォーズ「AIによる世界支配からの脱出」 オンライン懇親会 まずアイスブレイクとして自己紹介を兼ねたゲームを行い、次にいくつかのチームに分かれて、「一緒に共通のゴールを目指す」ことのできるオンラインリアル脱出ゲームを実施しました。 「AIによる世界支配からの脱出」 を選んだのは、他のチームから「以前やってみてプログラマー向けな内容で面白かった」という評判を聞いたことが一番の要因です。また、運営チームで他のゲームやコンテンツもできるだけ探して検討したのですが、オンラインで11人が一緒にできるものが見つからなったという理由もあります。 また、懇親会ではフードデリバリーサービスの nonpi を利用しました。今までは、各々が別々に用意するやり方だったのですが、「オフラインの懇親会と同じく同じメニューのものを食べればチームの一体感にもつながるんじゃないか」と「食事の準備をなくして気楽に楽しめるようにしよう」ということを期待して試してみました。 当日の様子 ①アイスブレイク アイスブレイクで行った「共通点探しゲーム」は次のようなものです。『 リモートワークでの相互理解を深める(共通点探しゲーム) 』という記事から引用させていただきます。 「共通点探しゲーム」とは、その名の通り、制限時間内に対話を通してグループの仲間と共通点を見つけるゲームです。またコミュニケーション能力で重要な共通点を探す力を養うことができるグループワークでもあります。ゲームの目的は共通点を知ることではなく、内容を伝え合うことで、一体感を感じて相手の特徴をより知ることを目的としています。結果としてチームの協力(コラボレーション)を生まれやすくし、相互に助け合える環境を築くことを目標とした、チームビルディングのための一つの手段でもあります。 今回は「脱出ゲームを行うチームに分かれ、20分で『意外な共通点』を見つけよう」という形式で実施しました。 とあるチームは、途中で読書が共通してそうだと気づき、そこから本の共通点を探したところ全員がミステリ小説が好きということがわかり、チーム内でミステリ小説の話をしていたそうです。 運営側は「せっかく自己紹介をするなら、ゲームにしたほうが楽しくない?」という軽い理由だったのですが、後述するように、後日実施したアンケートでは予想以上に評判がよく驚きました。 ②メインコンテンツ: オンラインリアル脱出ゲーム メインコンテンツのオンラインリアル脱出ゲームは、うまく裏をついて問題を解いていくような内容で、前評判の通りたしかにエンジニア向けだったように思います。 ただ、どこまで解答をメンバー間で共有していいか分からなくて困惑したチームがあったり、完答するまでの時間がチームごとにバラツキが大きかったりして、運営側としてはもう少しうまくファシリテーションできたんじゃないかと反省点はありました。 ③オンライン懇親会 オンライン懇親会では、nonpiのフードとお酒を楽しみながら、 ボードゲームアリーナ で遊びました。自分たちは他のオンライン懇親会でもボードゲームアリーナを利用していて、特に「 イラストリー 」が恒例になりつつあります。これはイラストにこじつけて言葉を考える"しりとり"で、「よくこれ思いついたね」とか「いやこれは無理やりでしょ」とか会話も盛り上がるゲームです。 結果・振り返り 最後に、次回の実施内容やチームのあり方に活かせることが無いか、後日アンケートを取って振り返りを行いました。 メインコンテンツでは、楽しかったという意見は多かったものの、次のような課題も挙げられ「一緒に共通のゴールを目指す」というところから外れてしまっていた部分もあったようです。 解くことに集中して無言になってしまった どこまで解答をやり取りしていいか分からなかった 一部メンバーが解きまくって後からついていくことが多かった この辺りは運営に課題があったように思います。次回は次のように対処しようと考えています。 「積極的に話し合ってほしい」みたいに期待することを明確に案内する 他の脱出ゲームの中には人の案内役がいるものや、「AさんとBさんが別々の問題を解かなければ脱出できない」というコンテンツもある。それらを検討してもいいかも また、運営側の予想からは外れ、「共通点探しゲーム」の評判が良かったことです。「コミュニケーションが取れて良かった」という意見が多くありました。 おそらくリモート以前の時代より、我々が思っていた以上に「普段の雑談」とか「同じ開発チーム外の会話の機会」が減っていて、特に新規メンバーは他の人の人となりを知る機会が減っているからなんじゃないかと推測しています。こういうような「ゲームをしながら楽しくお互いを知る」のは他のチームでも需要が大きいのかもしれません。 フードデリバリーはやはり準備の手間が省ける点や、「どのメニュー選んだ?」というような話題で話が生まれる点が喜ばれていました。実は運営メンバーが共通している全社のイベントでもフードデリバリーを利用されるようです。ただ、飲み会向けのメニューが多いので、事情があって飲めない人はメニュー選びに困っていたようでした。 また懇親会では「同時に1人しかしゃべれないので会話に困る」という回答が複数あり、もっと積極的にブレイクアウトセッションを利用し、話題のためにコンテンツを用意して…というように、オフラインより事前の準備が必要な印象があります。また、他の社内イベントで使われていた oVice や Gather などのツールも検討してもいいのかもしれません。 このチームの個別の話でいうと、総じて「共通のゴールを目指そう」というよりは、まずは相互理解を目指すような内容がよかったんじゃないかと思います。例えば、他のチームで行われていた中では「 カラーバリューカード 」や「 アンガーマネジメントゲーム 」などがそういった選択肢になりそうだと思っています。 まとめ 他のチームでも共通するような知見をまとめると、次のようなものがあるかなと思います。 「共通点探しゲーム」のように、楽しく自己開示するゲームは、リモート時代のコミュニケーション不足の補完にいいのかもしれない コミュニケーションがスムーズに行われるように準備が大事だ。特にファシリテーション方法や部屋分けはもっと工夫の余地がありそうだ フードデリバリーは各々の準備の手間が省けるのが嬉しい また、今の所はユニット内でチャットでの会話が多少は生まれてきて、チームビルディングがそのきっかけにはなっていると思うものの、「普段からグループ間で相談(実装面、スキル面など)ができるような信頼関係が作られている」というゴールを見返すとまだまだな点も多いと感じています。チームビルディング以外でも、普段からどうコミュニケーションを取ればいいのか試行錯誤が必要そうです。 そして、企画時からオンラインでの交流の難しさは感じていたのですが、企画メンバー以外からも「やっぱりオフラインのほうが仲良くなれそう。今はムリだが、コロナが収束したら、せめてチームビルディングのときは集まりたい」という意見も出ました。 オンライン主体のチームのあり方は難しいですが、試行錯誤しながらがんばっていきましょう🙌 最後になりますが、LIFULLでは一緒に働く仲間を募集しております。もし興味を持っていただけたら、募集求人やカジュアル面談のページもご覧ください。 hrmos.co hrmos.co
エンジニアの島です。AI戦略室でバックエンドシステムの開発をしています。 本記事ではPrometheusを利用して、独自のメトリクスを計測することで監視を効率よく行えることを紹介します。 背景 チームで作っているもの 社内共通基盤の活用 効果的な監視で得られるもの 問題の予兆に気付けるようになる 問題の原因特定につながる 時系列での傾向を把握できる Prometheusとは 思想 メトリクスの公開 custom metricsを追加しよう Prometheusで監視しよう custom metricsで計測すると嬉しいもの 外部IOに関して 内部状態に関して 外部起因ではないアプリケーションのエラーの数 有効データのうち、モデルが値を返せている割合 機械学習モデルのスコア(histogramを利用) そのほか 終わりに 最後に宣伝 背景 チームで作っているもの LIFULLのAIチームでは、いくつかの機械学習プロダクトを本番運用しています。 2022年2月にAIホームズくんᴮᴱᵀᴬをリリースしました!(SPサイトのみです) https://www.homes.co.jp/ai-homeskun/ また、3D間取りも2021年にリリースしています。 https://www.homes.co.jp/3dmadori/ その他には、LIFULL HOME'Sのレコメンド機能でも機械学習を活用しています。 https://www.homes.co.jp/chintai/tokyo/list/ それ以外の開発プロジェクトもいくつか進行中です! 社内共通基盤の活用 これらのプロダクトは社内共通基盤チームが開発したKEELという、 In-house PaaSとして各種機能を提供するKubernetesベースのアプリケーション実行基盤で動いています。 www.lifull.blog KEELチームが開発しているコードジェネレータ(keelctl)によって、Production Readyなアラートが自動的に設定されます。 例えば下記が監視され、しきい値を検知すると通知されます。 サクセスレート低下 レスポンスタイム CPU・メモリ使用量 www.lifull.blog success rateやresponse timeなどの基本的な指標は、ダッシュボードで閲覧できます。また、それらの通知も生成されるため、基本的な指標の悪化に気付けます。 そしてKEELチームが運用するPrometheus,AlertManager,Grafanaといったソフトウェアからアラートの受け取り、収集したメトリクスを確認できます。 www.lifull.blog アプリケーション開発者はこの仕組みを活用しながら、 DevOpsの考え方に従い、自分たちでアプリケーション固有のエラー対応や監視を行うことが出来ます。 開発したプロダクトが増えていくにつれ、運用コストも増えていくため、自動化できるところは自動化したいモチベーションがあります。 効果的な監視で得られるもの 問題の予兆に気付けるようになる 監視の恩恵としてここが一番大きいです。 本番サーバが突然落ちて、それにより割り込み対応や残業を余儀なくされるというのは、開発者体験として最悪ですよね。 バグの早期発見により対応コストが劇的に下がるのと同様、障害対応も早期解決・顕在化前の解決が最も効率的です。 適切に監視をすることで、サービス利用者への価値提供を継続できるだけでなく、あなたや同僚の時間を守る事にもつながります。 問題の原因特定につながる custom metricsを作成することの恩恵はこちらになります。 問題が発生したときに、手がかりがないと調査から始めないといけません。 custom metricsが手がかりとなれば、問題を迅速に切り分けることができます。 仮に問題がなかったとしても、「問題はそこではない」という貴重な情報が得られます。 結果的に初動が早くなり、問題を迅速に解決できるでしょう。 時系列での傾向を把握できる こちらはメトリクス値を蓄積することの恩恵になります。 通知を設定しなかったとしても、蓄積したデータを調べることで、システムの長期的な傾向を知ることができます。 リリースしてから、サーバのメモリは増加していないか 依存サービスのタイムアウトは一時的なのか周期的なのか catchして握りつぶしている例外の数は規定内に収まっているか 機械学習スコアの傾向に変わりはないか さまざまな情報を知ることで、サービス開発・運用に役立てることができます。 Prometheusとは 一言でいうとシステム状態の収集・可視化と監視ができるOSSです。 prometheus.io 元はCNCF(Cloud Native Computing Foundation)プロジェクトとして始まりました。 今ではAWSマネージドサービスも出ており、監視標準と言って良いでしょう。 aws.amazon.com 思想 Zen of Prometheus が分かりやすいので紹介します。(非公式サイトですが) https://the-zen-of-prometheus.netlify.app/ 3行でまとめると、 メトリクス取得は安価に行えるので、どんどん取得しよう。 ログを取ったり、可視化をしたりするのであれば、そのメトリクスを計測してアラートさせるように作っておこう。 やっかいな問題へと深刻化する前に、すぐ気付いて早期対処しよう。 といったところでしょうか メトリクスの公開 Prometheus公式にて、いくつかのプログラミング言語用のライブラリがサポートされています。 こちらを利用するだけで、簡単に実装できます。 github.com PythonのFastAPIフレームワークであれば、例えば以下のように記載するだけでデフォルトのメトリクスを公開できます。 import prometheus_client ... @app.get('/my_prometheus_metrics') def prometheus_metrics(): return fastapi.responses.PlainTextResponse( prometheus_client.generate_latest() ) その上で設定したパス /my_prometheus_metrics にアクセスすると、計測しているメトリクスを次のようなプレーンテキストで取得できます。 # HELP process_start_time_seconds Start time of the process since unix epoch in seconds. # TYPE process_start_time_seconds gauge process_start_time_seconds 1.64446715949e+09 # HELP process_cpu_seconds_total Total user and system CPU time spent in seconds. # TYPE process_cpu_seconds_total counter process_cpu_seconds_total 260.51 custom metricsをプログラム側で追加すると、このプレーンテキストに行が追加されていくことになります。 Prometheusが設定したエンドポイントをポーリングし、メトリクスを読み込みます。したがって追加されたcustom metricsも連携することができます。 custom metricsを追加しよう 利用方法もPrometheusのライブラリ側に書いてあるので、非常に親切です。 たとえば下記のように記載するとタイムアウトがどれくらい起きているかのメトリクスを追加できます。 ※異なるアプリケーション間でのメトリクス名を明確に区別するために、プレフィックスを付けています。 PREFIX = 'your_awesome_app' TIMEOUT_REDIS_COUNTER = prometheus_client.Counter(f'{PREFIX}_timeout_redis_counter', 'redis timeout counts') try: # some redis execution ... except redis.exceptions.TimeoutError: my_prometheus.TIMEOUT_REDIS_COUNTER.inc() Prometheusで監視しよう PrometheusではPromQLという記法で条件式を表現できます。 例えば下記のように割合を表現できます。入力から機械学習モデルのイレギュラー値の割合を、モデルに渡さない除外データの数を除外して計算しています。 これにより「有効データのうち、モデルが値を返せている割合」を監視できます。 (sum(increase(your_awesome_app_zero_score{app="your-awesome-app"}[10m])) - sum(increase(your_awesome_app_exclude{app="your-awesome-app"}[10m]))) / (sum(increase(your_awesome_app_input_records{app="your-awesome-app"}[10m])) - sum(increase(your_awesome_app_exclude{app="your-awesome-app"}[10m]))) < 0.0025 このPromQLによる検知がPrometheusのAlertmanagerに渡され、事前に設定した通知設定でSlackに通知されます。 custom metricsで計測すると嬉しいもの 以下のように外部IOや、アプリケーションの内部状態を計測しています。 外部IOに関して 複数の外部IOに接続して、レスポンス低下が起こっている場合に、どこで問題が起きているかが特定できて便利です。 response time(histogramを利用)やnetwork timeout数を計測しています。 分散トレーシングに関してはJaegerが得意なので、そちらで可視化しても良いです。 Prometheusで取得することで、PromQLで他メトリクスと同じように扱えたり、アラート通知が行えたりとメリットがあるのでこちらで計測しています。 内部状態に関して 注視しておきたい値を計測しておくと、時系列で追えるので便利です。 外部起因ではないアプリケーションのエラーの数 単純なsuccess rateだと外部起因エラーと内部起因エラーが交じるため、分離して監視しています。 今の所、安定して値を返せています。このような安定した数値は手動確認だと見なくなる傾向があるため、自動監視の恩恵が大きいです。 有効データのうち、モデルが値を返せている割合 単純なsuccess rateだと異常値は0点スコアとして200 OKで返すため、このメトリクスを監視しています。 監視することでモデルや入力データの異常に気付くことができます。 こちらも同様に普段発生しないため、自動監視に任せています。 機械学習モデルのスコア(histogramを利用) GrafanaでPromQLを記述し、Prometheusのメトリクスを可視化できます。 機械学習スコアの推移 こちらは問題が発生した場合の調査用に計測しています。 ※スコア自体は、相対的な順序が正しければそれでよく、絶対的な数値で正常・異常を測ることができないと判断しています。 機械学習スコアの比率は、細かなブレはありますが長期で見て変動ないことを確認できます。 ※年末年始に不動産会社がお休みのタイミングのみ微減しており、これは新鮮な物件広告の供給が途絶えていたためと考えられます。 モデルの継続的な品質担保は別の方法で行う必要があり、ABテストによるサイトのCTRやCVRを目視しています。 ※これはPrometheusで監視していませんが、サイトパフォーマンスのデータは別系統で集計されているためです。 Google Analyticsで計測されたものを、Data Studioのダッシュボードに表示しています。 そのほか こういうメトリクスを計測すると良いというものがあれば、ぜひブコメなどで教えてください! 終わりに Prometheusのcustom metricsを計測して通知すると、監視を効率よく行えることを紹介しました。 問題がやっかいなものになる前に、早めの対処で良いサービスを提供していきましょう! 最後に宣伝 このようにバックエンドサービスの開発から共通基盤開発まで、さまざまな職種を募集しています!よろしければぜひこちらのページもご覧ください! hrmos.co カジュアル面談もお待ちしております!ぜひぜひどうぞ! hrmos.co
プロダクトエンジニアリング部の海老澤です。 LIFULLでは2020年3月頃から自宅からのリモートワークが主体の働き方となっていますが、弊社が運営しているコミュニティ 「LivingAnywhere Commons」 の全国の拠点での就業も可能です。 これは従業員自らが働き方や働く場所を選択でき自分らしい働き方を実現することが、一人ひとりのWell-Beingやパフォーマンスの向上・イノベーションの種の発見に繋がると考えられているためです。 自宅だけでなく旅先の遊休施設で仕事をする、いわゆるワーケーションも行えます。 lifull.com 今回は 「LivingAnywhere Commons」 で二泊三日のワーケーションをしてきました。 控えめに言って最高だったので紹介させてください。 「LivingAnywhere Commons」 とは LIFULLは「あらゆるLIFEを、FULLに。」をコーポレートメッセージとして掲げ、さまざまな社会課題に取り組んでいます。 その中でも「自分らしくを、もっと自由に」をテーマに、ライフラインの限界から解放された本当の意味での自由な生き方を目指す取り組みが「LivingAnywhere」です。 そういった生き方を実践するコミュニティとして2019年に 「LivingAnywhere Commons」 の運営が開始されました。 コミュニティにはコワーキングスペース・レジデンススペースが完備されており、全国に拠点があるため自分の好きな場所で仕事・したい暮らしができます。(2022年1月現在29拠点・続々増えてます!) LIFULLの社員はこれらの拠点を格安・あるいは無料で利用でき、中には毎月利用されている方もいます。 ワーケーションレポート 今回は山梨県にある 「八ヶ岳北杜」 拠点を利用しました。 最寄は小淵沢駅、JR新宿駅から特急で2時間です。 ホームズくんも一緒にワーケーションしてきました 周辺のようす 駅から車で20分ほどの場所に拠点があります。 八ヶ岳北杜拠点 周辺 八ヶ岳北杜拠点 エントランス もともとは民間企業の研修施設だったようで、会議室や大浴場など設備はとても充実していました。 山の上(標高1000m)にあるため開放感がすごいです。富士山もバッチリ見られます🗻 個人的に夕暮れのオレンジと山々の青のコントラストが最高でした。 夕方の富士山 放し飼いにされているヤギもいます。 ヤギのニーナちゃん ワーキング 拠点はWi-Fiがしっかり飛んでいるのでどこでも自由にお仕事ができます。 コワーキングスペースも充実しており、各々作業環境を整えておりました。 二面ディスプレイの作業環境 分割キーボード勢の作業環境 ホームズくんの作業環境 バケーション 業務後はバケーションも楽しめます。 弊社はフレックスタイムを導入しているため、早めに退勤してお買い物にいったりサウナを楽しむメンバーもいました。 サウナーホームズくん 拠点にはサウナカーがあり、セルフロウリュも可能です。 ととのい環境も完璧で、水風呂はなんと 近くの川に飛び込むスタイル です。ワイルド〜! 晴れている日は満天の星空を眺めながら完全優勝しましょう。 圧倒的星空 サウナ後にバーベキューもできます。天才! 11月下旬の山でバーベキューは寒かった 感想 わくわくしながら働ける 普段と違う環境にそわそわすると思いきや、意外と集中して業務に取り組めました。 いつものリモートワークだと1日外に出ないこともよくあるのですが、 業務前の早朝にお散歩したり、地元のお店のおいしいケーキを食べたりQOLが爆上がりしました💣。 最高の朝 合宿で利用したい 今回は「Living Anywhere Commons 行ってみたい!」という好奇心からさまざまな部署の有志が集まって利用したのですが、チームビルディングや開発合宿にも最適な環境だと感じました。 働くのにはまったく不自由しない環境ですし、普段とは違うアクティビティも楽しめるので次回は部署単位で利用してみたいです。 自分らしくを、もっと自由に LIFULLではともに働く仲間を募集しています。 「自分らしくを、もっと自由に」を実現したい方、カジュアル面談という形で気軽にお話をさせていただくということも可能ですので、ご興味がある方は以下のページをご覧ください。 hrmos.co hrmos.co
エンジニアの松尾です。LIFULL HOME'Sの売買領域を支えるエンジニアチームのマネジメントを担当しています。 私の部署を始め、LIFULLでは複数の部門でエンジニア採用を行っています。人事部門の採用担当と現場で連携し、書類審査と複数回の面接により選考を行います。 今回はエンジニア採用を進める上で感じた課題とその解決への取り組みについて紹介したいと思います。 採用において抱えていたモヤモヤ いくつかの書類審査と面接を終えて、日々似たような作業を繰り返しながらいくつかのモヤモヤを抱えていました。 モヤ1: 書類審査に時間がかかる 打率よりもまずは打数。より良い候補者様を見つけ出すために、できるだけ多くの書類に目を通すようにしています。ただしどの方も真剣に経歴を書いてくださっており、すべてに目を通すにはなかなか時間がかかります。 採用以外にもやるべき仕事は多くあります。書類審査に時間をかけすぎることで、ほかの業務の質を下げてしまうリスクもあります。 モヤ2: 面接の時間を有効に使えない 実際に候補者様と対面する面接は、時間を無駄にしないよう慎重に行います。しかし結果を出すためには聞き出したい情報が多くあり、すべてを質問しているとすぐに終了時刻になります。 事前に職務経歴書内の掘り下げたい箇所については確認しつつも、自分の中で要点が定まっていない状態でした。 モヤ3: 自分で評価した結果が腹に落ちない 全力で書類チェックと面接をした結果として、手元には多くの判断材料があります。ですが「この点は物足りないけど、この部分がすごく良いからOKにしようかなあ…」と評価ポイントや基準が定まっておらず、結論を出すのに時間がかかります。そしてほかの評価者とすり合わせると意見が割れ、合議での結果出しにまた時間を要します。 最終的には合議で正しい結論を出せていると思っていますが、個人での評価には不備があり、納得に至るまでのプロセスに時間がかかりすぎている状況でした。 取り組んだこと 何かもう少しうまくやれる方法を模索できないか…と人事や上司に相談しようかと考えていたときに、 下記リンクの記事を発見しました。 現場メンバーの知識を人材要件定義に活かす手法「Job Analysis」の紹介 参考文献をもとに選考プロセスの設計について記載されていますが、私の部署の採用では以下の2点がまだ不十分である印象を持ちました。 採用したい人の人材要件を定義する 人材要件のうち、見極めたい能力を特定する そこで、ブログの内容を参考に求める人材の像を明らかにし、求人ページの応募資格を再設定するための取り組みを進めました。 業務上発生するタスクの洗い出し 採用したい人材とポジションが似たメンバーに協力してもらい、業務内でどのようなタスクを行っているかを洗い出しました。エンジニアにとっては設計、プログラミング、テストなどが主たる業務ですが、ほかの職種とのやりとりやメンバー育成など、タスクは多岐に渡ります。 私は比較的現場に近いポジションなのである程度は把握していましたが、あらためて眺めてみると気付きがあります。 実装よりもレビューの比重が大きそう 他のメンバーに何かを教えたり協力したりするタスクが多い ネットワークやDBの設定をスクラッチで行う機会は少ない 求められている能力(コンピテンシー)の洗い出し タスクとは別に、どのようなスキル/経験を求めているかを洗い出します。 言語、OSS、専門分野などのリファレンスとして、 Qiita の人気のタグを抽出して使用しました。これらからノイズを除去し、残った項目から現場で必要になり得る項目をまとめていきました。 弊社には新旧含めて多くのシステムが存在するため関わる技術は多く、項目全体で見るとなかなかの数になります。重要度の低いものはこのあとの工程で削ぎ落とされるため、現段階ではすべて含めておきます。 スコアリングと文章化 ブログの内容を参考に、タスクとコンピテンシーのそれぞれにスコアをつけていきます。頻度や重要度などの観点で点数を付け、それぞれに序列ができます。スコアリングはほかのマネージャーと相談しながらプランニングポーカーのような要領で進めました。 タスクとコンピテンシーの上位項目を突き合わせて、結果をもとに徹底的に議論します。 「今いるメンバーの立ち回りを考慮すると、PJ管理経験は必須だね」 「言語の具体的な知識より、設計力を優先したいですね」 「〇〇は面接で質問してたけど、入社してから覚えるでも問題ないね」 というようなやりとりを経て、人材要件が新しく定義されました。結果として、応募資格に記載していたスキルを下記のように変更しています。 応募資格の変更 人材要件を見直して改善したこと 実際に現場で必要としているタスクや求めている能力を見つめ直すことで、以前とは違った人材要件ができました。洗い出しただけではなくそれぞれの優先度も確認したため、採用活動の中で候補者様を評価する順序や観点も違ってきます。 見直し前のモヤモヤと比較して、改善した点についてまとめます。 書類選考でチェックできる人数が増える 要件ごとの優先度が決まったことで、書類の中で確認する箇所が明確になり、チェックの所要時間が削減できました。優先度の高い要件を満たしていない場合は早めに候補から外したり、なんとなく魅力的に見えてしまうスキルに目移りしなくなったことで、書類選考の量と質の両方が改善したと感じています。 面接が時間内に完了しやすくなる 優先度の高い要件から早めに質問していくことで、面接内で過不足なくヒアリングを終えられることが多くなりました。要件ごとの重要度が頭に入っているおかげで、質問ごとにかける時間の判断がしやすくなります。また我々からの質問が手短に終えられることで、候補者様からの質問も多く受け付けられます。 評価時のすり合わせがスムーズになる ターゲットとなる人材の像を文書化して認識を合わせたため、複数の評価者で議論して結論を出す場合にも意見が割れづらくなりました。「評価項目Aは文句なしですが、Bは満たしていないですよね」という項目ごとの評価に関する会話もしやすくなり、合否の理由付けも以前より明確になっています。 まとめ 採用活動は非常に重要な仕事ですが、本業務であるエンジニアリングと同時に進めるためには効率化が必須であると感じています。今回はスタート地点にあたる人材要件の作成に手間をかけることで、数ある書類選考や面接をスムーズに迷いなく進められるようになりました。 結果をすばやく正確に出せることは、採用をする我々だけではなく候補者様の転職活動のためにも有意義です。今後もより多くの方とお話をし、ともに働く仲間をみつけるために、妥協のない採用を続けていきたいと思います。 このように選考内容の改善も考えながら、一緒に働く仲間を募集してます。よろしければぜひこちらのページもご覧ください。 hrmos.co hrmos.co
事業基盤ユニットアーキテクトグループのyoshikawaです。 今回のブログではLIFULL HOME'Sを構成するレガシーシステムのリアーキテクティングについて書いていきます。 2年前にリアーキテクティングプロジェクトが発足し、ソフトウェアアーキテクチャのベースにClean Architecture、言語にTypeScriptを採用し 新たなAPI(Backend For Frontend)を開発してきました。 「コードの品質」と「プロダクト開発エンジニアとのコミュニケーション」が鍵となっていた本プロジェクトですが、 このブログ記事では「コードの品質」を主題として取り組みをオムニバス的に紹介していきます。 この記事で伝えること 想定する対象読者 過去のブログの紹介 データフローに注目したLIFULL HOME'Sのシステム概観 リアーキテクティングプロジェクトについて アーキテクトチーム(イネイブリングチーム)とプロジェクトの概要 新BFFへのリアーキテクティング対象機能 機能の特性と深刻な内部品質の劣化 エンジニア組織と横断的な機能 プロジェクト序盤:新BFFのアーキテクチャ選定、技術選定、PoC プロジェクト中盤〜現在:品質維持・改善 ユニットテスト コード量増加とBFF特有処理 モジュールの特徴を理解し、高凝集疎結合に 凝集度が高いモジュールを厚く、低いモジュールを薄く 凝集度に着目した解決策の効果 結合テスト・回帰テスト 機能系のテスト パフォーマンステスト 負荷テスト テスト結果の蓄積 リリース後の品質維持と検証とメトリクス 内部品質: 技術的負債の可視化 外部品質: パフォーマンスの可視化 リアーキテクティングの現在と今後:ノウハウの蓄積とリプレイスに向けて 終わりに Clean Architectureの考えを継承しつつ、アーキテクチャ内製化へ 内製ソフトウェアアーキテクチャを普及させる仕組みと教育 理想とこれからの課題 データ整備の課題とその解決のために 求人情報 この記事で伝えること LIFULLのレガシーシステムである参照系モノリシックアプリケーションの機能を新たなAPI(Backend For Frontend)へとリアーキテクトするまでの取り組み リアーキテクティングを支えた品質維持のためのツール、テスト、コーディング コードの品質、ソフトウェアアーキテクチャ、リファクタリング、Clean Architectureに関するプラクティス 想定する対象読者 十数年以上稼働し技術的負債を多く抱えるWebサービスにおけるレガシーシステムの改善について知りたい人 リアーキテクティング(リアーキテクチャ)やリファクタリング、コードの品質に関する実践的な取り組みを知りたい人 コードの品質やソフトウェアアーキテクチャに興味がある人 過去のブログの紹介 プロジェクト発足の経緯や新たに開発したBFFのアーキテクチャ選定、技術選定理由などプロジェクト初期の内容は過去のブログにまとめています。 気になった方はそちらもご覧ください。(読まなくともこのブログの内容は理解できます) www.lifull.blog データフローに注目したLIFULL HOME'Sのシステム概観 本題へと入る前に、LIFULL HOME'Sのシステムの概観をお伝えします。 BtoBtoC型の事業に類されるLIFULL HOME'Sでは多様なシステムから全体が構成されています。 toB用の書き込み系システムから物件データが入稿され、バッチ・DBなどのシステムを経て処理・蓄積された後、 物件検索機能などLIFULL HOME'Sの各種サービスで物件情報が利用可能となります。 そのデータフローを簡潔に示したシステム構成図が下記です。 LIFULL HOME'S の物件情報参照系システム概観 なお、リアーキテクティングプロジェクトでは参照系システムの技術的負債解消を目的としているので、 その対象外となるシステムや詳細なネットワーク構成、インフラ構成については省略しています。 図中の「モノリシックアプリケーション」こそがリアーキテクティングプロジェクトでの改修対象となるレガシーシステムであり、 「新BFF」がモノリシックアプリケーション上に実装された諸機能の移行先となります。 リアーキテクティングプロジェクトについて LIFULL HOME'Sを構成するシステムの概観をつかめたところで、本題であるレガシーシステムのリアーキテクティングおよびプロジェクトについて紹介します。 アーキテクトチーム(イネイブリングチーム)とプロジェクトの概要 筆者が在籍しているアーキテクトチーム(イネイブリングチームの一つ)の業務は2種類に分けることができます。 一つは、プロダクト開発チームで発生した設計や実装に関する問題の相談および解決策の提供です。 もう一つはプロダクト開発チームでの実行が難しい横断的な問題への取り組みです。 いずれの業務も、プロダクト開発エンジニアの生産性向上に寄与し続けることを目的としています。 そして2年前、後者の業務の一環としてLIFULL HOME'Sの参照系モノリシックアプリケーションにおける技術的負債の解消を目指すリアーキテクティングプロジェクトが発足しました。 このプロジェクトのミッションは、モノリシックアプリケーションが担っていた機能のフロントエンド部分とバックエンド部分の処理のうち、 バックエンド処理のリアーキテクティングを完了させることです。 そのリアーキテクティング先として、新たなBackend For Frontend(新BFF)の開発をすることとなりました。 新BFFへのリアーキテクティング対象機能 その膨大なLOCと影響範囲の大きさゆえ、モノリシックアプリケーションのすべてがリアーキテクティング対象になるわけではありません。 移行予定の機能を構想した後、リアーキテクティングによる事業上のインパクトや機能の特性、プロダクト開発チームとの調整ごとを加味して新BFFへ移行される機能を決定しました。 新BFFへのリアーキテクティング構想:巨大モノレポを複数のGitHub Repositoryから構成された新BFFに移行する その一つが「物件一覧機能」で、「検索条件の設定・変更」から好きな条件を入力し、入力完了と同時に検索が非同期的に実行されて条件に合致した物件情報を一覧できるという機能です。 100万件超の不動産・住宅情報を取り扱っており、派生系の機能も含めて100通り以上の導線(URL)を有していることからリアーキテクティングによる対外的な影響が大きい機能です。 そして横断的に情報が検索可能という特性上、複数のプロダクト開発チームで横断的に開発されている機能でもあります。 機能の特性と深刻な内部品質の劣化 物件一覧機能では下記のような内部品質の劣化が深刻でした。 入力した物件検索条件をパースする処理や、取得した物件情報を整形する処理がモノリシックアプリケーション内のControllerやViewなどに散乱しており、コードのトレーサビリティが低い ソフトウェアアーキテクチャや実装規約の陳腐化、責務が多過ぎるモジュール(いわゆる神クラス)の存在、コードのトレーサビリティの低さが相まって、機能改修・追加による影響範囲特定が困難 古めのバージョンのPHPで実装されており、型付けが行われておらずユニットテストの機構もないので可読性やテスタビリティが低く、潜在的なデグレーションが多い ドキュメントが機能していないので社内有識者へのヒアリングが頻発し、新規開発者にとって実装完了までのオーバーヘッドが大きい(最悪の場合、有識者が退職しており調査が困難) 内部品質の劣化はモノリシックアプリケーションの機能にも多く当てはまりましたが、物件一覧機能においては顕著でありフロー効率の低下を招いていました。 このような理由から、モノリシックアプリケーションのみを対象としたリファクリングや新BFFへの移行を伴わないリアーキテクティングだけでは技術的負債の解消には不十分と判断されました。 エンジニア組織と横断的な機能 LIFULL HOME'Sでは「不動産・住宅情報」というドメインの関心を起点として「賃貸」や「売買」など不動産のマーケット別にプロダクト開発チームが分割されています。 そして「物件一覧機能」では賃貸用の物件や売買用の物件など、複数の不動産マーケットの情報を横断的に一覧可能です。 つまり物件一覧機能は機能単体としての技術的負債だけでなく、責務が分割された横断的な機能であることからプロダクト開発チームとの横断的な連携を要する、という性質を備えていました。 横断的な機能かつ新規APIの開発を伴うプロジェクトということもあり、開発に対するステークホルダーが多いため、 横断的な基盤開発の可能なアーキテクトチームが開発の中心となりました。 LIFULLのエンジニア組織の概観:チームトポロジーの4つの基本的なチームタイプにより分類 プロジェクト序盤:新BFFのアーキテクチャ選定、技術選定、PoC 技術的負債を解決すべく、 Clean Architecture をベースにしたソフトウェアアーキテクチャで 新たなBackend For Frontend API(新BFF)を開発することが決定されました。 言語には学習コストの低さと型システムの存在から TypeScript が選ばれ、OASを備えたミニマルなWeb API Frameworkとして Loopback が採用されました。 技術スタックの選定など、プロジェクト序盤のより詳細な内容は冒頭でお伝えした過去のブログをご覧ください。 新BFFの技術スタック アーキテクチャと技術選定が完了した後は、PoC(Proof of Concept)の一環として「不動産用語集」機能という実在の機能を新BFFへリアーキテクトしました。 その後検証プロセスを経て新BFFが技術的負債の解消に寄与することを確認し、プロジェクトの本格始動となりました。 プロジェクト中盤〜現在:品質維持・改善 初期段階で正しいアーキテクチャ選定や技術選定をすること、あるいは初期のベストな実装のみによって技術的負債の解消や予防になるわけではありません。 「負債」というアナロジーの通り、初期段階では事業の成長を支える資産とも言える技術基盤であっても、継続的な品質維持のための改善を欠いてしまうと負債へと転じ得ります。 継続的な改善を実施するために、内部品質(可読性に問題はないか・保守性は高いかetc)と外部品質(仕様通りに動作するか・速度劣化が生じていないかetc)の両方の点で ソフトウェアテストを徹底して行い、同時にテストがしやすくなるような改善も行ってきました。 ユニットテスト 新BFFではユニットテストとAPIテスト用のテスティングフレームワークとしてJestを使用しています。 jestjs.io 主にテストランナーやテストカバレッジの出力、CI/CDでの自動テストという用途で利用しています。 Clean Architectureベースということもあり、モッキングについてはJestの機能を利用しておらずモック用のコードを作成しています。 コード量の少なかったリアーキテクティング初期フェーズではユニットテストの運用は順調でしたが、コード量が増えるにつれある問題が顕在化しました。 コード量増加とBFF特有処理 テストは重要です。しかしコード量が増えるにつれ、何を担保するテストなのか目的が分からなくなるほど冗長なテストコードを書いてしまう、というケースも目立ち始めました。 特に顕著だったのはDTO変換処理です。 新BFFにおける物件一覧機能用APIでは物件情報を含めたDTO(Data Transfer Object)を変換する処理が頻出します。 それらは以下のように、Domainを除く3つの層(Gateway, UseCase, Presenter)間および外部コンポーネントとのIn/Outの2通り計8パターンで分類できます。 外部データソース(=LSUDs API)のレスポンスオブジェクトをBFF内のGateway(Repository) DTOに変換する処理と、Repository DTOを外部データソースへのリクエストオブジェクトに変換する処理 Repository用DTOとUseCase用DTOとの相互変換処理 UseCase用DTOとPresenter用DTO(検索条件DTOとView Model)との相互変換処理 UI(フロントエンド、モノリシックアプリケーション)から送信されたリクエストオブジェクトをController用DTOに変換する処理、ViewModelをUIへのレスポンスオブジェクトに変換する処理 新BFF内のデータフロー図:Domain以外の層ではDTOを介してデータを送受信 DTO変換処理はレイヤー間の責務の違いによる差分こそありますが、大部分は似たような実装となってしまいます。 下記はそのサンプルコードで、PresenterにおいてInputDtoのプロパティ(ValueObjec)からOutputDtoが要求するプロパティを作成し詰め替える処理です。 export class Presenter { constructor(private readonly input: UseCaseInputDto ) {} present () : OutputDto { return new OutputrDto ( { money: this .input.money ? helper ( this .input.money , this .input.unit , this .input.house_type ) : 'default price' , houseName: // ワンライナーやヘルパー関数の呼び出しなど houseAddress: // // ワンライナーやヘルパー関数の呼び出しなど } ); } helper ( money?: MoneyValueObject , unit?: UnitValueObject , houseType?: HouseTypeValueObject ) : string { // money(金額)のフォーマット処理を行うヘルパー関数 } } リアーキテクティング初期段階ではDTOやプロパティの変換処理は単純なものであったため、ワンライナーや即時的なヘルパー関数への分割でも問題ありませんでした。 やがてモノリシックアプリケーションに存在していた機能の移行が進むと、BFFに実装する処理も複雑になりテストのし辛さも目立ち始めました。 その辛さをカバーすべく冗長なテストコードおよび巨大なモックが増えてしまいました。 この状況を見直すべく実装パターンの見直しを行います。 モジュールの特徴を理解し、高凝集疎結合に そもそもDTO変換処理はフロントエンドの要求に従って必要なプロパティを寄せ集め、用途に沿った加工を施し、扱いやすいよう集約する処理とも言えます。 よってフロントエンドの要求を受け入れるだけのBFFから見れば、偶発的に選ばれたプロパティに対し特に規則性のない処理を施し、一ヵ所に凝集させる処理とみなせます。 そのため注意して実装しなければ必然的に偶発的凝集・論理的凝集が生じ、凝集度の低いモジュールが出来上がってしまいます。 実際に上記のコードからわかるように、凝集度と結合度の観点でDTO変換処理には改善の余地があります。 OutputDtoのconstructorの引数の複雑さ・統一性の無さや、Presenterクラスの責務の多さを見ての通り、 実装の観点で似たような処理をただ集めた論理的凝集、つまり凝集度の低い状態が生じています。 これまでの新BFFではClean Architectureが示した責務別のレイヤー分割を忠実に採用し、 dependency-cruiser による依存関係違反の検知でモジュールの集合間(=レイヤー)の健全性は担保されていました。 しかし、一つのレイヤー内でのモジュール間の結合、および単一モジュールの凝集性は原理原則をヒントにしつつ自分たちで考える必要があったのです。 凝集度が高いモジュールを厚く、低いモジュールを薄く 凝集度とテストの辛さが相まったDTO変換処理問題の解決策として、Humble Objectパターンにヒントを見出しました。 テストの書きやすさと凝集度を両立させるべく、DTO変換処理を「凝集度を高くすべき部分」と「凝集度が低くても良い部分」に分離したのです。 「凝集度を高くすべき部分」では、テストすべきロジック(フォーマット、バリデーションなど)や再利用すべきロジックを集約させるとともに、テストカバレッジ100%を目指すなどしてテストコードを充実させます。 「凝集度が低くても良い部分」では、テストコードをほぼ書かずともTypeScriptの型システムだけで品質が担保可能となるような実装に限定します。 つまり、「凝集度を高くすべき部分」に渡す値とその戻り値を列挙するインタフェースとしてのコードを記述するだけにしました。 簡単な例ですが、具体的には下記のように実装しています。 凝集度が低くても良い部分 // 凝集度が低くても良い部分の実装、テストは薄くていい export class PresenterDtoConverter { constructor(private readonly input: UseCaseInputDto ) {} // (BFF的には)偶発的に必要とされるプロパティは列挙するだけ covert () : PresenterDto { return new PresenterDto ( { // テストすべき凝集度の高い処理(実際のPresentation処理)を呼び出し money: MoneyPresenter.format ( this .input.money , this .input.unit , this .input.house_type ), houseName: HouseNamePresenter.format ( this .input.name , this .input.house_type ), houseAddress: HouseAddressPresenter.format ( this .input.address , this .input.house_type , ), } ); } } 凝集度を高くすべき部分 // 凝集度を高くすべき部分の実装、テストを厚くする export class MoneyPresenter { private static readonly defaultPrice = 'default price' ; // 引数はBFFの最小構成単位であるValue Objectだけ static format ( money?: MoneyValueObject , unit?: UnitValueObject , houseType?: HouseTypeValueObject ) : string { // 複雑なPresentation処理 } } 凝集度に着目した解決策の効果 凝集度を起点に実装パターンを定めたことにより、テストと可読性の両観点でメリットがあります。 可読性の観点では、個別の値に関する仕様については「凝集度を高くすべき部分」を、 フロントエンドが要求する値の一覧については「凝集度が低くても良い部分」を見れば良いという共通認識が形成されます。 テストの観点では、「凝集度を高くすべき部分」は網羅性の高いテストを、「凝集度が低くても良い部分」は全体の結果の成否を確認する程度のテストを記述して テストのしやすさと保守性が担保できました。 もちろんデメリットもあり、それは実装のLOC(Lines Of Code)の増加です。 複雑なコードに慣れ親しんだ熟練者から見れば、変更前のコードこそ行数が少なくシンプルで良いと言えましょうが、今回は民主的にコードの品質を担保することを優先しました。 テストコードの冗長化に端を発する一連の問題でしたが、凝集度に注目したコード品質の向上というアプローチで解決できました。 結合テスト・回帰テスト フロントエンド(モノリシックアプリケーション)とバックエンド(新BFF)およびデータソース(LSUDs API)との結合の際には 複数の観点で結合テスト・回帰テストを実施して参照系アプリケーション全体の品質を担保しています。 しかし、ユニットテストの機構が整備されていないモノリシックアプリケーションがテスト対象に含まれているため、CI/CDでのテスト自動実行だけでは担保しきれない項目も多いです。 そのため、専用のテスト実行スクリプトや各種ツールのグルーコードを集約したライブラリを作成し、 テスト自動実行とローカルでのスクリプト実行とを交えてテストを実施しています。 以下では、ほぼすべてのテスト項目とその効率化のための取り組みについて紹介していきます。 機能系のテスト リアーキテクティングにおいてはその実施前後で、外部から見た挙動や機能が損なわれないことを担保することが必須です。 物件一覧機能においては表示される物件情報に差分が生じず、検索の挙動が仕様どおりで変化しないことを担保します。 その方法自体は以下の通りナイーブなアプローチです。 リアーキテクティング前後のテスト用の環境をそれぞれ用意する それぞれの環境で最終的にserveされるhtmlファイルをcurlによって取得する htmlから不要な要素・メタデータをスクリプトでクレンジングする クレンジングされたhtmlのdiffの有無を検知する diffが生じなければテスト成功 各プロセスのスクリプト化、 Playwright による画面操作の自動化など テスト効率化のための取り組みに加え、1.のテスト環境の用意では自社のアプリケーション実行基盤を活用し効率化しています。 テスト用の環境を用意する際には、Kubernetesベースの内製アプリケーション実行基盤により提供されているエフェメラルな開発環境を利用しています。 こうすることでテスト用環境の整備・管理の時間を削減するとともに、ローカル環境の差分など属人的な要因を排除し、再現性のあるテスト実行環境を用意できます。 テスト用環境はPull Request単位で作成可能で、Pull Request内での特定ラベル付与をトリガとしたGitHub Actionsが実行され、24時間だけ提供されます。 "preview"ラベルをPull Request内で指定するだけでテスト用環境を作成 自社アプリケーション実行基盤については下記などのLIFULL Creators Blogをご覧ください。 www.lifull.blog パフォーマンステスト 複数のコンポーネントが結合された参照系アプリケーションでのパフォーマンステストでは、 エンドユーザーに一番近いフロントエンド部分のレスポンスタイムのパーセンタイル値(p95)をメトリクスとします。 そのパーセンタイル値とSLAを基準にした速度劣化の許容値を比較し成否を判断します。 テスト実行や計測は前述のテスト用スクリプトやエフェメラルな環境を用いて実施しています。 許容できない速度劣化を計測した際など、詳細なパフォーマンス解析が必要になった場合にはFlameGraphを活用したスタックトレーシングにより原因の特定を行います。 開発途中である新BFFにおいては 0x でローカルでの解析を実施し、 それ以外の成熟したコンポーネントでは Datadog APM 上で解析を行いました。 負荷テスト 負荷テストではAmazon CloudWatchから移行対象機能の平常時/ピーク時アクセス数など過去の数値を収集し、 それらを基準として、秒間リクエスト数やリクエスト送信期間などを変えた複数のシナリオを作成します。 新BFFはKubernetesベースの自社アプリケーション実行基盤をインフラとして動作しているため、 そのシナリオ下の負荷でも機能が正常にアクセスできる、あるいは期待通りにスケールアウトするような Podの性能、Podのスケーラビリティなどのリソース調整を完了させることが負荷試験のゴールです。 シナリオベースで負荷テストを実施すべく、負荷テストのツールはHTTP通信用の負荷テストツール Vegeta をベースに作られた Kubernetes ControllerであるVegetaControllerを使用しています。 github.com 下記のようなyamlファイルにシナリオを記述し、 kubectl apply 実行時の引数にシナリオファイルを指定することで実行が可能です。 # シナリオ例: 30req/sec * 60sec のスパイクテスト metadata : name : attack-bff-ephemeral spec : scenario : |- GET bff-ephemeral/v1 GET bff-ephemeral/v1?param=1&flg= true output : text option : duration : 60s rate : 30 結果解析フェーズではサクセスレートや消費メモリの推移、スケールに伴うpod数の推移などをVegetaControllerの出力とGrafanaから取得し、 各シナリオの合否を判定します。 grafana.com Grafanaによる負荷テストの分析(図はPod数の推移) テスト結果の蓄積 これまで紹介したテストの成否やテストケースおよびそのカバレッジ、テスト実行方法、テスト実行時の条件、発生したバグの詳細など、 テスト結果に関する事柄は内製のテスト管理ツールを活用することでダッシュボード化するとともに一ヵ所に集約しています。 内製テスト管理ツール:テストに関するデータとダッシュボードが集約されている このようにして過去のテスト結果を蓄積し活用しやすくすることは、長期間になるリアーキテクティングプロジェクトにとって重要なことです。 リアーキテクティングプロジェクトは ストラングラーパターン というアプローチを執っているため、 対象となる機能すべての移行作業が完了するまでには複数回のリリースが必要となります。 完了には時間にして2年要するとされていました。 そして、その複数回のリリースのいずれにおいても上記のテストプロセスが含まれています。 将来のテストプロセスを効率化するという点で、過去のテストプロセスを活用できるようにしておくことには大きな意味がありました。 また知見を一ヵ所に蓄積し誰でもアクセス可能にすることで、テストに必要な知見を属人化させずにSSOT化できます。(Single Source Of Truth: 信頼できる単一の情報源) SSOTを構築することで、プロジェクト期間中にチームメンバーの入れ替わりが発生した際でもオンボーディング時のオーバーヘッドを最小化し、プロジェクト完遂へのリスクを抑えることができます。 リリース後の品質維持と検証とメトリクス それぞれのテストプロセス後、無事リリースされた後も品質維持のための取り組みは続きます。 内部品質と外部品質の両方の観点で技術的負債の解決を示す指標を計測し、リアーキテクティングによる影響分析を行っています。 その主たるものとして、技術的負債の可視化とパフォーマンスの可視化を紹介します。 内部品質: 技術的負債の可視化 LIFULLでは技術的負債の状況をリアルタイムに反映しているダッシュボードを構築しています。 エンジニアなら誰でも・いつでも・専用の申請なしで・同じ情報にアクセスでき、これもまたSSOTの一つです。 仕組みとしては、GitHub API、CodeClimateQuality APIの2つからコードの品質に関するデータを取得し、それらのデータを Metabase で可視化するというものです。 可視化ダッシュボードや技術的負債に関する指標については、過去のブログをご覧ください。 www.lifull.blog 以下の図のように、GitHub Repository単位で技術的負債を可視化しております。 技術的負債の推移の可視化イメージ リアーキテクティング先の新BFFは技術的負債については、具体的な数字をお見せすることはできませんがほぼ負債を抱えることなく開発できています。 技術的負債比率(図中左上のパーセンテージ)は、Code Climate Quality の MaintainabilityでA相当と低く抑えることができております。 docs.codeclimate.com 一方、リアーキテクティング元のモノリシックアプリケーションの技術的負債については、モノリスゆえの難しさが存在します。 モノリスゆえ特定機能に絞った改善を計測することが難しく、それに加えて物件一覧機能のリアーキテクティング実施中にも別のリファクタリングプロジェクトも進行しています。 そのため、ダッシュボードだけから物件一覧機能のリアーキテクティングに絞って技術的負債解消への寄与度合いを計測することは難しいです。 しかしながら、膨大な推定修復時間(=技術的負債を返済するまでかかる時間)を要するとされたモノリシックアプリケーションの主機能の一つである物件一覧機能を ほぼ技術的負債が見られない新BFFに移行できていることから、本プロジェクトが技術的負債解消の大きな一歩になっていると言えます。 外部品質: パフォーマンスの可視化 既出の通り、外部品質についてはDatadogでのパフォーマンス可視化やGrafanaでのインフラリソース状況推移の可視化を実施しています。 これらに加え、総合的なパフォーマンス推移を計測するためにLIFULL HOME'SのWebサイトのパフォーマンスの推移をSpeedCurveで計測・可視化しています。 www.speedcurve.com 下記は賃貸物件一覧機能(物件一覧機能の一つ)の昨年のパフォーマンスの推移を示した図です。 SpeedCurveによる物件一覧機能Webサイトのパフォーマンス推移 外部品質の点でも別プロジェクトによる軽微な影響は存在し、実際の数字をお見せすることはできませんがリアーキテクティングによってパフォーマンスは維持どころか総じて改善できています。 リアーキテクティングの現在と今後:ノウハウの蓄積とリプレイスに向けて 2022年1月現在、かつてモノリシックアプリケーションに存在した物件一覧機能の多くが新BFFへと移行されました。 プロジェクト発足当初のアーキテクチャ選定、技術選定から2年近くが経過した後も、新BFFおよび物件一覧機能においてインシデントはほぼ発生せず安定稼働を実現できています。 リアーキテクティングプロジェクトはもう少し続きますが、新BFFへのリアーキテクティングも終盤に差し掛かり、今春に予定していた移行作業が完了する見込みです。 しかし、事業の成長の陰に蓄積され続けたモノリシックアプリケーションの技術的負債の完全解決にはまだまだ時間がかかり、2年の時間をかけたリアーキテクティングプロジェクトはその一歩に過ぎません。 とはいえ、リアーキテクティングプロジェクトで得られたコード品質やアーキテクチャに関するノウハウとそれらを活用した後発プロジェクトの存在もあり、可視化ダッシュボード上の数字ほどは途方もない作業ではないと言えます。 フロントエンド部分を含めてモノリシックアプリケーションのリプレイスを実現すべく、プロダクト開発チームによるリファクタリング・リアーキテクティングおよび品質維持が促進されゆく予定です。 終わりに 技術的負債を解決および予防し、継続的にフロー効率の高い開発を行うためにも内製ソフトウェアアーキテクチャを含めた「コードの品質」のための取り組みは今後も続きます。 最後に、今後のLIFULL HOME'Sのシステムにおけるコード品質の今後の展望と、リアーキテクティングプロジェクトを通じて見えたデータの課題をお伝えします。 Clean Architectureの考えを継承しつつ、アーキテクチャ内製化へ Clean Architectureをベースに開発が開始した新BFFのソフトウェアアーキテクチャですが、 アーキテクトチームではClean Architectureが伝えているものはあくまでプリミティブな原理原則であるという認識で開発しています。 凝集度の例にあるように、実際にどのように実装しパターン化するかは機能の特性をもって判断しています。 そのパターンの中には、凝集度の項でお伝えしたような比較的一般化可能なものから、LIFULL独自の制約に由来したことで場合によってはアンチパターンと呼ばれてしまうものもあるかもしれません。 また、新BFFのソフトウェアアーキテクチャは物件一覧機能のリアーキテクティングを行ったプロジェクトおよびその当事者であるアーキテクトチームだけで完結するものではありません。 コードの品質向上に対する成果が認められ、複数の新機能実装プロジェクトや別のリアーキテクティングプロジェクトにおいても新BFFのソフトウェアアーキテクチャが採用・応用されています。 今後は幅広いプロジェクトでの利用に耐え得るように、Clean Architectureの考えを継承しつつ、LIFULL独自のパターンとノウハウを備えた内製ソフトウェアアーキテクチャを正しく普及させ運用することが求められます。 内製ソフトウェアアーキテクチャを普及させる仕組みと教育 内製ソフトウェアアーキテクチャの普及のためには、ドキュメンテーションや開発者コミュニティづくりなど、 プロダクト開発チームが自律的に開発可能になることを補助するための仕組みおよび教育が必要です。 後日公開予定のブログにて、その仕組みづくりなど「プロダクト開発エンジニアとのコミュニケーション」においてアーキテクトチームが実施したことを詳しくお伝えする予定です。 理想とこれからの課題 LIFULL HOME'S の物件情報参照系システム概観:モノリシックアプリケーションの技術的負債が解消した場合の理想形 上記は冒頭に載せたデータフロー図とほぼ同じですが、リアーキテクティングプロジェクト等のモノリシックアプリケーション上の技術的負債解消の取り組みによって、参照系アプリケーション開発の分散統治が可能になった将来的な理想形です。 開発の度に全社的な調整を要することもあるモノリシックアプリケーションから、部署レベルでの自治(self-service)が可能な単位で機能が切り離される、という構図です。 その端緒であり、技術的負債解消という当初の目的を果たしつつあるリアーキテクティングプロジェクトですが、self-serviceの障壁となり得る課題がプロジェクトを通じて顕になりました。 それがデータ整備です。 図中でLIFULL HOME'Sのシステムを「データ分析システム」・「データ利用システム」・「データ提供システム」の3つに分類しましたが、 その3つを通じて運用されるデータの品質には依然として課題があり、整備する余地があると考えています。 データ整備の課題とその解決のために データ分析・活用の文脈で語られることの多いデータ整備ですが、LIFULLのように一定以上の規模と歴史を持つ業務用アプリケーション開発においてもデータ整備の課題は顕著であると考えています。 その中でリアーキテクティングプロジェクトにおいて体感した課題はデータの発見可能性です。 既存システムの理解のためにコードリーディングを行う機会は多々ありましたが、 改修対象のモノリシックアプリケーションのコードリーディングに加え、大元のデータソースであるLSUDs APIやデータベースを対象とした利用すべきデータの発掘やデータ仕様調査にも多くの時間を要しました。 つまり、「データ提供システム」で生成されるデータが「データ利用システム」で利用可能になるまでに属人的な取り組みが必要だったのです。 リアーキテクティングプロジェクトとは別の調査で判明していることですが、上記以外にも以下のような課題があると考えています。 分析用データ(OLAP)と、アプリケーション用データ(OLTP)の一貫性の問題(→「データ分析システム」と「データ利用システム」間のデータ相互運用性が低い) 特定のアプリケーション向けに加工されたデータを再加工する必要性の存在(→「データ利用システム」間のデータ相互運用性が低い) 再利用すべき大元のデータおよびそのデータに至る経路が見つけられない、見つけられないので似たようなデータを使うか自作してしまう(→システムを通じたデータ系統樹:Data Lineageの問題) データ整備が起因する課題はドキュメンテーションや有識者へのヒアリングなど、静的なコンテンツの整備や属人的な努力によって一時的には解決可能な問題です。 しかし、大規模なデータを抱えるLIFULLにおいて持続可能性のある解決策を実現するためには、データをマネジメント・発見・一覧可能な基盤づくりが必要と考え現在はその検証が進行中です。 求人情報 LIFULLではエンジニアの募集をしております。 このブログで紹介させていただいたような、Clean ArchitectureとTypeScriptで堅牢なアプリケーション開発を行う業務も可能ですので、募集中の職種や詳細などは下記をご覧ください。 hrmos.co hrmos.co
みなさん、こんにちは。品質改善推進ユニット クオリティエンジニアリンググループの平野です。 2020年4月に新卒で入社し、現在はセキュリティ/テスト自動化に関する推進、支援などを中心に取り組んでいます。 私事ではありますが、所属するグループでの業務の性質などもありプロダクトをゼロからしっかりと作るという経験をしたことがありませんでした。 そんな私がLIFULLでの新卒エンジニア2年目研修【SET】を受講して何を得たかについて、研修の紹介と合わせて説明します。 目次 SETとは 開発サービス紹介 インフラ フロントエンド バックエンド 学び・反省点 学び 反省点 おわりに SETとは はじめに申し上げますと、ここでいうSETとは社内での造語で「Sophomore Engineers Training」の略です。 テストの自動化などを推進するエンジニアであるSET(Software Engineer in Test)とは全くの別物です。 LIFULLの「理想のエンジニア像」のひとつは、バックエンドからフロントまで一通りこなせるWebアプリケーションエンジニアです。 しかし、業務で触れるスコープが限られているケースが多く幅広く業務を行う機会を得られない、という課題もありました。 そのような背景から生まれたのがこの研修であり、開始から7年ほど行われています。 以下が研修の目的です。 サービスをスクラッチから開発する過程を通してサービスを動かすために必要な要素を学ぶ 今まで触れる機会の少なかった分野を経験する機会を作り出す 研修では数人一組のチームでサービスをゼロから創り上げることが課題として与えられ、参加者は普段の業務から離れ集中的に取り組みます。 開発サービス紹介 今年の研修では私たちを含め計3チームおりましたが、私たちはQuoraを模したQ&Aサービスを開発しました。 トップページ Q&Aサービスを選んだ理由はいくつかありますが、一番の理由は設計が比較的容易かつ認証やデータベースなどWebアプリケーション開発で必要不可欠な技術に触れられるからです。 jp.quora.com 開発は大まかに以下の3つに分けて行い、私はその中でもバックエンドを主に担当しました。 なお、チームメンバーそれぞれが未経験の分野を担当しています。 インフラ(AWSを利用) フロントエンド(Vue.js) バックエンド(Go+Gin+GORM) インフラ 開発環境と本番環境の2種類を用意し、それぞれをAWSの提供するIaC(Infrastructure as Code)サービスであるAWS CloudFormationでコード化しました。 開発環境 本番環境 フロントエンド Vue.jsを用いてSPAに対応させたことにより、質問や回答追加ページ、一覧表示ページをシームレスに遷移できます。 バックエンド(APIサーバ)へのPOSTリクエストは、JSON形式でデータが送信されます。 バックエンド APIサーバを構築し、フロントエンドから指定したURL(質問追加、回答一覧表示など)にリクエストが来た際にJSON形式でデータを返却するようにしました。その際にDBを操作するORMとしてGORMを利用しています。 以下は回答一覧表示の返却値サンプルですが、 results の中に回答IDや回答内容、質問に紐づく回答IDなどを配列として入れることで一括返却ができるようにしています。 { "results": [ { "user_id": 15, "question_id": 6, "question_title": "Vue.jsが分かりません", "question_body": "おすすめの学習方法はありますか?", "question_rate": 2, "answer_ids": [ 10 ], "n_answers": 1, "answer_id": 10, "comment": "ますは公式ドキュメントを読みましょう", "answer_rate": 3, "user": { "user_id": 15, "user_name": "homes-kun" } }, { .... } ] } 学び・反省点 学び 個人としては、研修を通して3つのノウハウを得ることができました。 API設計の基礎 アーキテクチャを意識した開発スキル DB設計・操作の知識 1つ目のAPI設計の基礎について、私自身APIの概要や良し悪しは把握していたものの実際に設計したことはありませんでした。 普段の業務でもこれまで触れることのなかった箇所にしっかりと触れることができ、大きな学びとなりました。 2つ目のアーキテクチャを意識した開発スキルについて、今回の開発では代表的なアーキテクチャの一つであるMVCを採用しました。 知識として基本的なことは知っていてもそれを利用した開発経験に乏しかった私にとって、実装は苦労したもののMVCの恩恵を身をもって享受できスキル向上につながりました。 3つ目のDB設計・操作の知識についても、座学で理解するだけでは得られないものを実践を通して得る良い機会となりました。 なお、チームメンバーからは以下のような声がありました。 ちゃんとしたフロントエンドの開発がはじめてだったので、学びになった(フロントエンド担当) デプロイを意識した本番環境構築ができた(インフラ担当) 反省点 個人としての反省点は以下の2つです。 つまずき調査する時間が研修期間の多くを占めてしまい、予定した箇所まで実装が完了しなかった フロントエンド側との連携がうまくできなかった 1つ目について、分からないことを調査すること自体は自身の学びにつながります。 一方で、調査に時間を使いすぎてしまい、そこでストップし続けてしまうのはよくありません。 今回は研修だったので期日までにすべて実装できなくても問題ありませんでしたが、実際の業務でそうはいきません。結果的に早めに相談した方がスムーズに進むということは多々あるかと思いますので、調査と相談のバランスをうまく取りながら今後の業務をしていきたいと強く感じました。 2つ目について、開発期間中はフロントエンドとバックエンドそれぞれで開発しておりました。 ですので、つなぎ合わせての動作確認を自身の担当だったバックエンドの開発がある程度進んでからしようと考えていたところ、開発の遅れから研修最終日にすることとなってしまいました。 いざつなぎ合わせてみると、フロントエンドから送られてくるデータとバックエンド側で受け取るデータの形式が違うことによるエラーなど単体では発生しなかった問題が複数発生しました。そして、設計の重要性を痛感するとともにもっと早くから確認できていればと感じました。このことは、今後の業務に活かしていきたいと思います。 おわりに 今回の記事では、LIFULLでの新卒エンジニア2年目研修【SET】の説明とそこで得たことについて紹介いたしました。 2週間超も普段の業務から離れてスキルアップに充てる機会をいただけたのは大変ありがたく、結果として多くの学びを得ることができました。今後も研修で得たことを忘れず、業務や自己研鑽等でスキルをアップし続け、一人前のエンジニアを目指していきます。 最後になりますが、LIFULLでは一緒に働く仲間を募集しております。よろしければぜひこちらのページもご覧ください。 hrmos.co hrmos.co
LIFULL札幌開発拠点で働くエンジニアの村田です。 本エントリーは LIFULL Advent Calendar2021 、12月20日の記事になります。 私が働く札幌では、この時期雪が積もり始め寒さも厳しくなってきます。 東京本社から札幌に職場を移してから早3年が経ちましたが、ようやく札幌の寒さにも慣れてきた今日この頃です。 私が所属する部署は東京本社と札幌支社のエンジニアで構成された部署になり、社内では通称KEELチームと呼ばれています。 KEELとは、LIFULLグループ全体で利用することを目的としたKubernetesベースの内製のアプリケーション実行基盤です。 詳しくは以下のエントリーをご覧ください。 www.lifull.blog KEELはLIFULLのアプリケーションの開発・運用に必要な多くの機能を提供しています。 本エントリーでは、KEELが提供する監視基盤の一部であるURI毎のサクセスレート可視化機能のお話しをしたいと思います。 背景 LIFULLの主要サービスであるLIFULL HOME'Sは20年以上続いているサービスであり、非常に多くのコンテンツを保有したサービスに成長しています。 このモノリスな巨大アプリケーションを運用するにあたり、障害検知に関するとある問題が発生していました。 ことLIFULL HOME'Sにおいては、サイト全体に影響を及ぼすような、ある程度規模の大きい障害であればすぐに検知できるのですが 特定のコンテンツのみで障害が発生した場合、アプリケーション全体のサクセスレートが閾値まで押し下がらずアラート通知されないまま、その不具合が見過ごされてしまうといった事がありました。 URI毎のサクセスレートの開発 KEELチームが問題解決のアプローチとして導き出した答えは、URI毎にサクセスレートを確認できるダッシュボード機能の開発でした。 説明するよりもまずは現在運用されている実物の画面を見てもらう方がイメージがつきやすいと思います。 アプリケーションダッシュボード アプリケーションのダッシュボードの上部には、ステータスコード毎のRPSや、パフォーマンスのパーセンタイル値、その下には各URIのRPS・パフォーマンス・サクセスレートが表示されています。サクセスレートが正常であれば緑で表示されますが、低下している状態だと赤くハイライトされ一目でどのコンテンツに異常が起きているかわかるようになっています。 上記のイメージに表示されていませんが、CPUやメモリのリソースの状態やPod数の推移などのパネルも用意されており、アプリ開発者はこのダッシュボードを見るだけでアプリケーションの状態を把握することができます。アプリケーションによっては、アプリケーションサーバーのworker数なども確認することができます。 どのように実現したか URI毎のサクセスレートの可視化は、以下のようなステップで実現しています。 コンテナから出力されたアクセスログをFluentdにて集計しPrometheusにメトリクスを送信 ダッシュボードで使用するメトリクスをRecording Ruleで予め集計して用意しておく Grafanaのダッシュボードで集計したメトリクスを可視化する アラートルールを設定する まず、コンテナが出力したアプリケーションのアクセスログをFluentdにて集計し、Prometheusにメトリクスを送信しています。 ここで作成されるメトリクスはラベルにURIやHTTPメソッドを持ち、リクエストを識別できるようにしています。 メトリクスタイプはヒストグラムを利用しており、パフォーマンスをパーセンタイル値で表示するのに適した形になっています。 ここで注意したいのが、全てのURIをラベルに含んでしまうとカーディナリティが高くなりPrometheusのリソースを大量に消費してしまいます。 URIにIDといったパラメータが含まれている場合、それだけで無数のURIが生まれてしまいますので、そうならないように、アプリケーション毎に「ラベルとして登録できるURIのプレフィックスリスト」を定義しておき、集計対象となるURIを限定しています。 これで必要最低限のメトリクスの準備はできましたが、実際はこれをベースに様々なPromQL式を評価して目的とするデータを得る必要があります。PrometheusにはあらかじめPromQL式を評価しその結果を新たなメトリクスとして保持することができるRecording Ruleという機能があります。この機能を利用し、必要なデータを前もって計算しておくことで処理の高速化をはかっています。 メトリクスの可視化にはGrafanaを利用しています。 Grafanaのダッシュボードは、UIを利用して手動でパネルを組み合わせて構築することも可能ですが、アプリケーション毎に手動で構築するのは運用の面から考えても避けたいものです。 そこでGrafanaのダッシュボードをJsonnetでコード管理することにしました。 当初Jsonnetの用意は開発者が手動で行っていましたが、コードジェネレーターである keelctl が開発されてからは、上記のJsonnetファイルがコマンド一発で自動生成されるようになり、容易にダッシュボードの作成ができるようになりました。 最後はアラートの設定です。 閾値を調整したり、アラート発生時のRunbookを設定することがURIそれぞれで可能になりました。アラートルールも上記と同様にJsonnetで管理されており、keelctlを利用して開発者は容易にアラート設定を行うことができます。 何が変わったか アプリケーションのURI毎のサクセスレートが可視化された結果、どのような変化がLIFULLにもたらされたでしょうか? 一番大きく変わったのは、今まで見えてこなかった細かな不具合が見つかるようになりました。 URI毎にサクセスレートを計測できることになったことで、それぞれのURI単位でアラートを通知できるようになりました。 今まではサイト全体のサクセスレートが閾値を割らないとアラートが通知されず、細かい不具合は露呈されませんでしたが パス毎にアラートを飛ばすことができるようになったため、今まで見過ごされてきた多くの不具合を見つけることができました。 結果LIFULLのサービスの品質向上にかなり寄与できたと思います。 さらに、障害調査の点でも効率が上がる結果となりました。 従来、障害が発生した際に、まずは影響範囲を調査する必要がありましたが、ダッシュボードを確認するだけでアプリケーションのどの部分でエラーが発生しているのかすぐに把握できるようになっています。 URI毎のアラートにRunbookを設定できるようになっていますので、例えばDBにアクセスしているコンテンツでサクセスレートが低下しているなら、対応するURIのアラートにDBの障害を疑うといったヒントを記述しておくといったようなことができ、調査効率が飛躍的に向上しました。 slackに通知されるアラート 障害がどのURIで発生しているのかを明確にしたことで、障害対応のフローにも変化が起きました。 LIFULL HOME'Sは一つのアプリケーションに多くのコンテンツが含まれており、それを管轄する部署が多岐に渡ります。 仮に障害が発生した場合、どこの部分で障害が発生したかで対応する部署が変わってきます。 KEELチームが障害を検知したとしても、それをどこの部署に報告すれば良いか判断が難しい場合がありました。 そこでURIのパターンによって管轄部署を定義することで、障害発生時のエスカレーションを無駄なく行うことができるようになりました。 具体的には、障害が発生した際にBot経由でGitHubに障害チケットを作成し、その対象URIに対応した部署のラベルを自動で付与します。 開発者は自分が所属する部署のラベルが付与された障害チケットが発行されると、その障害の調査・解消にあたる、といった障害対応フローが確立されるようになりました。 自動起票されたissue まとめ LIFULLを支える監視基盤を構成する要素の一つであるURI毎のサクセスレート可視化について紹介させていただきました。 アプリケーションのURI毎に細かい情報を可視化することで、今まで見過ごされてきた思わぬ不具合を見つけることができ、障害発生時にも効率良い調査が可能になりました。 障害対応フローも整備され、今では細かい不具合も見逃さず検知し、うまく対応できるような体制が構築されました。 結果、URI毎のサクセスレート可視化を起点にBPRに繋がる形にまで発展させられたことを嬉しく思います。 KEELチームはLIFULLが掲げる「あらゆるLIFEを、FULLに。」の実現に向けて、LIFULLのものづくりを加速させるためのプラットフォームを革進し続けています。今回お話しさせていただいた機能以外の取り組みについては、以下のエントリー一覧をご覧ください。 www.lifull.blog 最後にLIFULLの採用について少し触れさせてください。 LIFULLでは、「あらゆるLIFEを、FULLに。」に実現を目指して共に働いていただける仲間を募集しています。 カジュアル面談という形で、まずは気軽にお話をさせていただく、ということも可能ですので、ご興味がある方は以下のページをご覧ください。 hrmos.co hrmos.co
こんにちは!Ltech運営チームの井上です。今回は2021年12月15日(水)に開催した「Kubernetesを用いたアプリケーション実行基盤の取り組み」についてレポートします。 lifull.connpass.com Ltechとは Ltech(エルテック)とは、LIFULLがお送りする、技術欲をFULLにするイベントです。特定の技術に偏らず、様々な技術の話を展開していく予定です。 LIFULLの全社アプリケーション実行基盤 KEEL について LIFULLではKubernetesベースのアプリケーション実行基盤を内製しており、KEELと呼んでいます。KEELは社内ですでに3年の本番環境での運用実績があり、LIFULL HOME'Sの大部分はKEEL上で稼働しています。 LIFULL HOME'Sの全トラフィックの約9割がこのKEEL上で稼働しているアプリケーションにより処理されています。 そんなLIFULL内製PaaSであるKEELがなぜ生まれたのか、そしてどのような課題を解決しようとしているのかについてのお話です。 LIFULLの全社アプリケーション実行基盤 KEEL について from LIFULL Co., Ltd. www.slideshare.net KEELができる以前のLIFULLでは、 マイクロサービス化を推進しており、たくさんのアプリケーションが稼働していました。マイクロサービス化を進めていくことによって開発効率の向上に成功した一方で、監視やデプロイの仕組みの「車輪の再発明」が頻発するなど、新たな課題が顕在化していました。これらの課題を解決するために、インフラストラクチャの中央集権化を決意したのがKEELの始まりでした。 KEELはすでに開発者の負担を軽減する多くの便利な機能を有していますが、更に開発効率の向上を実現する機能を追加するため、KEELチームでは開発者へのヒアリングなども都度行い、追加する機能の選定や優先度付けを行なっています。 私もLIFULLの開発者の1人として、今後の機能追加が楽しみだと改めて感じる発表でした! Kubernetesセキュリティの歩き方 LIFULLではマルチテナントのKubernetesクラスタを運用しています。様々なアプリケーションが1つのクラスタに混在する中で、OPA GatekeeperやConftest を用いて、セキュアなKubernetesクラスタを実現している方法についてのお話でした。 Kubernetesセキュリティの歩き方 from LIFULL Co., Ltd. www.slideshare.net 以前のKEELでは、不適切な設定や悪意のある設定を含むマニフェストがデプロイ可能な状態になっていました。また、マニフェストのチェックを人力で行なっていたため、チェックのコストも少なくありませんし、見落としの可能性をゼロにできていませんでした。 セキュリティについては情報の流れがとても早く、開発者全員が全てを理解することはとても困難ですよね。GitHub Actions で Pull Request ごとにマニフェストのチェックを自動化することで、チェックのコストがほぼ lint の実行時間だけになり、また見落としのリスクをゼロにすることができました。開発者が感じる不安の大部分を解消することができていて、私もLIFULLの開発者の一人としてその恩恵を享受することができています。 Kubernetesクラスタバージョンアップを支える技術 LIFULLのKubernetesクラスタでは、安全にバージョンアップを行うためにKubernetesクラスタ構築とE2Eテストの自動化を行っています。またAdmission Webhookを利用し後方互換を保ちながらバージョンアップを行う仕組みも導入しています。これらの自動化の手法についてのお話でした。 Kubernetesクラスタバージョンアップを支える技術 from LIFULL Co., Ltd. www.slideshare.net アプリケーション開発において切っても切れないのがバージョンアップ。このような運用作業はミスが許されない為、頻繁に行うことを避けがちになってしまいます。またメンバー入れ替えでの作業手順の引継ぎなどがうまくいかず、苦労するケースは少なくないですよね。 作業手順のスクリプト化によってとにかく手作業をなくし、誰でも低コスト高頻度でバージョンアップ作業ができるようにすることは、安全なアプリケーション運用をしていく中では、Kubernetesクラスタ以外にも必要不可欠なことだと思います。自動テストも含めた自動アップデートの仕組みを作って、健全なサービス運用を更に進めていきたいと感じさせられる発表でした! まとめ 今回はLIFULLの内製アプリケーション実行基盤であるKEELについて、3名のエンジニアに発表いただきました。KEELについてはチームメンバーが随時 LIFULL Creators Blog にて情報を発信しています。興味を持っていただいた方にはぜひ1度ご覧いただきたい記事ばかりになっています! www.lifull.blog Ltechでは、LIFULLのエンジニアが中心になって皆様の技術欲を満たすよう実例を交えた勉強会を開催しています。今後も Ltech を積極的に開催していきますので、ぜひ気になった方は、connpass で LIFULL のメンバー登録をよろしくお願いします! lifull.connpass.com また、LIFULLでは今回紹介したアプリケーション実行基盤に関わるものを含め、数多くの職種の仲間を募集しています。 よろしければこちらのページもご覧ください。 hrmos.co hrmos.co
テクノロジー本部の相馬です。好きな Web API は Window.requestAnimationFrame() です。 私が現在所属しているグループでは、弊社のメイン事業である LIFULL HOME'S における開発効率の改善などを行っています。 私はフロントエンドの開発環境の改善などを主に担当しております。 今回は、LIFULL HOME'S の JavaScript 開発環境のビルドを、esbuild を使ってビルドしたところ、当社比で 55 倍高速になった事例について紹介いたします。 目次 サマリ Before/After はじめに 従来の開発環境について 開発環境のインスタンススペック不十分問題 npm run dev 遅すぎる問題 esbuild とは? 開発中大変だったところ/ちょっとハックしたところ esbuild に当時 watch option がなかった トップレベル this のスコープ問題 UMD ライクで実行環境毎に global object を判断するライブラリのコードが壊れる おわりに サマリ 本改修以前、バンドラー には Rollup を使い、transpiler は IE11 むけに設定 本改修時点で 401 本のバンドルファイル を作成(歴史的経緯) 本改修以前、 npm run dev コマンドから全てのバンドルの warmup が終わるまで 220sec(m4.4xlarge) 使用メモリ 3.7GB/process 本改修以後、 npm run dev コマンドから esbuild で全てのバンドルの warmup が終わるまで 4sec(m4.4xlarge) 使用メモリ 685MB/process Before/After Before After バンドラー Rollup esbuild time 220 sec 🐢 4 sec 🚀 memory 3.7 GB 685 MB はじめに LIFULL HOME'S は弊社でもっとも開発が盛んなアプリケーション(Repository)です。 Commit 数や Contributor 数は弊社でもっとも多く、また開発の歴史も比較的に長い(10 年)部類に入ります。 これまでも「フロントエンドの開発環境の改善」という文脈で、何度か記事を書いているので、お時間ある際に読んでいただけると喜びます、私が。 9 年を超えて開発が続く LIFULL HOME'S の Web フロントエンド開発環境の改善 - LIFULL Creators Blog Node.js で Twig のプリプロセッサーを作って言語の機能拡張をしてみた話 - LIFULL Creators Blog 従来の開発環境について 以前の記事で解説させていただいた「近代化」により、フロントエンドにもそれなりにモダンな開発環境が整いました。 近代化を行って全てがハッピーエンドだったかというとそうではなく、新しいモノを導入することで部分的に不都合が生じている箇所もありました。 開発環境のインスタンススペック不十分問題 npm run dev 遅すぎる問題 開発環境のインスタンススペック不十分問題 現在 LIFULL HOME'S の開発環境は「一つの開発サーバに個人の開発マシンから ssh して開発する」という方式をとっているため、高価な処理を行うようなプロセスが開発環境で必要な場合、開発マシン上では「 ログインユーザ(開発中のユーザ)*高価な処理 」だけ該当マシン上でリソースが必要になってしまいます。 Rollup を導入することで、JS の依存関係が明確になり様々なツールの利用が可能になった反面、当然バンドルや minify といった比較的に高価な操作が必要になってしまいました。 それまでのインスタンスタイプでは不十分で、インスタンスタイプの変更を余儀なくされたことが記憶にある限りで 2,3 回あります。 npm run dev 遅すぎる問題 それまでは歴史的経緯により 401 本のバンドルファイルを直列で作成 していたため、220sec(m4.4xlarge) ほど warmup に時間がかかっており、開発時の問題の種となっていました。 JavaScript(Node.js) はご存知の通りシングルスレッドの実行モデルであるため、こういった AST をトラバースしたり文字列の置換など、高価な計算処理を苦手とします。 The Node.js Event Lvop, Timers, and process.nextTick() | Node.js Node.js だけで高価な計算を処理したい場合、 jest-worker などで worker-thread を駆使してパラレルで実行することで実時間の短縮などが可能です。 Rollup にも JS API が存在しているので、やろうと思えばできそうですが、シンプルにそこまでやっていませんでした。 そんなことを思っている中、JS バンドル界を揺るがす期待の新星として esbuild が颯爽と登場しました。 初期から動向を見守り続け、プロダクションでいけそうなことを目視で確認したので、esbuild にトライしてみようと奮い立ちました。 esbuild とは? Figma の CTO である Evan 氏が作成した、Go 製の JS バンドラーです。JS といっていますが、デフォルト(特に設定不要)で TypeScript のトランスパイル/バンドルも、 tsconfig.json をよしなに解釈し、実行してくれます。 esbuild - An extremely fast JavaScript bundler An extremely fast JavaScript bundler ↑ と評されている通り、既存の JS バンドラー(webpack/rollup/parcel)と比べてベンチマークのスコアで 10-100 倍ほど高速です。 Snowpack や Vite といったモダンなバンドラーにも採用されているバンドラーで、非常に高速であることで知られています。 ネタバレ(というかすでに上でも書いてるのでバレか怪しいですが)になりますが、当社比でも Rollup から esbuild への移行で 55 倍程度高速 になりました。 なぜこんな速度が出せているのかというと、簡単にまとめると並行処理とメモリ効率が高度に配慮された設計でフルスクラッチで記述されたライブラリだからという感じです。 例えば、JS のバンドラーはコードの parser/generator は 3rd party のライブラリに依存しており、また transpiler や minifier もそれぞれ別のライブラリがプラグインとして機能を追加で提供している形が多いと思います。 それぞれのライブラリはそれぞれの主たる目的があり、全てのライブラリがパフォーマンスを最優先としているわけではありません。 esbuild は read/parse/traverse/compile/minify/generate 全ての機能を備えているため、ライブラリ間の I/O 調整のためだけな不要なデータ構造のコピーや多重に AST を捜査するオーバーヘッドなどを極力抑えることで、その圧倒的なパフォーマンスを実現しています。 詳しく知りたい方は下記リンク先の記事をご覧ください。より詳細をご確認いただけます。 Why is esbuild fast? - esbuild FAQ また、esbuild は ES6(ES2015) 以降のコードしか生成できないという特徴があります。モダンな構文のみをサポートすることで、速度を保っているという側面もあります。よって IE 対応などが必須な場合 esbuild は利用できません。(バンドル後のコードを再度 Babel にかけるなどの対応は可能ですが、esbuild 単体での機能完遂はできないという意味です。) Lowering for ES5? · Issue #297 · evanw/esbuild LIFULL HOME'S では依然として IE11 をサポートしています。ですが開発環境では、開発の時は開発者はみんなモダンなブラウザを使っているはずだということを担保に、とりあえず開発環境にだけ入れてみようということで、作業に取り掛かることにしました。 開発中大変だったところ/ちょっとハックしたところ esbuild に当時 watch option がなかった 作業を開始したタイミングでは、esbuild はバンドラーとしてはそこまで多くの機能を持っていませんでした。CLI や JS API からワンショットでバンドルできるだけでもありがたかったのですが、ファイルの変更差分を監視し、変更があったタイミングで再度 build が走る、いわゆる watch モードが存在しなかったので、この辺は chokidar などで watch モードをラップするような処理を書いて満足して PR を温めていたところ、公式から watch オプションが登場したのでこのコードは日の目を見ることがなくて安堵しています。 トップレベル this のスコープ問題 esbuild はその名の通り ESM(ECMAScript Module) 向けのモジュールバンドラーであるため、context 関連で patch をあてる必要がありました。 ESM ではトップレベル(global context)の this は undefined と解釈されます。 そのため、esbuild も当然同じ振る舞いをします。 Bug: global this is optimized to void 0, which will lead to runtime errors. · Issue #1225 · evanw/esbuild しかし、古くから動いてる我々のコードは ESM を前提としておらず、一部のファイルでは以下の例のようにトップレベルの this が window であることを前提にしたコードが含まれていることがわかりました。 ( function (win) { // do something } )( this ); こういったコードが軒並み undefined になってしまい、そのままでは動かないコードが多くありました。 そこで トップレベルの context を window で bind する関数を injection するプラグイン を書きました。 esbuild - Plugins プラグインのコードの肝となる箇所を一部抜粋しますが、こんな感じで必要なファイルに対して const banner = "(function () { " ; const footer = " \n }).bind(window)();" ; // ........... // なんやかんやあって // ........... build.onLoad( { filter: /.*/ } , async (args) => { const path = args.path; const fileBody = await fsp.readFile(path, "utf-8" ); if (!needWindowCtxWrap(fileBody, path)) { return { contents: fileBody, loader: "js" , } ; } const contents = `$ { banner } $ { fileBody } $ { footer } `; return { contents, loader: "js" , } ; } ); このプラグインを挟むことで、先程のコードは ( function () { ( function (win) { // do something } )( this ); } .bind( window )()); となり、これによって「プラグイン 適応前にトップレベルであった context」は window であることが確定します。これによって暗黙(?)の変換は行われず、期待通り window を解釈できるようになりました。 また、一応 esbuild にも Rollup でいうところの context オプション のような --define というオプションがあり、これによって this の値を書き換えられそうなのですが、同時は this に window を指定することはできませんでした。 これに関して、issue で起票しており、現在は window の指定ができるようになっているそうですが、こちらは指定せず上記のプラグインを引き続き利用しています。 [feat] optional global context setting in ESM #1361 UMD ライクで実行環境毎に global object を判断するライブラリのコードが壊れる LIFULL HOME'S のコード群の中のライブラリには、歴史的な理由で npm からではなく内部的にソースコードを抱えているものもいくつか存在しており、その中には UMD ライクな形式の宣言が多くありました。 UMD は、実行環境によってモジュールをどのようにエクスポートするかをユニーバサルに決定する機構です。 決定ロジックに exports 変数の存在確認が含まれており、もし存在する場合は Node 環境だと解釈されてしまいます。 私たちの扱いたいコードはブラウザ向けのコードだったのですが、esbuild でバンドルする際に挿入されるコードに exports 変数が含まれているため、誤って解釈されるという問題が発生しました。 これについても プラグイン によって解消済みで、dummy の引数をトップレベル IIFE に対して付与することで擬似的に全スコープにおいてそれらの変数が undefined となるべく(つまり window が正しく判断されるべく)対応しました。 const banner = "(function (module, exports, require) { " ; const footer = " \n }).bind(window)();" ; このように exports の変数が存在する場合、esbuild としては exports オブジェクトを injection することができず、名前の衝突を避けることができます。 LIFULL HOME'S のコードは全てブラウザでの実行が期待されているため、このように別環境で悪さをしそうな変数は軒並み強制的に全スコープで undefined とすることでことなきを得ています。 おわりに 速度とパフォーマンスは圧倒的に正義であることを esbuild で再認識させてもらいました。 esbuild は プラグイン の拡張性も高く、Rollup など既存のバンドラーで複雑なビルドを組んだ経験があり、バンドラーの特性や特有の挙動などに知見がある場合、ドキュメントを読めばこちらも難なく利用できると思います。 幸い、LIFULL HOME'S の既存の JS ビルドはそこまで複雑ではなかったので、今回は比較的シンプルに収まりましたが、プロジェクトによってはプラグインなどいくつか用意する必要があるかもしれませんが、その労力に見合うだけの見返りが得られると思いますので、esbuild、おすすめです! 最後に、LIFULL では一緒に働く仲間を募集しています。よろしければこちらも合わせてご覧ください。 【エンジニア】募集求人一覧 | 株式会社 LIFULL 【エンジニア】カジュアル面談 | 株式会社 LIFULL
みなさんこんにちは。 品質改善推進ユニットQAグループでQAエンジニアをしている飯泉です。 今回は技術的な話からちょっと離れているのですが、 社内向けのサービスを広めるために工夫した話をしたいと思います。 新しいツール導入やアイデア浸透で苦労した経験がある方には面白い話かもしれません。 お時間があれば是非読んでみてください。 結論 『FEARLESS CHANGE アジャイルに効く アイデアを組織に広めるための48パターン』を参考にいくつかアプローチを行った結果、サービスの利用・相談が増えました。 新しいサービスを作る時は、計画時からどう広めるか・使ってもらうようにするか考えるべきであることが今回得られた教訓です。 QAグループが展開するサービス QAグループではLIFULLが展開するプロダクトの品質を向上させることを目的に社内の開発・企画メンバー向けに様々なサービスを提供しています。 他の記事でも紹介していますので興味があれば読んでみてください。 本番障害からテストのヒントを抽出して活用する - LIFULL Creators Blog 新卒エンジニアのテストワークショップではテストを考えられるようになってもらっている - LIFULL Creators Blog プロジェクトに直接的に関わらないQAのアプローチ - LIFULL Creators Blog LIFULLのQAの取り組みについて - LIFULL Creators Blog 新しいサービスをなかなか使ってもらえない 皆さんも、新しいツールの導入やアイデアの浸透が中々進まずに苦労した経験はありませんか? QAグループでも、色々考えて新しいサービスを作って社内へ公開・告知するのですが、最初は全然使ってもらえません。 この課題はQAグループの長年の悩みで、最近も新しくサービスを作りましたが、作って間も無い頃は依頼が来なくて困っていました。 サービスを浸透させる方法を考えた チームメンバーからの提案で、アイデアや方法論を組織に広めるアプローチが書かれた本 『FEARLESS CHANGE アジャイルに効く アイデアを組織に広めるための48パターン』 を参考に、QAグループが展開するサービスに適したパターンをピックアップしてから具体的なアイデアを考えました。 工夫した結果 実行して一番効果があったのは、「質問フォームを設けてそこで気軽に相談を投稿できるようにする」でした。 気軽な相談・質問が切っ掛けでサービスを利用してくれる機会が増えたのかもしれません。 ただ宣伝するだけでは無く、サービスの利用シーンや条件を相談・質問できる場があるとイメージがつきやすくなり、 サービスの利用に繋がるということがわかりました。
検索エンジンチームの寺井です。21卒新卒エンジニアです。 気づけば入社から半年、本配属からは約4ヶ月が経過して、入社後最初の半期が終了しました。 ちょうど節目のいい機会なので、主に配属されてから今までやってきたことを振り返りつつ、使用した技術やもっと事前に勉強しておけば良かったことなどを書いていこうかなと思います。 今後エンジニアとして入社を考えているみなさんや、初心者エンジニアのお仲間さんがちょっと気づきを得られる記事を目指します。 ※とは言いつつ今回はテクニカルな話はほとんど出てきませんのでゆるい読み物として読んでいただけたらと思います。 入社までの話 学生時代は認知心理学の分野に強化学習を取り入れた研究をやっていました。 当時のエンジニア的な能力はPythonを利用したシミュレーションやデータ解析を研究で扱っていたのと、競技プログラミングを少しやっていた(緑)くらいで、何もできないというわけではないけど…でもコード書くのは楽しい!!という感じでした。 また、Webアプリの開発経験はほとんどありませんでした。やばいですね。 (LIFULLの新卒エンジニアは約1ヶ月半の研修で全員が基礎の基礎から学んでWebアプリを作って発表するという鬼カリキュラムになっているので未経験でもばっちり学べて安心です!) 配属後にやってきたこと そんなエンジニア超初心者の私ですが、新卒エンジニア研修を無事修了して5月末に検索エンジンチームへ配属されました。今までやってきた仕事の内容は主に以下の通りです。 検索エンジンSolr周りの機能の改善 内部機能で使われるコンポーネントのバージョンアップ 障害が発生しづらくなるような仕組みの追加 Solrの新バージョンの検証 変更箇所の調査 新バージョンで動作やパフォーマンスに問題ないかをテスト 弊社サービスの「LIFULL HOME'S」のメイン機能である物件検索は全文検索エンジンのSolrを利用しています。検索エンジンチームではユーザーの皆様のより良い物件検索や検索体験の向上を目指して、Solrを最新のバージョンに保ったり、Solr関連の機能を使いやすい形にメンテナンスすることなどに日々取り組んでいます。 業務で使用した技術をいくつか挙げると、 Solr: オープンソースの全文検索エンジンです AWS関連: 様々なリソースを活用してSolrの構築から自動化まであらゆることに活用しています mitamae: サーバをプロビジョニング(初期設定みたいなこと)するのに使います goss: YAMLでテストを記述してサーバ構築のテストをすることができます Node.js: AWS上のLambdaの中身を記述しています mocha: JS用のテストフレームワークで自動テストに使われます 細かく挙げるとキリがないのですが、この辺りのものは使用しました。 入社するまでにこれらを利用した経験はほとんどありませんでしたので業務中に苦しみながら学びました。人は痛みを伴うとしっかりと記憶に刻まれるんだなと実感しました(先輩エンジニアのみなさんに手取り足取り教えていただき、毎日大変お世話になっております)。 やっておいた方が良かったと思ったこと AWSに触れておくこと 真っ先に思いついたのがこれです。先ほど使用した技術をいくつか挙げましたが、その中でも特にやっておくべきだったなと感じています。 理由としては、AWSは独自の用語がたくさん出てきて謎が謎を呼ぶ状態になるので、0→1の部分をしっかりと押さえていない状態でいきなりサービス運用に携わろうとしても迷子になってしまうからです。 そんな0→1の部分を自分のペースでしっかりと押さえるためにはもちろん実際に触って何か作ってみることが一番いい経験になると思うのですが、そうじゃなくてもAWSにあるサービスについて理解しようとしてみるだけでも最初の一歩としては十分だと思います。 事前にざっくりとサービスの概要を知っているだけでも、配属されてからEC2…?CloudFormationって何…?何もわからないわ…って泣いちゃうことは減ることでしょう。また、ざっくりと知っていれば頼れる先輩エンジニアのみなさんに質問する時にも有利です(何がわからないのかがわからない問題を低減)。 その入門としておすすめしたいのがAWSが毎月無料で開催(2021年9月現在)している「AWSome Day Online Conference」です。 aws.amazon.com 約3時間で、全く知識がない状態からある程度手広くAWSのサービスを学ぶことができます。 ちょっとサービスを触ったことがある初学者の方にも、知識を整理し直せるという意味でおすすめです。 私は配属当初、業務の一環として上長から許可をいただいて参加をしてきました。 確かに実際に業務で使われている運用のレベルと比較すると非常に初歩の内容しか取り上げられていないのですが、それでもどこから手をつけていいか分からないほどの初心者だった私には学びの多い経験でした。 ちなみに同期エンジニアや別企業へ入った学生時代の友人たちも同じような苦しみを味わっているみたいなので、今までAWSを避けてきたエンジニア志望の方々は早めにアクションを起こすのがおすすめです。スタートダッシュで差をつけよう。 一人で何か動くものを作ってみること 業務では基本的なプログラミングスキルに加え、通信に関する知識やサーバ構築に関すること、さらにLinuxに関する知識やその他諸々が基礎的な知識として使われます。 新卒として関わらせてもらっている業務では、知識レベルとしては基本情報技術者で出てくる程度の内容のものが多いのですが、実際に自分で手を動かしてシステムを触ったことがほとんどないと、暗記しただけの知識だけでは実務で活用していくのはなかなか難しいです。 それらを手っ取り早く身に付ける方法としては自分で何か1つ、動くシステムを作成することが良いのではないかと思います。 私はエンジニア研修中に初めて一人でアプリを作り上げましたが、想像以上に基本的な情報スキルを幅広く要求されることが印象的でした。 大変なことも多かったのですが得られるものも多く、エンジニアとしてのレベルが一段階上がる非常に良い経験になりました。 しかし同時に、時間のある学生の内にもっと開発経験をしておけば良かったとも思いました。 なので、一人で動くものを作った経験があるということは大きなアドバンテージになると保証します。ぜひ取り組んでいただきたいです。スタートダッシュで差をつけよう。 逆にやっていてよかったと思ったこと 1つのプログラミング言語についてある程度複雑なコードを書いた経験があったこと プログラミング言語は使い回しが効くとはよく言われますが本当にその通りでした。 言語によって多少の表記の違いや実装概念の違いはありますが、逆に言えばそこだけ押さえてしまえばあとは汎用的なプログラミングスキルで何とか食らいつくことができました(万事解決できたわけではないです)。 また、これも大体の企業で共通していると思いますが、業務で利用するコードはかなり莫大な量です。 1つの機能を見るだけで何百行も追ったりするといったことが多々あるので、やはりある程度は複雑なコードを書いた経験が欲しいところです。 とはいえあまり身構える必要もないと思っていて、長めのコードを見たときに強烈な嫌悪感を抱くことがないくらいに、プログラミングに触れて慣れていればいいんじゃないかと思っています。 そのためにもなるべく日常的にプログラミングに触れる機会を増やしていくことが大事だと思います。 例えば、ゲーム感覚で楽しめる競技プログラミングなど、楽しみつつ手軽にプログラミングを触れる環境を自分に合わせて構築していくことがおすすめです。 コードを書くのは楽しいという感覚が身についているのは、エンジニアにとってかなり心の拠り所となります。 メモを取る癖があったこと 私は正直記憶力がそこまで良い方ではないので、昔から聞いた内容やその時考えていることなどをなるべくメモに書き出すようにしていました。 仕事を始めてからは毎日の業務に加え、新しい知識のインプットなど扱う情報の量や覚えることが増えたので、このメモを取る癖がかなり役に立っています。 もちろん言われたことを忘れないようにする目的もありますが、定期的に見直したりまとめ直したりすることでより知識を定着することができていると感じます。 また、雑多に書き残すのに加えて、部署に配属されてからは毎日やったことやその時悩んでいる点、その日の気分を一言で などを盛り込んだ日報を書くようになりました。 今回の記事を書く際にも日報を読み返しつつこんなこともやったなぁと思い出しながら執筆しています。 自分がやってきたことを時系列順に書き残すことで、成長を実感してモチベーションにつなげることもできますし、当時の記述をレベルアップした今の自分が読むと思いがけない新しい発見があったりもして楽しいです。 メモを取る癖をつけてみるのと、日報あるいは日記のように日付順に見られる形式で自分の文章を残すこと、おすすめなのでぜひやってみてください。 おわりに 冒頭にも書いた通り、気づくと半期が終わってあっという間の社会人0.5年目でした。 でも振り返ってみると中身の詰まった濃い毎日で、充実した日々を過ごしています(今回書ききれていない仕事の話やチーム内外での勉強会の話、チームビルディングでマインクラフトをやったりLIFULL独自のイベントがあったりと盛り沢山でした!)。 業務もわからないことや難しい内容が多く苦しいことも多々ありますが、それでも難しいことに挑戦をすることは楽しいですし、それが達成できた時の嬉しさは他の何にも勝ると思っています。 今後も精進して強いエンジニアを目指しつつ、ユーザーのみなさまにより良いプロダクトをお届けできるように頑張っていきたいと思います。 最後になりますが、LIFULLでは一緒に働いていただける仲間を募集しています。カジュアル面談もやっていますので、よろしければこちらもご覧ください。 hrmos.co hrmos.co
こんにちは。プロダクトエンジニアリング部の島村です。 今回は部署の垣根を超えてサービスの改修を進める「横断案件」の取り組みについて紹介します。 プロダクトエンジニアリング部の課題 プロダクトエンジニアリング部はLIFULL HOME'Sの開発を担当するエンジニアが集まった部署です。 LIFULL HOME'Sは「不動産・住宅情報の総合サービス」であり、多数の領域を扱っているため、それぞれの領域を扱うグループがそれぞれ存在します。 そのため、下記のような課題が存在していました。 各グループは基本的にそれぞれの担当領域の開発に専念するため、担当外領域に影響が及ぶ改修は調整コスト、学習コストが高い 部署ごとに個別の開発が行われるため、同じような仕組みを各部署で開発しているケースがあり、効率が悪い 多数の領域を扱う巨大なサービスであるがゆえ、対応優先度が上がらずに放置された技術的負債が存在する 上記のようにプロダクトエンジニアリング部では、領域をまたぐ横断的な改修を進めにくいという課題がありました。 また、同じ仕組みを実装しているケースなど、技術的負債になりそうな課題についても早めに吸い上げ、対応可否含めて検討をする必要がありました。 横断案件WG 上記課題に対する対策のため、プロダクトエンジニアリング部では横断案件WGを発足しました。 このWGでの活動は主に下記です。 メンバーに起票してもらった「横断案件」の実施に関する協議 実施中の「横断案件」の進捗確認 メンバーからは上がっていないが、WGとして「横断案件」として扱うべき課題に関する協議 横断案件WGでは各部署からメンバーを出し合い、横断案件を効率的に実施することを目的に活動しています。 横断案件の進め方 各部署のメンバーには、 「こんな取り組みを横断案件で進めてほしい!」 「これ技術的負債になりそう・・」 といった案件を事前にシートに記入してもらいます。 WGでは上記のシートを確認し、横断案件としての実施を協議します。 実施が決まった案件については、下記のステップで実施に向けて進めます。 実施することを決めた案件についてはWG内から担当者をアサイン その担当者が案件を具体化し、実際に案件を実施するメンバーを公募 実施するメンバーが無事見つかれば案件を進めてもらい、完了までWGがサポート 案件はメンバーに起票してもらったものがメインではありますが、WG内で「横断案件」として対応すべき重点項目を決め、その項目に関する案件を起票して進めることもあります。 活動の成果について 上記のような仕組みで今年1年活動し、下記のような実施結果となっています。 起票された案件:32件 実施した案件:23件 実施完了した案件:11件 例えば下記のような案件がこの1年で実施されました。 プロダクトごとに別々のリソースを参照していた祝日情報をAPI化して共通化 独自管理されていたアプリケーションを全社アプリケーション実行基盤「KEEL」に載せ替え 複数領域のプロダクトで問題となっていたキャッシュ機構のバグの解消 この1年は同じようなデータを参照しているのに個別管理になっているようなものを共通化する、特定領域の問題でないため、組織的問題で優先度が上がっていなかった負債/バグの解消が案件としては多かったです。 横断案件の課題と展望 この「横断案件」の取り組みですが、現状ではまだまだ上手くいっているとは言えない仕組みだとは思います。 案件を進める上での主な課題は下記です。 起票される案件がまだまだ少ない 案件を実施する実施担当者が見つからない 自部署案件との兼ね合いでどうしても優先度が劣後してしまう 特に実施担当者が見つからない問題は解決が難しく、担当者が決まらない場合には担当部署を決めた上で、部門長にアサインを委ねる等の試行錯誤もしてみたのですが、なかなか状況の改善には至っていない状況です。 仕組み的な面での難しさもあるため、全体的な仕組みの改善、インセンティブの強化等含め、今後改善を進めて参ります。 一方、しっかりと成果が出た案件も複数存在しており、特に若手のエンジニアが積極的に案件に挑戦してくれる姿は大変心強かったです。 このような案件をロールモデルとしつつ、彼らの利他の心に甘えすぎないような仕組みに仕上げ、LIFULL HOME'Sの開発に根付いた取り組みにしていければと思っています。 まとめ 今回は部署の垣根を超えてサービスの改修を進める「横断案件」について紹介しました。 横断案件WGで扱っている、調整コストの高い案件の対応や技術的負債への対応については、頭を悩ませる企業も多いのではないでしょうか。 LIFULLでは組織として優先度の高い課題は、専門チームの発足等で対応を進めているものの、どうしてもこぼれ落ちる課題は出てくるので、そうした課題にできるだけボトムアップで解決してゆければと考えています。 LIFULLではこのような課題解決にも興味がある、一緒に働く仲間を募集しています。よろしければこちらも合わせてご覧ください。 hrmos.co hrmos.co
LIFULLのプロダクトエンジニアリング部でエンジニアリングマネージャーをやっております野澤と申します。 もともとはゲーム用途で使われることの多かったDiscordですが、最近はIT系のイベントでは必ずといっていいほど使われるようになりました。LIFULLでも昨年導入され、各部署でDiscordを使って日々コミュニケーションを取っているようです。 コロナ禍になる前はオフィスで偶然出会った人と話せたり、連絡せずともふらっと会いたい人に会いに行って話せたりしていました。ところが、リモートワークだとどうしても自分が所属するプロジェクトやチームの人としかコミュニケーションしなくなりがちではないでしょうか。 そこで、私が所属するプロダクトエンジニアリング部ではDiscordを使った「ハンガーフライト」というコミュニケーション施策を講じてみたので少しだけご紹介できればと思います。 ハンガーフライト Okänd fotograf "Montering / underhåll av flygplan S 6 samt B 4 på CVM, Centrala verkstäderna Malmslätt. Arbete i hangar." Public Domain Mark 1.0 https://digitaltmuseum.se/021016832015/montering-underhall-av-flygplan-s-6-samt-b-4-pa-cvm-centrala-verkstaderna 飛行機を格納する倉庫のことをハンガーフライトと呼ぶそうです。 ところが、飛行機のパイロットたちが天候悪化などの理由で空を飛べないときに、ハンガーフライトに集まって飛行技術のコツなどについて雑談したり、情報交換をしていたことから、この行為自体をハンガーフライトと呼ぶようになったようです。 (詳しくは市谷聡啓さんの『 カイゼン・ジャーニー 』をご参照ください) コロナ禍の影響でリモートワークが中心になり、自部署以外のメンバーと話す機会が激減したため、ちょっとでも話す機会を作ろうと思ったのがきっかけで、私が所属する部署でもZOOMを使ってハンガーフライトを始めてみました。毎週決まった時間に自部署以外のメンバー含む数名でおしゃべりをしていました。 コロナ禍が長期化し、リモートワークが常態化しました。そのことによって、会社でも他部署の人と交流する機会が減ったことに対して課題意識が強まってきました。そこで、自分たちの周りでしかやっていなかったハンガーフライトを、エンジニア組織全体でやってみてはどうだろうと思い立ち、実施することにしました。 協力してくれる仲間とともに開催する時間を決め、Discordサーバーにエンジニア専用のチャンネルを作りました。最初はそんなに参加者も多くないだろうから、ざっくり「仕事について」「キャリアについて」「雑談」という3つのボイスチャンネルを作りました。ちょっとした仕事の息抜きや、誰かと喋りたいときに、興味のあるテーマのチャンネルに入っておしゃべりする、という感じです。 始めてみてどうだったか 8月の上旬から開始し、今のところ火曜日の16:00-17:00と、金曜日の13:00-14:00の週2回で開催しています。最初は数名しか参加してくれなかったものの、最近では大体10名くらいの方が参加してくれます。 普段あまり一緒に仕事をしないような人や、初めて話す人など、部署関係なくいろんな人が集まります。特に新卒や中途採用で入社された方々に喜ばれている印象です(まだ人数自体は少ないですが)。話を聞くと、入社してから直接会って話したことのある人は数名だし、自部署以外の社員と話すこともほとんどなかったからということです。 話の内容としては、やはり仕事のこと、最近の会社での出来事、キャリア、技術系のニュースなどについての話が盛り上がります。「好きな言語について話そう」とか最近参加したセミナーの感想、LIFULLに入社した理由や今後どういったことをやっていきたいか、などなど様々な話題で盛り上がります。 ただし、初めての人同士だとなかなか話すのも大変です。なるべく私も週一回は参加し、ファシリテーションをして、いろんな人の話が聞けるように努めています。そのうち特定のファシリテーターがいなくてもその場で自然に話せるようになるといいなと思っています。 ハンガーフライト以外の時間でも時々Discordに来て誰かが喋っているのを見かけました。弊社のCTOもちょくちょく顔を出しているようで、普段CTOと話す機会が無いようなメンバーも、CTOと直接話すことができているようです。 結果として、今まで相談しにくかった部署への相談がしやすくなったり、他の部署で実施しているコミュニケーション施策を別の部署でもマネしてみたりと、少しずつ業務改善にもつながってきています。最近施行されたセキュリティ施策の担当者が参加してくれて、みんなでその施策の内容について質問したり、解説してもらったりと予想していなかったような情報の共有が行われており、参加してくれた方のリピート率は非常に高いです。 今後の課題と展望 とはいっても、なかなか参加人数が増えません。まずは粘り強くエンジニア全員が入っているチャットルームで開催30分前にアナウンスをしたり、参加してくれた人にも身の回りの方を連れて一緒に参加してみて欲しい旨を伝え続けています。最近は多くの社内エンジニアが参加するイベントでも関連して告知をしたりしています。 弱くなってしまった社員同士のつながりを修復しようとしているので時間がかかるのは当たり前です。焦らず、諦めず、根気強くやっていくことが大事かなと思っています。ご参考になれば幸いです。 LIFULLでは共に成長できるような仲間を募っています。 よろしければこちらのページもご覧ください。 hrmos.co hrmos.co
こんにちは。テクノロジー本部基盤開発ユニット改善推進グループの花岡です。 改善推進グループでは技術的負債解消の一環としてLIFULL HOME'S で使用されているDBエンジンプロジェクトに取り組んでいます。 今回はDBエンジン移行プロジェクトにおけるSQL改修漏れを防ぐための取り組みについて紹介したいと思います。 DBエンジン移行プロジェクトの概要 LIFULLでは運用コストの削減や開発効率やパフォーマンス改善のためにOracle DatabaseからPostgreSQLへの移行を進めています。 両DBのデータを同期させつつアプリケーションのSQL改修を進めています。 ※ 以下ではOracle DatabaseをOracle, PostgreSQLをPostgresと呼びます。 プロジェクトの内容については以下の弊社ブログでも紹介されていますのでそちらもご覧いただければと思います。 www.LIFULL.blog www.lifull.blog DBエンジン移行の進め方について https://www.LIFULL.blog/entry/2021/03/24/151447 でも紹介されていますが、本プロジェクトでは以下のようにDBエンジン移行を進めています。現在は参照系SQLの移行を進めている最中です。 スキーマオブジェクトとアプリケーションの依存関係の洗い出し Postgresに移行先のテーブルを作成(AWS SCTを使用 OracleとPostgresのデータ同期(AWS DMSを使用 参照系SQLを移行 上記のブログでも言及されていますが、移行が必要なSQLの調査が不十分なことによるアプリケーションの障害が課題の一つとなっていました。 そこで今回は抜け漏れ検知のためのDBアクセス監視のしくみを構築することで移行漏れを早く検知できる様にしました。 DBアクセス監視のしくみ DBアクセス監視のしくみは以下の通りです。 Oracleにアクセスがあった際に検知してChatWorkへ送信して開発者が確認できる様にします。 Oracleの対象テーブルに監査ログ(以下Audit Log)を設定してアクセス状況をログ出力する。 ⬇︎ CloudWatch Logsのサブスクリプションフィルタで監視対象スキーマオブジェクトへのアクセスを検知してLambdaを起動する。監視対象スキーマオブジェクトはJSONで管理する。 ⬇︎ Lambdaでデータを整形してChatWorkへ送信する。 ⬇︎ ChatWorkでアクセス情報を表示する。 全体の構成は以下の通りです。 ここからはそれぞれの設定や処理内容についてもう少し詳細に説明していきたいと思います。 Oracle OracleへのSQLの実行を検知するために、Audit Logを出力する設定をします。 監査ログにはアクセス対象のスキーマオブジェクトや実行されたSQLの種類を出力できます。 対象テーブルの参照系SQLがすべてPostgres用に改修された段階で、以下のコマンドで対象テーブルに監査ログの設定を追加します。 AUDIT SELECT ON <対象テーブル>; この設定により監査ログが出力される様になります。 ログの内容についての詳しい説明は省きますが、このログでどのスキーマオブジェクトがアクセスされているかやスキーマオブジェクトに対してどのような操作があったのかを調査できます。 今回は監査ログからアクセスされたスキーマオブジェクト名を抽出します。 監査ログについて詳しく知りたい方はこちらも参照してください。 docs.oracle.com OracleでAudit Logを出力できる様にした後、Amazon RDS側でCloudWatchにログを出力する設定をすれば監査ログの設定は完了です。 CloudWatch Logs Audit Logを記録しているCloudWatchLogsのロググループにサブスクリプションフィルタをつけて、ロググループへのログの追加をトリガにしてLambdaを実行する様にします。 これで、ログのデータをLabmdaで受け取ることも可能になります。 サブスクリプションフィルタは以下のコマンドで追加します。 $ aws logs put-subscription-filter \ --log-group-name $LOGGROUP_NAME \ --filter-name ora2pos-notification-filter --filter-pattern "$FILTER_PATTERN" \ --destination-arn arn:aws:lambda:ap-northeast-1:$AWS_ACCOUNT:function:$FUNCTION_NAME \ --profile $AWS_PROFILE --region ap-northeast-1 サブスクリプションフィルタのfilter patternは監視対象のスキーマオブジェクトリストから抽出して作成します。 監視対象のスキーマオブジェクトリストは以下のようにJSONで管理しています。 { " objects ": [ { " schema ":" HOMES ", " object ":" object1 " } , { " schema ":" HOMES ", " object ":" object2 " } , { " schema ":" HOMES ", " object ":" object3 " } , ] } サブスクリプションフィルタでLambdaに送信するデータはBase64でエンコードされ、gzip形式に圧縮されます。 複合化したデータは以下のようになります。 { " awslogs ": { " data ": { " owner ": " xxxx ", " logGroup ": " xxxx ", " logStream ": " xxxx ", " subscriptionFilters ": [ " xxxx " ] , " messageType ": " DATA_MESSAGE ", " logEvents ": [ { " id ": " xxxx ", " timestamp ": 000000000000, " message ": " Audit Logの内容 " } , ] } } } サブスクリプションフィルタの設定方法について詳しく知りたい方はこちらも参照してください。 docs.aws.amazon.com Lambda Lambda側で受け取ったログから必要な情報を抽出して整形し、ChatWorkへ送信します。 Lambdaはgzip形式で圧縮されたデータを受け取るため、以下のようにしてログ情報を取得します。 const zlib = require( 'zlib' ); var payload = Buffer.from( event .awslogs.data, 'base64' ); zlib.gunzip(payload, function (error,result) { if (error) { console.log(error); } else { result = JSON.parse(result.toString( 'ascii' )); const logs = result.logEvents; const logGroup = result.logGroup; const logStream = result.logStream; ... SQLでアクセスされたスキーマオブジェクトを監視対象のスキーマオブジェクトリストと照合します。このリストはサブスクリプションフィルタのfilter patternに使用したのと同じ物を使用します。 照合が終わったら受け取ったデータを以下の形式に整形します。 これでアクセスされたスキーマオブジェクトを確認し、ログのURLから原因調査できる様にします。 oracle異常アクセスログ検知 異常アクセスがあるオブジェクト一覧: ... ... ... 以下のLogStreamを参照してください: <ログのURL> データを整形したらChatwork APIでChatworkに通知メッセージを送信します。 APIの形式は以下の通りです。 URL https://api.chatwork.com/v2/rooms/$CHATWORK_ROOM_ID/messages ヘッダ 'X-ChatWorkToken': $CHATWORK_TOKEN ChatWork APIについては、以下のドキュメントを参照ください。 developer.chatwork.com ChatWork ChatWorkでAPIを受け取ると以下のようなメッセージが表示されます。 モザイクで隠していますが、アクセスのあったスキーマオブジェクトとログのURLが表示される様になっています。 これでOracleのアクセスをChatWorkで確認するできるようになりました。 移行漏れ検出時の運用フロー ChatWorkでアクセスを検知した場合は以下のような運用フローで問題を把握して対処します。 ChatWorkでSQLの移行漏れを検出する。 ⬇︎ 監査ログの詳細(ログが発生した原因)を調査する。 ユーザーやアクセス対象のオブジェクト、どのサーバからアクセスされているか?SQLの種類は何か?を把握する。SQLの種類は SQL Command Codes を参考にする ⬇︎ ログ発生の原因や状況に応じて緊急度を判断して対応する。 原因・状況 緊急度 対応内容 手作業によるSQL実行など、移行漏れが原因でない場合 対応の必要なし - 移行漏れだが障害につながらない場合 緊急度低 ・対象のSQLを確認 ・移行計画を立て、対象のSQLを移行する ・移行後、ログが出なくなった場合はOKとする 移行もれによる障害が発生した場合(もしくは発生する可能性が高い場合)  緊急度高 ・至急で障害対応を実施する ・障害対応後、ログが出なくなった場合はOKとする これでSQLの移行漏れがあった場合に早く検知して対処するしくみを作り上げることができました。 まとめ 今回はCloudWatchやLambdaを使ったSQL検知システムについて紹介しました。 DBエンジン移行を行っている方にとって少しでもお役に立てれば幸いです。 まだDBエンジン移行プロジェクトは道半ばですが、一つ一つの課題に対して解決方法を模索しつつ進めています。 ここで紹介したのはその取り組みの一つですが、 これから発信できる様な取り組みがあれば引き続きブログで紹介していきたいと思います。ぜひ楽しみにしてください。 LIFULLではともに成長できるような仲間を募っています。 よろしければこちらのページもご覧ください。 hrmos.co hrmos.co
検索エンジンチームの加藤宏脩です。 突然ですが、自分たちが行う施策をもっと雑談に近いところから決められたらいいなと思ったことはないですか? 私は気軽に話せる環境のほうがいろいろな意見が出やすく、またそういった話し合いから生まれるアイディアが意外と良いものだったりするのかなと考えています。 検索エンジンチームでは、「検索」というテーマを軸にラフな議論を行いその中から次にやる施策を決めるという方法を半年ほど続けています。 その結果、 現状のLIFULL HOME'Sが利用している検索エンジンの構成を前提にするのではなく試験的なユーザー体験をシームレスに提供・検証していく検索エンジンの環境を用意するプロジェクトができました。 LIFULLには「クリエイターの日」というイノベーションを創造するため、通常業務を離れ新たな技術や手法に取り組むための仕組みがあり、 こういった仕組みを利用して検索エンジンの開発をできるようにしたいというアイディアからこのプロジェクトが生まれました。 これ以外にもいくつかプロジェクトが徐々に進行し始めています。 今回はこの施策の作り方について紹介します。 気軽な会話から施策を作るとはどのようなことか? この活動は大きく以下の4ステップに分かれています。 思いついた課題や解決策をメンバーに共有するステップ テーマに対して課題や解決策を話し合うステップ 課題と解決をまとめて、できそうな施策を見つけるステップ 調査、設計、実装をするステップ 1. 思いついた課題や解決策をメンバーに共有するステップ ここではふと思いついたアイディアを忘れないようにメンバーに共有します 施策のアイディアについて話し合うためのslackのチャンネルがあります。 MTG中や休憩時間に思いついたアイディアや、約に立ちそうな情報をそのチャンネルに記入しています。 記入したアイディアや、情報は次の「テーマに対して課題や解決策を話し合うステップ」で話題の1つとして活用します。 2. テーマに対して課題や解決策を話し合うステップ ここではアイディアの発散をします 週に一度全員で話し合うMTGを設定します。 毎週一人のメンバーが「検索」を軸にしたテーマを用意します。(テーマを持ち寄るメンバーはローテーション) テーマ発表後、そのテーマについて課題や解決策を各メンバーが感じたままに挙げていきます 私達の場合、slackにテーマを記入して、スレッドにコメントで書いていますが、もう少しやりやすい方法もあると思います。 このステップを全メンバーがテーマを持ってくるまで繰り返します。(5人のメンバーであれば5週かけて行う) 3. 課題と解決をまとめて、できそうな施策を見つけるステップ ここではアイディアの収束を行います。 全員がテーマを出し終えた次の週のMTGで全員が出した課題、解決策をグルーピングします。 LIFULLではコンフルエンスを使っており、そこに今までのアイディアのまとめページを追加します。 各メンバーが、まとめから実施したい施策を選びとります 4. 施策としてすすめるステップ ここではアイディアを実現させていきます 他のプロジェクトと同様に製品要求仕様書(PRD)を作って調査、設計、実装を行います。 MTGの最後の時間に、進捗を共有します。 似ているところをやっていれば柔軟にメンバーが合流したり、途中で分裂したりします。 なぜこの取組みを始めたか もともと検索エンジンチームは運用に時間を取られてしまい、利用者への価値提供に時間を使えていないという課題がありました。 これを解決するために、運用方法の変更、自動化、手順化を行っていました。 運用コストを下げた結果、利用者への価値提供に時間を割けるようになってきたという経緯があります。 この方法で進めてよかったこと LIFULLの知識が増えました 私のようにLIFULLでの経験の浅いメンバーにとっては、今まで通りの施策の仕方だけでは得られない知見が溜まっていきました(部署外で運用しているデータやサイト、検証方法等) チームメンバーが考えている課題感を知ることができました 開発者がSolrの開発に苦手意識を持っており、実現しなかった事業案があることがわかりました(調査の際の副産物ですが) 開発者に対するSolrの勉強会の開催を積極的に行うようになり、社内に対してもいい影響を与えています この方法で進めて課題だと感じているところ ジャストアイディアで話しているため、データがなくてこれ以上話が進まないというときがあります MTG中に社内の担当の方に聞いて解決することもありますが、どうしても限界があります。 まとめ 今回は検索エンジンチームでの取り組みについて紹介しました。 雑談のような気軽な会話の中で出てきた考えは今までとは違う視点からの新しいアイディアを生み出す機会にもなります。 また、ボトムアップに施策を作ることは会社のことを知り、考えるきっかけにもなります。 ちなみにLIFULLではこういうコミュニケーションから新たなことを始める取り組みを色々なところで行っています。 例えば月に一度、部内の他チームと雑談をするという機会があり、このような雑談から新たな目的や構想を誘発すると考えております。 カジュアル面談もやっていますので、LIFULLやLIFULLの取り組みに興味がありましたらぜひお話しましょう! ここまで読んでいただきありがとうございました。 hrmos.co
こんにちは。 プロダクトエンジニアリング部の吉永です。 本日はLIFULL HOME'S におけるLINEを活用した施策「 LINEで新着物件通知を受け取る 」について機能改善を行ったプロセスとリリース内容について紹介したいと思います。 プロジェクトメンバーが以前投稿した下記記事も一緒にご覧いただけると幸いです。 www.lifull.blog www.lifull.blog アジェンダ LINEで新着物件通知を受け取るとは どのような機能改善を行ったのか 機能改善に至るまでのプロセス まとめ LINEで新着物件通知を受け取るとは LIFULL HOME'SにおけるLINE活用 #1 LINEで新着物件通知を受け取る の再掲にはなりますが、改めて本機能についてご紹介いたします。 その名前のとおり、 毎日決まった時間に希望に沿った新着物件をLINEでお知らせしてくれる機能 になります。 新着物件を受取るまでのフローを簡易的にあらわすと下記のようになります。 LIFULL HOME'Sで任意の条件で物件を検索する。 検索結果画面から「LINEで受取る」ボタンを押す。 LIFULL HOME'S公式LINEアカウントを友達登録する。 翌日以降に、登録した検索条件に合致した新着物件情報がLINEで通知されるようになる。 ※LINEで受取るまでの詳細なフローについては こちらのページ をご参照ください。 また、開発に携わったエンジニアとして、個人的に新着物件通知機能で良いなと思っている点を紹介すると下記3点になります。 希望条件を決めて、新着情報受け取り設定をしておけば、 自分からサイトを見に行かなくても 新着物件情報を通知してくれる。 通知情報である程度の概要情報(賃料、所在地、最寄り駅からの徒歩分数など)が把握できるので、 本当に気になった物件のみ をサイトに見に行けば良い。 普段から 使い慣れているLINEアプリ でこれらの有益な情報を受取れる。 この機能を開発すると決まった際に、ちょうど自分も住み替えを検討していたので、素直に「 この機能使いたいな、欲しいな 」と思ったことを覚えています。 どのような機能改善を行ったのか 新着情報受け取り設定の延長機能 初期リリースでは新着情報受け取り設定を行ってから、30日後には自動で新着情報の配信が停止される仕様でした。 よって、31日目以降も新着情報を受け取る為には、物件の検索画面上からもう一度新着情報受け取り設定を行う必要がありました。 今回自動で停止する仕様はそのままなのですが、自動で配信が停止されていることに気づいていない方もいるであろうということから、29日目に「明日で配信が停止しますが、引き続き配信を受取りますか?」というお知らせとともに、LINEトーク画面上から手軽に延長を行えるボタンを配信し、 利用者が簡単に配信受け取りを延長できる機能 を追加しました。 同一物件情報を繰り返し送らないようにする 初期リリースでは、配信受け取り設定後、登録した希望条件で検索した結果から1週間以内に登録された物件情報の新着順からLINEで新着通知メッセージを送っていましたが、希望条件によっては検索結果が少なく、毎日同じような情報が送られてきてしまう方も一部いました。 今回はこちらの改善をする為に、一度通知した物件情報は繰り返し送らないようにして、 LINEで通知が来た時の「また同じ情報か...」というがっかり体験を無くす ようにしました。 同じ日に同じ建物の部屋情報を送らないようにする 上記の改良と合わせ、なるべく受け取る情報が有益なものになるように、 同じ建物の部屋情報を同一日には通知しない ようにしました。 物件によっては同じ建物の別々の部屋が同時に空き部屋として登録されることもあり、初期リリースでは通知されるメッセージの物件1件目が101号室、2件目が201号室などのように同じ建物の別の部屋が並ぶことがあったので、なるべく多くの物件情報を新着情報として届けたいとのことから、この機能を追加しました。 物件情報で表示する情報を追加 初期リリースでは、物件名、所在地、最寄り駅までの徒歩分数、賃料、物件画像などをLINEで通知していました。 今回の改修で、物件が持っているこだわり条件(2階以上、角部屋など)合致情報を元に、 こだわり条件をカテゴライズした情報を表示 するようにしました。 例えば、新着通知としてお知らせする物件が「2階以上」もしくは「南向き」などのこだわり条件と合致している場合には 日当たりを良くしたい というカテゴリ情報をテキストで、物件情報と合わせて表示するようにしました。 登録した希望条件に加えて、こだわり条件を分かりやすく伝える情報も同時に見せることで、物件を決める際の判断材料の一つになればいいなと思い、この機能を追加しました。 機能改善に至るまでのプロセス 続いて、上記の機能を実際に開発するまでにどのようなプロセスを経たのかについて紹介したいと思います。 初期リリース直後 まずは初期リリース後に開発に携わったステークホルダーでKPTを用いた振り返り会を開催しました。 振り返り会の内容は、 プロジェクト進行において良かったこと、悪かったこと、次回トライしてみたいことに着目しての振り返り会 だったので、具体的に機能改善したいことについての言及はあまりありませんでした。 初期リリースから1か月後 このプロジェクトに直接的に関わった、関わっていないに限らず、プランナー、デザイナー、エンジニアでオンラインホワイトボードツールを用いての機能改善案のブレストを実施しました。 ブレストでは改修にかかる工数や、実現可能性についての考慮はせず、ひとまず各々が、 こんな風になった方が良いよなと思う機能 を次々と上げ、それぞれのアイディアをグルーピングするところまでを行いました。 初期リリースから1か月半後 ブレストで出たアイディアの具体的な実現案や、UX向上の為の改善案などをプランナーとエンジニアで出しあい、おおよその改修イメージを皆で共有しました。 また、開発工数についてもチーム内のエンジニア間で認識を統一したかったので、プランニングポーカーを行い、 おおよその開発工数イメージの共有 をプランナーとエンジニア間で行いました。 初期リリースから2か月後 プランナー側で、 利用者アンケートでいただいたご意見やプランニングポーカーで算出されたポイントを元に改修案の優先度付け を行い、今回の機能改修を実施しました。 まとめ 今回は「LINEで新着物件通知を受け取る」機能と、LIFULL内でどのような流れで機能改善を行っているのかについて紹介させていただきました。 機能改善するまでのプロセスについてはプロジェクトやチーム毎に異なるので、この方法がLIFULLのスタンダードというわけではないのですが、社内で一つだけ共通していることがあるとすれば、 我々は職種に関わらず常に利用者目線で物事を捉え、自分ごと化して考えるようにしている という点だと思います。 LIFULLの経営理念である 常に革進することで、より多くの人々が心からの「安心」と「喜び」を得られる社会の仕組みを創る を実現する為に、私たちはLINEに限らずあらゆるチャネルを通じて感動体験を創出できるように日々プロダクト改善に取り組んでいます! 「LINEで新着物件通知を受け取る」機能についても、今後更に機能改良していくつもりですので、アップデート情報を楽しみにお待ちいただけますと幸いです。 最後に、LIFULLでは共に成長できるような仲間を募っています。 よろしければこちらのページもご覧ください。 hrmos.co hrmos.co