システム設計/開発/マネジメントmemo

ある交流のお陰て、大規模インターネットシステム設計開発とマネジメントに関する経験と考え方をまとめてみる事にしました。
秘密保持のため、具体的なプロジェクト名や技術要素(ハードウェア、OS、開発言語、サーバーソフト及びミドルウェア、DB)は書きません。
なお、各プロジェクトのマネジメント手法やビジネスロジックがまちまちなので、ここでは抽象的概念だけに留めます。

インターネットビジネスに参加してから約20年経ちましたが、
特に2000年からずっと今の会社で仕事してきました。
会社の規模でいうと、エンジニアの数が当時3-40名程度から、2-3000名と成りました。
startupの気持ちで会社に入り、ここまで大きくなる事はまったく想像できませんでした。
サイトへのアクセス量も1日数千万PV程度から、数十億PV/日まで成長し、
静的なリソースとAPIを加えると、常に百億以上/日のアクセスあるはずです。
devopsから、多数プロジェクトのアーキテクチャー設計などを得て、
プロジェクトと部門マネジメントまで、ある程度の技術力と管理力の成長があると思われます。
2007-2008年頃は、自分が設計・開発・運用したシステムが一日1億超えるアクセスでも耐えれた事が自信に繋がった代表的な出来事です。
何より重要なのは、システム開発全工程を俯瞰できるようになり、
部分最適化より全体最適化思考、抽象思考ができるようになりました。

以下いつかの軸を中心にまとめてみたいと思います。
ソフトウェアエンジニアリング
アーキテクチャー
チームビルディング
マクロマネジメント
情報セキュリティとリスクマネジメント
これからチャンレンジしたいこと

1 まずはソフトウェアエンジニアリングの原則の適用。

大学での専攻が電子工学でコンピューターサイエンスではなかったため、アルゴリズム等はどっちかというと苦手の方です。
ですので仕事では、専門家の力を活用することになります。
たとえば08年頃にあるプロジェクトでアメリカ側のサイエンティストに機械学習のモデルを作って頂いた事があります。
エンジニアとして、論理モデルをシステムに反映して、サーバシステムの開発と同時に、
数年かけてパラメーターのチューニング、辞書の拡充、ナレージベースの成熟をやってきました。

ですので、エンジニアリング的には、限られた資源(物、金、人)の中で、
経営目標とスケジュールを達成させるために、
リクエメント管理、アーキテクチャー設計、進捗とリソース管理、開発プロセスと開発規約、
品質管理、運用管理などを総合的に実践する経験が欠かせません。
それから、中長期の技術戦略、古い技術負債の対応、新しい技術の選定、組織の調整などもソフトウェアエンジニアリングの一環です。

最近のプロジェクトでは、
アジャイル開発スタイルへの適応、スクラム管理手法の普及、
オブジェクト指向設計とプログラミングの浸透、
RESTFULなWebAPIとSOAによりサービス化と疎結合、
CI/CDによりバージョン管理・テスト・コンパイル・リンク・デプロィメントの自動化
などは当たり前になっています。

戻る

2 アーキテクチャーについて。

Webシステムなのでまずデータセンターの課題があります。
中小サービスであればアマゾンやGoogleやMSのクラウドサービスを利用する事ができますが、
大規模なシステムを前提なので、自社でインフラを運用する事がほとんどです。
ですので、データセンターについて、安全性、CCTV監視、拡張性、
365/24の障害対応体制、発電設備、UPSバッティリーの老化管理などがチェックポイントになります。

十数年前でしたら、システム障害が起きて、かつサーバにリモートアクセスできない場合、
深夜の3時にしてもタクシーでDCに行ってコンソールに繋いてメンテしないといけなかったが、
場合によってラックから故障となったサーバを外し、ハードウェアの交換もやりました。
今はDC事業をやってる子会社があるので大分対応が楽になりました。

ビジネス計画から数年後のユーザ数・アクセス数・トランザクション数予測を作り、
ネットワークの計画を立て、必要なルーター・LB・スイッチ・FWを用意します。
もちろん出口の帯域も大事だが、実はシステム内のトラフィックがもっと多いです。
フロンドエンド・マルチレイヤーのアプリケーション層・キャッシュ・分散データベース・
モニタリング・ログ・データマイニング・内部業務システム等のサブシステム間の通信量は実に巨大であります。
ですので内部用のネットワーク機材に特に注意する必要があります。

