![見出し画像](https://assets.st-note.com/production/uploads/images/150002221/rectangle_large_type_2_62ad8ac6c74dac12bb093d880ee8f16f.png?width=1200)
「アーキテクチャを突き詰める Online Conference」登壇しました【イベントレポート】
こんにちは、deep-rain.comです。
2024年5月に行われたFindy主催の「アーキテクチャを突き詰める Online Conference」に、「パフォーマンス改善を支えるアーキテクチャの役割とは?」というタイトルで登壇させて頂きました。登壇時に話しきれなかった内容も含め、出来るだけ詳細にお話させて頂きます。
自己紹介
2024年2月入社以来、CTO室というチームで日々全社規模の技術課題と向き合っています。
CTO室は、これまでオープンロジの10年という歴史を経る中で、積み上がってきた技術負債や、生産性向上などの課題に向き合うために発足したチームであり、高い専門性を持つメンバーが在籍しています。
今回は、オープンロジの業務の中核となる「引当処理」に関するパフォーマンス改善と、それを支える構造上の価値についてお話させていただきました。
登壇スライド
アーカイブ動画
※閲覧にはFindyへの登録が必要です
「引当処理」の概要
物流業界、特に倉庫内作業に詳しくない方のために、「引当処理」について簡単に説明します。
倉庫では、商品を搬入し保管する「入庫」と、商品を搬出する「出庫」という2つの大きな作業があります。「引当処理」は、この「出庫」に関する重要なプロセスの一つです。
引当処理は、荷主からの配送指示に基づいて、どの商品を・倉庫内のどこから・どれだけ出庫するかを決定するもので、倉庫内の担当者はこの情報をもとに出庫作業を行います。この処理が遅れると、出庫作業が進まず、倉庫作業者に無駄な待ち時間が発生してしまいます。
また、引当処理には複雑なロジックが含まれています。例えば、「賞味期限が近いものは出庫しない」「先に入庫したものから優先して出庫する」といったルールが存在します。
オープンロジにおける引当処理のコードは、長い歴史を経てこれらの複雑なルールが絡み合い、変更に多大なコストがかかる状況となっています。
パフォーマンス改善について
引当処理のパフォーマンスは非常に重要です。クエリのチューニングやメモ化などの改善策は、局所的であるためアーキテクチャを意識することなく実施できます。クエリチューニングとは、データベースへの問い合わせ(クエリ)を最適化して処理速度を向上させる手法です。一方、メモ化は計算結果を一時的に保存して再利用することで、不要な計算を省略する技術です。
これらの改善策は多くのパフォーマンス問題を解決しますが、それだけでは限界があります。クエリのチューニングやメモ化、計算量の削減などのポピュラーな解決策を全て実施した上で、さらに数十倍、数百倍のパフォーマンス改善が必要となった場合、大規模な変更が避けられません。
このときに重要なのがソフトウェア・アーキテクチャです。
構造の価値と重要性
ソフトウェア・アーキテクチャは、ソフトウェアの課題を解決するための手段のひとつです。それぞれのソフトウェアや組織、文脈によって、適切なアーキテクチャは異なるため、適切な目的を導き出すことが大切です。
今回の最終的な目的は数十倍、数百倍もの大幅なパフォーマンス改善ですが、そのパフォーマンス改善を実現するためには、ソフトウェアの保守性や変更容易性が必要不可欠となります。
また、先にも述べたとおり、引当は大変重要な処理です。これが停止してしまったら、企業として甚大な損害を出してしまうことに繋がります。そのためには、バグのないソフトウェアを安全にリリースすることも重要な視点です。
これらを踏まえると、重要なキーワードは以下に絞られます。
テスト容易性
保守性
変更容易性
リソースは常に有限ですから、きれいな構造を形成することよりも、諦めるべきところはしっかりと諦め、効率よく目的を実現できるような構造を重視しています。
ソフトウェア・アーキテクチャは誰のもの?
ソフトウェア・アーキテクチャは、優れたアーキテクトが構築し管理していく、というやり方もありますが、一方で、開発者組織全体のものである、とも解釈できます。
元々ソフトウェア・アーキテクチャは抽象的で難解、かつ明確な答えがない厄介なものです。そのため、アーキテクトがいくら優れた構造を構築しても、それが開発者全員に伝わらなければ、結果として変更容易性や保守性の向上などは期待できません。
構造の価値を意味のあるものにし続ける責任は、アーキテクトのみならず開発者組織全体で担うことも視野にいれる必要があります。数年後、アーキテクトが責任を持ち続けるのか、開発者組織全体が体現できるようになっているべきか、といった中長期的な展望を描くことも大切です。
アーキテクチャスタイル
ソフトウェア・アーキテクチャの元となるスタイルはいくつかあります。中でも、Eric Evansにより提唱されたDDD、あるいは、Robert C. Martinによって提唱されたClean Architectureが比較的有名ですよね。
これらのアーキテクチャスタイルは、チームとして高いレベルで取り組んでいくために多大な時間と労力が掛かります。
ひとつ例を挙げてみましょう。「エリック・エヴァンスのドメイン駆動設計」という本は500ページを超える大作であり、事前知識もそれなりに必要です。全てを読破するだけでもかなりの時間が必要な上、理解するためには更に読み返すなどの時間も必要になります。
DDDは設計のパターン集であり、必要な部分を抑えていけば良い、という考え方もできますが、それでも難解であることに変わりはなく、ある程度プログラミングに精通したエンジニアでさえ、理解するのに膨大な時間が掛かります。また、内容には抽象的な部分も多くあるため、人によって解釈にズレが生じることもあります。
目的ドリブン
アーキテクチャスタイルは多岐にわたり、それらは有用であるものの、運用する難易度は非常に高いことが伺えます。アーキテクチャはその殆どが抽象の領域であり、認識を揃えるのに大きな力が必要だからです。
概ね数人程度の、少人数のチームであれば成立しますが、数十人規模となってくると話は別です。構造の価値に責任を持つアーキテクトチームを組成し各チームに配属し、コードレビューやスキルの底上げを行うなどの仕組みを作り上げることも、場合によっては必要となってくるでしょう。
しかし、今回の目的は、引当処理という限られたドメインのパフォーマンス改善であるため、組織全体としてのソフトウェア・アーキテクチャを整えることにコストを掛けすぎるのは、趣旨に反しています。
そのため、今回は、既存のアーキテクチャスタイルに拘らず、何よりも目的をベースに置いたうえで、理解しやすく、かつ、シンプルな構造を目指しました。
依存と影響
ソフトウェア・アーキテクチャは、適切なモジュール分離と依存に注意を払って設計することが重要です。何がどの業務を体現し、それはどういった振る舞いを見せ、何に依存しているのか、をコード上で的確に表現する必要があります。
モジュールと依存が明確に整理されていれば、仮に機能に変更を加える場合であっても、変更対象と依存関係のみを確認すればよい、ということになります。また、モジュールが分離されていることで、テストの文脈もより明確になったり、モックやスタブの作成が容易になるなど、様々な利点があります。
先に述べた、重要なキーワードを引用します。
テスト容易性
保守性
変更容易性
依存と影響について強く意識することで、これらを効率的に改善することができそうです。
ORMとの兼ね合い
今回、大きな課題となったのは、LaravelというフレームワークのORMである、Eloquentでした。
純粋性を追い求めるのであれば、専用のドメインモデルを定義してORMと変換しあったりなども考えられますが、ある程度これをそのまま使ったり、wrapしたりして共存する方針に一旦落ち着きました。
というのも、ソフトウェア全体のアーキテクチャがORMを前提としたものになっており、部分的なドメインでの利用であっても混乱を招いてしまう懸念があります。また、変換におけるパフォーマンスの問題も無視できるものではないからです。
将来的に、これが課題となる可能性もありますが、そうならない可能性もあります。今回の目的を踏まえると、この課題が重要とはならないだろう、という判断です。実際のところ、適切な分離と依存の整理さえ出来ていれば、適宜変更を行うことはそう難しくありません。
未来への道しるべ
意図したかどうかにかかわらず、今回のアーキテクチャは今後に繋がる道しるべとなります。進め方などもそうですが、目的や設計思想をドキュメントなどに残しておくことも非常に重要です。
先にも述べた通り、ソフトウェア・アーキテクチャは非常に抽象的な事柄を含んでいます。
プログラムは「コードを読んだだけで瞬時に理解できる」ように書くことが理想ですが、ソフトウェア・アーキテクチャに関して言えば、万人がコードを読んだだけで瞬時に理解できることは殆どありません。
PHPとソフトウェア・アーキテクチャ
オープンロジでは、プログラミング言語としてPHPを採用しています。
ただ、PHPはいわゆる「テンプレート言語」で、レガシーである、というイメージをお持ちの方が多いのではないでしょうか。実際に触れてみるまでは私もその一人でした。
PHPは、もちろん最近のモダンなオブジェクト指向言語からすれば違和感を覚えることが多いですが、実際には、クラス、インターフェース、スコープなどの基本的な構文を兼ね備え、ソフトウェア・アーキテクチャを表現するには必要十分です。
感覚的にはJavaやTypeScriptにも似ており、色々と癖の強い部分はありつつも、アーキテクチャを構築したり表現する上で特に不便を感じるようなことはありません。
おわりに
お読み頂きありがとうございました。
アーキテクチャは答えのないものであり、どのような形でも成立してしまうため、目的から逆算して構造を設計すること、そして、設計思想を正しく伝え、適切に使えるようにしておくことが重要だと考えています。
今回の事例が、読者の皆様の参考になれば幸いです。
We are hiring!
オープンロジは比較的歴史も長く、このような技術的に難しい課題や、ビジネス上の課題が無数に存在します。
特に、昨今話題となっている物流における社会問題解決の一助になるべく、職種を問わず全力で奔走しています。
比較的抽象度の高い領域で仕事をすることも多く、俯瞰した視点を得たいITエンジニアにとって成長できるフィールドとなるのではないでしょうか。
事業拡大にむけてビジネス・エンジニア・コーポレート職、全ての職種で採用強化中です。
もしこの記事を読んでオープンロジに興味を持って下さった方は是非、カジュアルに話してみませんか?