受益者の価値最大化のために、データ指向のITサービス企画・設計・開発・実装をリードする
少子高齢化の進む日本社会で、企業の価値を向上させるためには、これまでと全く違ったユーザーとの接点を生み出していくことが必須であると考えています。IoT、ロボティクス、AI、DXなどさまざまな手法や考え方がありますが、本質的には企業経営がデータ指向に変遷していくことを指していると考えています。
私は、データベースのチューニングやデータ移行についてのスキルがあり、多様な業種のアプリケーションの企画・設計・開発に携わってきました。
仕事の形態が、自社サービスか受託かコンサルティングかを問わず、受益者(ユーザー・カスタマー)の価値をデータ指向のサービスを通して最大化し、ひいては社会貢献ができる技術者を目指します。
食品製造流通業の顧客(売上1500億円規模)の基幹システム全面刷新プロジェクト(利益管理・販売管理・物流管理・債権管理等)に新卒研修後に、DBの横串し担当として参画しました。
アプリケーション基盤チームのDB担当として、RDBの開発・テスト・本番環境の構築を行っていました。
苦労した点は、複数のサブシステムが異なるリリースタイミングであったため、Aシステムのチームの本番環境のリリースをするのと並行でBシステムはシナリオテスト、Cシステムは開発を開始するなど、複数の環境間の差異を頭に入れながら作業をする必要があったことです。
プロジェクトの方針として、自動デプロイを行っていなかったため、手動でそれらの作業をミスなく行う必要がありました。
VBAマクロで手順書を自動生成するツールを使うことにより、作業の品質を担保していました。(先輩が作ったツールのテンプレートを修正して使っていました)
また、オンプレミスでリソースに制限があったため、表領域不足が各環境でリソース監視をするためのジョブを仕込み(JP1 + PL/SQL)表領域不足でアプリケーションのエラーが発生しないように自動検知するようにしていました。
日配の食品製造業であったため、1日の販売データのトランザクション量が多く15-20万件ありました。
トランザクションは120日保持が原則だったため、1テーブル2000万件超のテーブルが複数存在している状況である一方で、大規模プロジェクトで開発者のDB知識のばらつきがあったこともあり、インデックスが適切に使われていなかったり、使用していたOracle製品(Oracle Exadata)の特性を十分に利用できていないケースが多々ありました。そのため、DBAとして性能の悪いSQLのチューニングを依頼され対応していました。
チューニングとして行ったことは、インデックスが適切に設定されているかという基本的なところと、SQLの実行計画が最適でない場合のヒント句 による固定をメインで行いました。
また、Exadataの特性として、Smart Scanというストレージ・サーバー内で仮想のインデックスを使いスキャンニングを行う機能がありました。そのため、SQLの実行計画としてフルスキャンに寄せたほうが性能がいい場合があったため、日次レンジあるいは区分によるリストレンジのパーティション・プルーニングを行った上でフルスキャンを選択するなど変化球的な対応もしばしば行っていました。
また、DBAとしてのDB性能対策の経験を買われて、アプリケーションの旧システムから新システムへのデータ移行についても、主担当として取り組みました。
債権管理(請求データ)の移行だったのですが、上述の販売データと同件数があり(1日15-20万件、4ヶ月で2000万件)、一日あたりのバッチ処理時間としては数分程度でしたが、それらを120日分一括でシステム停止時間の数時間の中でもれなく移行する必要があったため通常のアプリ内のバッチ処理とは異なる処理方式で移行を実現する必要がありました。
移行の時間制限が課題になっていて、最も処理時間のかかる処理は4時間程度かかっていました。これを、上述のsmart scanを使い、テーブルにパーティションを16分割のhash化して並列処理を組むなどして、10分程度に縮めることができました。結果として、移行作業の時間に大幅な余裕ができて、時間内での移行を安全に成功させることができました。
環境構築・運用について、現在は、RDBではクラウドのマネージドサービスを利用することが多いと思います。異常にデータが膨らむ処理があった場合などに課金超過にならないように自動検知する仕組みを取り入れるなど、当時の知見を応用することができると考えています。
SQLチューニングについて、個々の対応については一定の成果をあげられたと考えていますが、そもそも性能が下振れしないような取り組みをプロジェクトの全体計画として取り入れることができたと考えています(新卒で新規参画した際には大枠の方針が決まっていました)。
具体的には、アプリケーションの基本設計(DB論理設計)の段階からレビューを行ったり(上述の債権管理領域では行うことができました)、製品の性能を活かして、フルスキャンを基本方針にする設計をしたり、性能悪化する危険性のあるSQLを回帰テストで拾い上げて事前対応するなどです。
これらは、当時の実力でもできたことですが、プロジェクトの仕事量に対するリソースが足りていなかったこともあり実現することができませんでした。
次に、近いポジションになったときに、DBに限らずバックエンド全般の性能に対する取り組みに応用していきたいと考えています。
最大手コンビニ本部(売上規模2.4兆円)を顧客に、店舗システムの刷新(店舗に一台のストアサーバーをクラウド化し、端末をタブレットに置きかえ)プロジェクトに要件定義〜詳細設計にて、店舗機器管理システムの領域のチームのサブリーダーとして関わりました。
顧客の現行システムの調査を行い、必要な画面数・テーブル数・データ連携を定義して、顧客担当相と折衝を重ねて要件定義を行いました。
店舗システムの刷新プロジェクトの中で、自分は店舗機器管理システム(タブレットやPOS、プリンター等の管理。HWの異常を自動検知して本部側のサーバーに通報する仕組みや、不良品・故障品の取替を依頼する画面等)を担当していました。
旧システムはHWのベンダーが担当しており、ソースコードの開示が不可能で、ドキュメントの開示についても非常に時間がかかったため、要件をファクトベースで提示することの難易度の高い案件でした。
顧客担当が新任の方であったこともあり現行ベンダーとの意思疎通が困難だったため、以前の担当から経由でドキュメントを入手したり、顧客にお願いをして、現行機(コンビニのバックヤードに一台ずつあるストア・サーバー)の操作をさせてもらうなどして、要件をまとめていきました。以前のプロジェクトでは、顧客との折衝は上司が基本的に行っていたため、ここで基本的な交渉スキルを学ぶことができました。
画面数・テーブル数・データ連携についての、詳細を定義していくフェーズでした。
自分は前のプロジェクトで、DB担当だったこともあり、すべてのテーブルの論理設計を行いました(30テーブルほど)。横串のデータベース担当チームにレビューをしてもらうスタイルでした担当の方は業務に詳しくないので、用語が一般的すぎるなどの指摘などがあったため、業務の用語を現在のものを含めて整理する(辞書の作成)などしてコミュニケーションを円滑にするなど工夫して対応しました。
また、画面以外のバックエンドの処理については設計レビューを担当していたので、協力会社の方に設計書を作成してもらい、レビューを行っていました。
自分よりプログラミング経験のあるエンジニアの方に設計してもらっていたので、レビューの際は当初は緊張しましたが、「自分がその設計書を見てコーディングできるか」を基準にレビューを行いました。暗黙の了解のようになっているところをあいまいにしないで、仕様の伝達が不足していることがわかれば伝えたり、わからなかったら自分が責任をもって調べて伝えるということを徹底していました。経験の浅い自分に対して、反発をするエンジニアの方もいましたが、対立をしすぎないように時間をかけてコミュニケーションをして理解のギャップを埋める努力をしつつ、やるべきことはやってほしいと伝えることをしていました。
本来の性格では、自分でやったほうが早く手を動かしたいタイプなのですが、今後のキャリアも踏まえて、苦労しながら人に動いてもらうように努力しました。そのために、上司に対応方針を相談したり、職場でのコミュニケーションの方法を専門家(産業カウンセラーの方)に相談したり、抱え込み過ぎないように他人の力を借りるようにしました。
この刷新プロジェクトについては、自分たちが担当していた領域については、顧客側の都合で途中中断して、基本設計終了後に案件は終了してしまいました。
しかし、自分としても消化不良な部分があったこともあり、別ベンダーの構築領域に関して、システム部の運用業務の業務移行についてコンサルティングを行う案件があり、その案件のディレクターに誘われたこともあり、自分のこれまでの業務とは毛色の違うコンサルティング業務に携わりました。
主な業務内容としては、顧客の業務ポータルサイトから、業務内容についてのドキュメントを抽出して、分析を行い、現行の業務についてドキュメント化することでした。
苦労した点は、顧客側で採用した別ベンダーの方と協力してドキュメントのアウトプットを出すことでした。企業文化の異なる中で、同じ仕事をしていくことは、自社で雇用した協力会社の方と仕事するのとは、また別のコミュニケーションの難易度の高さがありました。具体的には、どれだけ説明しても取り決めた形のフォーマットでのアウトプットにならないなどが大変な部分でした。
Microsoft Office Excelで作成するドキュメントの体裁を目検で整えることは難しいので、RDB(SQLite)にexcelの表をインポートして、SQLでチェックをするなどして、技術的に効率性をカバーしていました。
コミュニケーションの部分では、なるべくコミュニケーションを重ねたり、日次のMTGを重ねるなど努力はしましたが、結果として、顧客の意向もあり別の業務を担当することになりました。
要件定義については、はじめて行ったにしては成果をあげられたと考えています。
リーダーが、顧客や自社の上位層との金額含めた調整で手一杯の中で、現場レベルでの情報収集や整理、エビデンスに基づいた顧客担当者への説明ができたと考えています。
できれば、ソースコードを入手して、解析をしてみたかったと考えています。
自分自身で行うDBの設計については難易度は高く感じませんでした。
一方で、他の方に作ってもらってレビューをしてもらうのは難易度が高かったです。当時は人間同士のコミュニケーションの力が足りないせいだと感じて対処をしていましたが、本質的には技術力不足だったと振り返っています。
現在の自分だったら、自分が一番難易度の高い設計を行ってしまい、それ以外の部分を自分のを見本して作ってもらうなど、もっと効率の良い方法をとっていたと思います。
こちらも基本設計と同様に、本質的には技術力不足だったと思います。
顧客の業務分析につていも、業務のエビデンスとなるポータルサイトの抽出についてもスクレイピングして、ドキュメントについては自動生成するなどして、他社よりも圧倒的にアウトプットを出せば、業務面での多くの調整は不要だったのではないかなと考えています。
大手スーパー(売上規模3900億円)本部の顧客に対して、老朽化した本部店舗間データ連携(発注データ等の連携)システムの刷新プロジェクトについて、リーダーとして参画しました。
会社にとっては、新規顧客で案件開始2ヶ月くらい、メンバーは自分以外に全員職位が上のメンバ5名というフェーズで参画しました。
データ連携システムの刷新については、企画段階から携わりました。
刷新するシステムの選定(自社プロダクトと他社のプロダクトとの比較)を行いました。会社の方針として、自社プロダクト導入の推進をすることになっていましたが、社長採決が必要であったため中立的な視点で、機能(対応するデータフォーマット)や非機能要件(拡張性)、コスト面での比較を行いました。
他社プロダクトのベンダーの方にヒアリングしたり、試用版を試してみたり、資料請求するなどをして、顧客の立場になって使いやすさなども含めて調査しました。
プロダクトの選定が自社プロダクトに決定し、旧システムの現行調査を行いました。
COBOLのソースコードの受領をし、データ連携の前処理としてどのようにデータ変換を行っているか、自社プロダクトでのカスタマイズがどれだけ必要かの調査を行いました。
COBOLの言語仕様がJavaと全く異なっていたのと、詳しい人が周りにいなかったため理解するのを難解に感じましたが、書籍を購入しドキュメントを参考にするなどして、業務で必要最低限度の知識を習得するようにしました。
難しかった点は、技術的ではなく、プロジェクトリーダーということで、予算管理を行うことでした。予算の都合で、エンジニアの工数の確保をするのが難しく、社内調整も重ねてなんとか確保することはでき、プロジェクトを遂行することができました。
技術的な面での苦労よりも、予算管理での調整ごとが難しく感じました。顧客側の都合と、会社側の都合両方について上手に折り合いをつけることがなかなかできず、進め方について上司にだいぶ助けていただきました。
振り返りをすると、自分の経験+自分の指向+ストレッチでどれだけその案件をコントロールできるかを見越した上で案件を受けるべきだったと反省しています。上からの期待もあったと思うのですが、周囲の期待に答えたいという自分の性格が逆効果になったと思っています。以後のプロジェクトでは、受ける前に十分に上述のことは考慮し受けるようにしています。
一方、未知の領域で成果を出すことの経験は積むことができたと考えています。
大手自動車部品メーカーのモビリティIoTプラットフォーム構築プロジェクトに開発メンバーとして参加しました。
Go言語を使った、ユーザー管理のAPIの開発を行いました。
Go自体ははじめてで、最初はすこしとっつきづらかったですが、少しの間で慣れることができ生産性をあげることができました。1APIの開発に当初は3日くらいかかっていたのが、1日に2,3APIを開発することができました。
このプロジェクトでGitを使った開発・レビュー体制を初めて経験し、モダンな開発スタイルの経験をつ無事ができました。
KongというOSSを使った、APIの認証基盤の構築を行いました。
マイクロサービス指向のアーキテクチャで、AWSのECS上にコンテナを立てて、OAuthによる認可を行ったAPIのみリクエストが通過できるような機構の実装を行いました。当時、AWS上に構築するのは初めてだったためALBやECSの違いもわからないというところのスタートでしたが、自分で調べて実装してみてうまくいかない部分は社内でAWSに詳しい先輩に聞いて解決し、構築手順・運用手順書まで作成して納品をすることができました。
会社の方針もあり、業務系のマネジメントよりの仕事をしていましたが、技術指向の仕事をしたいという要望を伝えたところ、部署異動を行い配属された最初のプロジェクトでした。そのためメンバーからの開始となっています。自分にとって向いている仕事がこちらだなという実感を持つことができました。
クラウドを使った、マイクロサービス指向のWebサービスというこれまで経験した業務アプリとは異なる、設計思想や開発スタイルに対して、最初はとまどったものの、開発自体が非常に楽しく感じることができ、最も技術的に充実感を感じる仕事でした。所属している会社としては、当時でもあまりないタイプのプロジェクトであり短い期間で終了してしまったのが残念でしたが、独学でWebサービスの勉強をするモチベーションに繋がりました。
(現在はRuby on Railsの学習を独学でしています)
大手全国紙(売上規模3700億円)の編集業務で用いるデジタル紙面向けのCMS(※)の導入プロジェクトにメンバーとして参画しました。
※自社プロダクトとしてメディア企業向けのCMSが開発されていて、その第一顧客へのサービス提供するプロジェクトです。そのため、開発は自社プロダクトのカスタマイズとなります。
プロジェクトの開発準備期間に参画して、品質保証の機構の構築を行いました。
要件定義で作成したドキュメントをベースにソースコードを自動生成する仕組みを構築しました。(パイプラインはJenkinsを用いています)。
難しかった点は、自社プロダクトという性質上、標準仕様と顧客のカスタマイズ仕様を並行して管理する必要があったことです。仕組み自体は、社内の品質管理ツールを使っていたためテンプレートは存在していたのですが、標準-
カスタマイズの並行管理についてはプロジェクト側(自分)が設計・実装する必要がありました。
具体的には、区分マスタを例に取ると、標準では、10番の区分では、
1:AAA、2:BBB、3:CCC
として管理したいときに、このプロジェクトの顧客の要望で
1:AAA、2:CCC、3:DDD
として管理したい、10番以外は標準と同じというときに両方の定義を共存させて、JavaのEnumクラスを生成するということをどのように実現するかということです。
前提としてドキュメント(Excel)をRDBにいったん保存して、そのDBの内容をSQLでチェックしてから、velocityテンプレートを使って各種ソースコードを生成する機構を用いるとことでした。
RDBに保存する際に、標準と当プロジェクト用のスキーマを分け同名のテーブルに別個に取り組み、チェック・生成する際にその両方のスキーマに対して参照権限のあるスキーマにDBオブジェクトのビューを実装して読み取るという方針をとりました。
そのようにした理由は、既存のチェック・生成のSQLを使い回せる点と、別プロジェクトが新しく利用を開始するときに、スキーマのDDLは全く同じものをDB上にデプロイすればDBの構築は簡易に済むと考えたためです。
難しかったのはJenkinsのパイプラインの構成で、標準のソースコード生成とプロジェクトごとのジョブをどこまで汎用化するかという点です。具体的には、ドキュメントを読み込みDBに取り込むジョブに対し、ドキュメントのパスや取り込み先のDBの接続定義をパラメータで変数としてもって、前工程のジョブからパラメータとして渡すかどうかという点です。汎用化すれば、プロジェクト追加したときの実装が楽になる部分がありますが、ジョブ定義の可読性が下がるというデメリットがあると考えていました。
結果としては、プロジェクトの受注可能性などをみると、続々と参加プロジェクトが増えるのではないかという予想を行い、追加の容易性を選択して、汎用化を行うことにしました。
また、アプリ開発については、CMSの後続に連携するシステムへのデータ変換の機能のカスタマイズを行いました(Java/DynamoDB/PostgreSQL/Groovy/XML)。
KVSのDB(DyanmoDB)から、Groovyを介してJavaのmapを生成して、Javaでデータレイアウトを変更して、velocityテンプレートを用いてXMLで出力するという形式をとっていました。
KVSから一度に50-60項目を取得するため動的型付け言語もGroovyで一度に取得してから、大まかな型定義を暗黙変換で行い、細かい型変換やレイアウト変換(List-MapをListに変更するなど)はJavaで行っていました。
難しかったところは、細かいひとつひとつの項目に対して、入ってくるデータのパターンを予想しながら変換処理を実装するところでした。NULLの場合、配列型で要素がない場合などのチェックの実装は、あとから必要性に気づく場合が多く予め予想して対応できていればという対応ケースがあったため、途中からは必ずNULLチェックを想定して実装するようにして、そのような頻度を下げることを行いました。
シナリオテストのフェーズでは、バックエンドだけでなく、Backbone.jsをベースとしたフロントエンドの改修の対応にも幅を広げて対応をしています。独学で勉強したWebアプリ開発(Rails,Vue.js)の内容が役に立ちました。
運用フェーズのために、主にAWSのコンソールからCMSのデータ登録状況の確認や操作履歴をユーザー側でも追えるように、説明資料の作成をして説明を行いました。
技術要素としては
工夫したことは、記事のIDなどシステム的な項目ではなく、ユーザー目線で関心のある項目(文書見出し名等)からシステムの履歴やデータの参照を追跡を行えるようにしたことです。普段、仕様を詰める顧客担当者はスキルレベルが高いので、必ずしも必要はない状況でしたが、実際に運用フェーズがはじまると様々なレベル感の人が使い始めることは予想できたので、顧客側での説明負荷を下げるためにも丁寧な説明を盛り込んだ資料作成を意識しました。
運用フェーズの準備として、記事配信の一括リカバリをAWS Lambdaの関数を使って実行するツールを開発しました(ランタイムはPython3.6)。
背景としては、CMSで作成した記事をニュースサイトに配信する処理があるのですが、それが何らかの理由で失敗した場合、配信管理画面からひとつずつ再実行をする必要がありますが、理由によっては大量の記事が配信エラーになる場合があります。そのため、それらを一括でリカバリするためのツールを作成する必要がありました。
工夫したことは、AWS Lambdaを使って、WebアプリのEC2と同じVPC内でしか実行できないようなツールにしたことです。windowsのバッチスクリプトなどでAPIをコールするようにもできましたが、セキュリティの観点から限定したIAMユーザーでしか実行ができないようにすることで運用における権限管理の煩雑さを吸収しました。
単純に目の前の要件を満たすことではなく、その後の拡張性も実現可能性をみながら考えて、コストと見合いながら実装できたことは、良かったと思います。
ただし、実装に時間をかけすぎた反省はあるので、次近い業務を行うときは最初から拡張性についてはメリット・デメリットを周囲と相談しながら実現したいと思います。
正常系のテストはしっかり書いていたため、対応工数はあまりかかりませんでしたが、上述したように異常系についての手戻りが何回かあったため、仕様外の部分の異常系について経験のバリエーションを増やしたいと考えています。
運用に関しては、ほとんどの場合自分がずっとやるわけではないので、自分以外の誰かが使ったときに、不足した情報はないか、権限の管理を適切に行えるかを考える必要があると考えています。
上記を意識して取り組むことができました。また、AWSの各サービスの知識についても拡充することができたため、スキルの幅が広がったと感じています。
コンビニ店舗システム刷新プロジェクトでの、基本設計フェーズでの成果物(設計書)のデリバリーと品質
オン・スケジュールで行うためには、要件定義で自分が定義した仕様の認識齟齬が設計書を作成するメンバーとの間で極力無いようにすることが優先度が高いと考えました。
その中で、伝えたつもりであった仕様が十分に伝わらず設計されたものに対して、認識齟齬を埋めて説明することが難しいと感じました。伝え方が至らない部分はあったと考えていますが、「言った言わない」の不毛な議論にもっていきたがるメンバーもいたためその対応に苦労しました。
そのため、メンバーのちょっとした疑問点についても拾い上げていくことが必要だと考え、毎朝の定例会を提案・運営したり、リーダーとサブリーダー(私)は客先にいる必要があったのですが、どちらかがなるべく執務スペースにいるようにするなどしました。
品質については、以下を重要と考えレビューを行っていました。
自分のアプリ開発の経験が浅いこともあり、「自分でも実装できるか」をポイントにレビューを行っていたのですが、その意図がうまく伝わらなかったのか、「これで実装できる。何が問題あるのか?」と行ってくるメンバーがいたことが苦労ポイントでした。(端的にいうと舐められてました)
自分自身で抱え込まずに、上司に相談するととともに、コミュニケーションの方法を専門家(産業カウンセラー)に相談したりとなるべく自分で抱え込まないようにしていました。
最終的には粘り強く説明し、やってほしいことは毅然として伝えることによって対応してもらうことができました。
データ連携システム刷新プロジェクトでの、要件定義から基本設計フェーズでのコスト
経験の浅い領域でのコスト管理で不明点が多かったため遂行できるか正直不安があったので、社内の知見をなるべく活用することを意識していました。
また、コスト管理で参画したプロジェクトについては社内プロダクトで、実績も多いことから、高めの貢献利益率の目標が設定されていて、そのクリアをするのが難しかったです。
自分も含め、経験の浅いメンバがほとんどであったため、社内プロダクトの知見の深い内製開発メンバーのアサインが必須と考えていました。しかし、その方の単価面で数字をクリアするのが難しく、上司を巻き込んで会社側の負担をするように交渉を行い、数字を達成することができました。
会社の負担が若干とはいえ出てしまったのは、苦しい決断でしたが、プロジェクトマネジメントの仕事は顧客・会社・プロジェクト(仲間と自分)に対して結果として3方良しにすることだと思っているので、会社側に必要であればある程度損失を飲んでもらうという交渉をできたこと自体は良い経験だったと考えています。