BCPも大事です。特に日本は地震の多い国ですので、複数DCが常識になります。
coloの間のネットワーク遅延は仕方ないので業務フローの精査が必要となります。
非同期処理とデータ一致性の両立が難しいですので。
ですので、coloを跨って通信するような設計をできるだけ避け、
サービスのローカル化を目指す事によって、
パフォーマンスの改善を計ります。

ソフトウェアアーキテクチャーについてです。
サブシステム間のstateless原則は、Roy Fieldingにより90年代前半からhttpの設計に適用してきました。
REST(Representational State Transfer)の思想があまり知れていないが、
実にこれはグローバル的なネットワークシステム設計の指針になります。
会社のWebAPI開発ガイドラインを作っていて定期的に技術者向けのセミナーを開いていますが、
SOAとRESTについての講義をやった時に、あまり堅苦しい内容せいで、
約半分の方が寝ていました。。
ただ、RESTの中のstateless、キャッシュ、リソース指向、レイヤー化、
統一インターフェース、マルチメディアスタイルなどの概念はそんなに難しくなく、
実際のシステム設計の適用も一般的に行われています。

今はモバイルインターネットの時代で、アプリ開発のために、
企画や技術者たちにとってシステムのインターフェースサービス化が当たり前の存在となりました。
数十年前に会社でAPI化を推進時の苦労を思い出すとまさに隔世の感があります。

EDGE層もしくはGateway層はシステムの安全性に直接に関わるものの、
ユーザ認証・TLS・ルーティング・ログ・キャッシュ・アクセスコントロールなどの機能があります。
(2007年頃に会社でWebAPI Gatewayの構想を発表しましたが異動のためあまり推進できませんでした。
今年の夏頃アマゾンが同名のサービスをAWSにてリリースされていて、
やはり彼らも同じニーズを理解していますね。)
Circuit-breaker、Fail-fast、Retry、Throttlingなどの技術用語が最近よく聞くようになりました。
実は08年のあるプロジェクトで我々がすでに実装していて、特許まで取っていました。

CDNは静的コンテンツに対してパフォーマンスとスケーラビリティの改善について言うまでもないです。

C10K問題解決のために、開発時にもシステムリソースを注意深く意識し、
それから運用時にチューニングが欠かせません。
たとえば、OSやサーバソフトウェア(apacheやmysqlなど)のネットワーク・メモリ・キャッシュサイズ・ファイルハンドルなどです。
経験上古いapache 1.xのpreforkとブロッキング型のソフトウェアでもいいパフォーマンスが得られます。
epollやkqueueやlibeventやnodejsのlibevなどのの多重ノンブロッキング I/O技術は十分成熟したと言っても、
運用時にきちんとシステムリソースのモニタリングを行う事が欠かせません。

大規模なシステムを開発する際に、機能が複雑かつ開発人員が多く、
ビジネスロジックを階層化する事で、複雑な計算を各レイヤーに分散させ、
開発効率の向上及びリソース(CPUやメモリなど)競争のボトルネック解消に努めます。
こういった実践は2000年からもすでに始まっています。
場合によって集中ステータス管理によりデータ一貫性問題を解決する必要があります。
ただほとんどの場合は一貫性が大きなボトルネックにはならずに、
ユーザも短い時間内のデータ同期の遅延も気づきません。
ですので弱一致性のシステムが多く存在しています。

大量データを処理する時に、sharding(shared nothing architecture)技術によってデータ水平分割し、
スケーラビリティを得られます。
こういった実践も2000年から一般的に行われてきました。
ユーザ数は無限に増えないので、ある程度設計時に予測が可能ですので、
実験したものの、動的なHashリング的な仕組みがほとんど必要がありません。

分散NoSQLデータベースを使用しても、ビジネスニーズによって高パフォーマンスを追求する場合は、
ステータスありの分散データベースも必要となります。
水平分割と垂直階層化後のサブシステムはマトリックスの一ユニットになります。
データアクセスのルールが明確であるため、最短ルールでのアクセスが望ましいですが、
運用が大変になります。
もしデータのバックアップとリストアが透明に行われているならシステムのデプロイメントがだいぶ楽になります。

以前担当したあるプロジェクトではまだ手動で管理していますが、スマートではありません。
現代のシステムなら、明確なPaaSとIaaS層があって、
アプリケーションレイヤーの担当者がビジネスロジックに集中できるならば、
開発とデプロイメントのスピードがすごく上がるでしょ。

CQRS(Command Query Responsibility Segregation)という用語を知ったのはつい最近の事ですが、
クエリと実施を分割する思想も2000年から適用してきて、
非同期メッセージ待ち行列でNoSQL DBのread/write分離を実現してきました。
CAP和BASEなどのWeb2.0時代の言葉についても、だいぶ昔から実践に使われていて、
イベントモデルとメッセージ行列をバリバリ使っていました。

分散トランザクションのステータス管理時に集中管理が必要について触れましたが、
このモデルはフェイルセーフとデータ複製にも役に立ちます。
ビッグデータのデータマイニング時にMQやメッセージバスを通してhadoopに転送も簡単に実現できます。

ソフトウェア開発の方向性は抽象化・自動化で、
OOD、OOP、UML、サービス化(IaaS, PaaS, BaaS, SaaS, FaaS...)、クラウドコンピューティング、
CI/CD、コンテナ化が普及しつづ、devops担当者がモデリングと自動デプロイメントにフォーカスにできます。
我々は今までOSカーネルの動きや大量UNIXコマンドとオプションやOSSのソースコードを勉強してきましたが、
今後こういった個人努力の必要性がどんどんうすくなっていくでしょ。

ムーアの法則はあと10年持つか持たないかの話はよく聞きます。
数十年間高速な進化もあって安いハードウェアを常に入手できましたが、
これからソフトウェア開発時はもっとCPU/メモリ/IOを工夫し、
アルゴリズムや並列計算を研究しないといけないと思われます。

戻る

3 チームビルディングについてです。
パフォーマンスの高い技術チームは自己管理・自己啓発とオープンコミュニケーションできる環境が欠かせません。

マネジャーとしては、まずオープンな協力体制できる技術チーム雰囲気作りに努めます。
チームメンバーが、
協調性を大事にし、自分の意見を自由に発言ができ、官僚主義にせず、
声の大きい人だけではなく、異なる意見に対しても誰でも安心にディスカッションを行い、
間違いがあっても犯人探ししないように、
などできるように、よく観察と介入を行います。
部門のスキルマップを作成し、誰が何が得意するかを可視化して、
教育の方針や全体のスキル向上に役に立ってます。

実践上心かけてる事は、
先入観や偏見を持たず、メンバーの優れた点を見るようにする、
寛容である、
焦らずにディテールをよく観察する、
結論を急がない、課題の本質を追求する、
手段を目的にしない、ゴールを失わないように定期的にチェックする、
実行力重視、見た目や表面的なパフォーマンス重視しない、
流行りの新技術を盲信しない、きちんと調整と検証とチューニングをした上で特徴特性をよく理解する、
ビジネスニーズとビジネス要件を熟知する
などあります。

地味かもしれないが、誠実かつ適応力の高いチーム作りが目標であります。

管理者としては、定期的にメンバーと1on1を実施し、
お互いの考え方を交流し、各種フィードバックをもらう事も大事です。
それから個人個人の個性を重視し、多様性を大事にします。
もちろん原則はちゃんと守らないといけないし、事なかれ主義しません。
たとえば技術選定時にきちんと選定基準を明確に定義し、ビジネスゴールとのバランスを注意よく扱う事です。
メンバーたちはこういった管理手法覚えてもらえ、
業務中に適用できるようになれば、あとは権限移譲で彼らの独立性発揮を支援するだけになります。

関係部署との協力関係について、エンジニア以外のステークホルダーとのコミュニケーションも欠かせないので、
経営者、PM、ビジネス開発、マーケット、営業、顧客サポート、広報、法務などの社内関係者、
および社外のパートナーを含め、良好な信頼関係を構築し、
お互いの交流を深めていく事がプロジェクト成功の重要要素であります。

技術チームの代表としては、できるだけ専門用語を使用しなくても、
ロジカルな説明によって技術者以外の関係者に対して、
必要な計画(リソース、金、日程など)と進捗を理解してもらえるように努力しないといけません。
それから、ビジネスニーズとビジネスロジックを深く理解した上で、
ハイレベルのシステム分析を行い、実現性評価、リソース計画、
スケジュール計画、リスクアセスメントなどのコンサルタント的な業務も大事です。

お喋りが苦手、政治手腕のない技術者としては、全然派閥政治に興味がなく、
ただ今までの業務実績に基づき、適宜な距離を置きながら、
全ての関係者と良好な信頼関係を作りたいと考えています。

プロジェクトマネジメントに関しては、基本的にスクラムによって管理していてます。
スクラムマスターがキモですから、採用面接の時に、将来のスクラムマスターになれそうな候補者を常に探しています。
ボトルネックやクリティカルパスを常に意識しながら二週間単位のスプリントが基本です。
タスクの粒度は、数日程度、機能単位にまとめらているケースが多いです。
詳細については、以前参加したスクラムセミナーに紹介した手法が多く採用しています。

なお、会議の進め方と組織開発型マネジメント研修に少し書いたように、
会議のファシリテーションは、発散と収束をバランスよく行うことが大事で、この数年間ずっと実践してきました。

戻る

4 今までやってきた部門(事業部)のマネジメント業務を纏めてみます。
具体的に、
・人員計画ー中長期なビジネス計画に基づきヒューマンリソースの増強と調整
・人事関連ー目標管理、業績評価、OJT、1on1、勤怠管理、個人成長計画、マネジメント手法トレニング
・財務ー予実管理(人員、ハードウェア・ソフトウェアなどの設備投資、書籍、教育、アウトソーシング、出張、交際費など)
・部門管理ービージョン、組織構成、リスクマネジメント、情報セキュリティ、ISMS、契約管理、プロジェクト優先順位
・各種会議体ー経営会議、定期会、年会
などあります。

雑務的な業務が多いようですが、一定的な規模まで成長した会社なので、仕方ないと思います。
ただ各分野において専門家がいるのでマクロ管理にフォーカスし、
個人個人の力とチームワークが発揮できるようにサポートするだけです。

戻る

5 情報セキュリティとリスクマネジメント
カンパニーのCISOとリスクマネジメント責任者を担当しているので、
守りと攻めのバランスの重要性は大変理解しています。
なお、技術負債も一つのリスクとしてきちんと管理しないといけないと思います。
技術負債の返済方法には、自分の考えをまとめています。

機密性Confidentiality、完全性Integrity、可用性Availability、すなわちCIA三要素。
システムの規模がどんなに大きく、ユーザ数がどうなに多く、技術がどんなに先進であって、
脆弱性のあるものは誰も使いません。
ですので情報セキュリティのCIAは全てのシステムの基礎であります。

DoS攻撃、ATP攻撃、個人情報流出、大規模システムダウンなどのインシデントを経験した身としては、
言うまでもありません。

ですので下記の対策が必須となります:
最小限原則に基づきアクセスコントロールポリシーと運用原則の確立;
重要データの暗号化によって漏洩と盗難リスクの低減;
平均修復時間MTTRや単一障害点SPOFなどをKPIにし継続にモニタリングと評価;
情報セキュリティ緊急対応体制CSIRTの構築;
リスクマネジメント体制の確立と推進;
セキュリティオペレーションセンターSOCを構築、システム及び情報機器の脆弱性を可視化と定期アップデート
など。

ISO27001 ISMS情報セキュリティマネジメントシステムはこの一連のプロセスに対して包括的な定義がありますが、
CISSP(Certified Information Systems Security Professional)認定資料にはもっと実践的な記述があります。
ISMSとCISSPのトレニング双方受けましたが大変勉強になりました。
今業務の中に、意識的にこういった知識を活用するようしています。

戻る

6 これからチャンレンジしたいこと
これからのシステムの構築、設計、開発、運用は、自動化とAI化になります。
技術要素としては、 CI/CD、コンテナ、マイクロサービス、クラウドネイティヴアーキテクチャー、機械学習などの流行りの言葉がありますが、
Google/Facebook/Amazon/Alibaba/Tencentなどの会社ではすでに確立し、成熟に運用されているものであります。
ですのでいち早く彼らに近づくように最新の技術トレンドを学び、業務に導入し、
開発と運用のコスト・効率を向上させていきたいところであります。

戻る
以上