« 高品質と高機能は同義ではない | トップページ | PMBOKにおけるプロジェクトファイナンスの考え方 »

2013/01/03

アーキテクチャ設計のアンチパターン集~44のアンチパターンに学ぶDBシステム

44のアンチパターンに学ぶDBシステム」を読んでみて、とても優れたアーキテクチャ設計のアンチパターン集に思えた。
過去の経験上、あるあると思う箇所がたくさんあった。
感想をラフなメモ書き。

【元ネタ】
44のアンチパターンに学ぶDBシステム - give IT a try

あなたの現場にも必ずあるDBシステムの"悪い例"が満載!「44のアンチパターンに学ぶ DBシステム」 | oracletech.jp

『44のアンチパターンに学ぶDBシステム』 - 虎塚

44のアンチパターンに学ぶDBシステム : 賢者の図書館 (Under Construction) : livedoor Blog(ブログ)

【本】SQLをしっかり学習したい人におすすめミック本。 | プラプラ式技術系 Access流!

【本まとめ】44のアンチパターンに学ぶシステム構築時の失敗パターン。もっとはやく言ってよーとなる前に。。。 | プラプラ式技術系 Access流!

ソフトウェアの品質を学びまくる:【本】我がふり直すためのアンチパターン百花繚乱

【1】「44のアンチパターンに学ぶDBシステム」は以下の目次になっている。
アンチパターンは「アンチパターン―ソフトウェア危篤患者の救出」のパターンテンプレートに従っていて、とても分かりやすい。
幾つかのアンチパターンについて感想を書く。

PART1 DB&アプリケーション 編

Chapter1 データ設計
アンチパターン(1) ねずみ算
アンチパターン(2) 大河ドラマ「大作SQL」
アンチパターン(3) バケツ RDBMS
アンチパターン(4) 太っちょ(多くの列を持つ表)
アンチパターン(5) OLTPなのにSQLが重い
アンチパターン(6) DATE型の意識統一不足(時分秒など)
アンチパターン(7) データの保持期間を決めていない

Chapter2 アプリケーションコーディング
アンチパターン(8) 不適切なリトライの仕組み
アンチパターン(9) バッチにおいて適切に処理を分割していない
アンチパターン(10) バッチがリラン(再実行)できない
アンチパターン(11) 再利用しない(コネクションなど)

Chapter3 SQLコーディング
アンチパターン(12)バインド変数を使っていないSQL
アンチパターン(13)組み合わせ爆発
アンチパターン(14)臭い物に蓋をすると、もっと臭くなる
アンチパターン(15)データの量の暴力
アンチパターン(16)過ぎたるはなお及ばざるがごとし

Chapter4 計画にまつわるもの
アンチパターン(17) データの分身の術……どれが本物?
アンチパターン(18) DB連携地獄
アンチパターン(19) サーバー移行やバージョンアップでSQLのテスト軽視
PART2 インフラ 編

Chapter5 設計
アンチパターン(20) トランザクションスコープが不適切
アンチパターン(21) なんでもかんでもリアルタイム集計
アンチパターン(22) 詰まると接続が増えるアーキテクチャ
アンチパターン(23) 引きずられるアーキテクチャ
アンチパターン(24) 無関心(エラーが起こるまで異常に気がつかない)
アンチパターン(25) タイタニックシンドローム(絶対に沈まないと思って緊急時の備えを怠る)
アンチパターン(26) 自分で自分を診察する(自分を冷静に判断することはできない)

Chapter6 設定やテスト、運用
アンチパターン(27) 不法占拠
アンチパターン(28) 掃除しない部屋
アンチパターン(29) 振り返れば相手はいない
アンチパターン(30) 足元おろそか
アンチパターン(31) リソースのバランスが悪い
コラム● 限界性能テスト
PART3 プロジェクトマネジメント 編

Chapter7 DBシステムとプロマネの問題
アンチパターン(32) 気がついたらテストの時間がない(もしくはテストをしない)
アンチパターン(33) 目標なきチューニング
アンチパターン(34) 完璧な初期DBサイズ見積もりと実際のデータ量の差が生む悲劇
アンチパターン(35) 性能に関するアプローチがない
アンチパターン(36) DBに格納されているテストデータ量が少ない/種類が少ない

Chapter8 人のサガに起因するトラブル
アンチパターン(37) 見て見ぬふり
アンチパターン(38) 重すぎる高価な鎧(よろい)
アンチパターン(39) 度を越した楽観
アンチパターン(40) 心配屋

Chapter9 DBAをめぐる組織や権限の問題
アンチパターン(41) 自社に合ったDBAのあるべき姿が分からない/DB担当の要員アサインが悪い
アンチパターン(42) DBAが育たない
アンチパターン(43) セキュリティ権限設定とDB運用のミスマッチ
アンチパターン(44) DBチームのリーダー/担当者の権限が弱い

【2】OLTPなのにSQLが重い、なんでもかんでもリアルタイム集計

例えば、Webシステムなのに、応答時間に3秒以上かかったりする。
今のWebシステムならば、1秒以上応答がなかったら、苛つくユーザも多いし、Webサイトに訪れるリピータが減ってしまう。

原因は、開発時は少ないデータ件数でSQLを実装して問題なかったが、システムテストや性能テストで、Web画面から検索したら応答時間に30秒以上かかってタイムアウトしてしまう、などの事例が多いだろう。
特に新規案件で、過去プロジェクトの経験者のいない開発チームでは、どこにDBのボトルネックが起きるか予想できないから、よく起こりうる。
似たようなアンチパターンとして「なんでもかんでもリアルタイム集計」があげられる。

再構想の解決法としては、開発初期にプロトタイプを作って性能検証したり、性能負荷テストを十分に実施すること。
最近なら、JMeterのようなオープンソースの優れた負荷テストツールがあるので、故意にリクエストデータを増やすなどのテストもやりやすくなった。

あるいは、サマリ用テーブルや導出属性をテーブルに追加するなど検索結果を取得しやすいテーブル構造へ設計しておくこと。
サマリ用(集計)テーブルを作るなら、普通はCobolやストアドプロシージャなどのバッチ処理で集計処理する設計になるだろう。
導出属性の場合も同様で、累計回数とか累計金額、残高、在庫数などのデータはバッチ処理で後から更新するようにした設計になるだろう。

【3】データの保持期間を決めていない

本番リリース後、トランザクションテーブルは放置しておけばどんどんデータが溜まっていき、数年後には当初想定していたデータ容量よりも溢れてしまう時もある。
例えば、業務要件として、会計データは8年間保持しなければならないという法律があったりするので、過去のデータをすぐに削除することもできない場合もある。
しかも、会計監査上、過去データを保持するだけでなく、いつでも検索できるようにしておかないと、会計監査に引っかかる場合もある。
そもそも、会計データ(特に日々の仕訳データ)を紙の会計3伝票からシステム化することで、8年分の紙データを倉庫に保管するコストがなくなるために、そのようなシステムを導入する場合が多いから、皮肉なものだ。

再構想の解決法としては、引き落とし処理を実装しておき、直近数ヶ月~1年のデータを保持して更新する可能性のあるテーブルと過去データで参照するだけのテーブルに分けたりする。
そうすれば、更新系テーブルから参照系テーブルへ月次で引き落とし処理を実装すれば、参照系テーブルにインデックスを貼ってチューニングすればいい。

あるいは、運用後数年してトランザクションデータ量が多くなり、DB設計が複雑でリファクタリングもできないならば、メモリやHDDなどのハードウェアを強化するしか方法がないだろう。
この方法では、システムリプレースになるまで、コストが増え続ける弱点がある。

【4】バッチにおいて適切に処理を分割していない、バッチがリラン(再実行)できない

バッチは業務システムの生命線である場合が多い。
例えば、日次で、製品や商品の在庫数や納期のリードタイムを計算したり、製品を作るのに必要な品目とその所要量を計算したりする。
あるいは、月次で、在庫の棚卸しや会計締めを行い、商品有高帳や損益計算書、貸借対照表を出力したりする。
いずれも、これらの処理が止まるとユーザ企業の業務が文字通り止まってしまう。

このアンチパターンでは、そのバッチ設計で、業務の観点では1トランザクションなのに、バッチ処理の観点では複数のトランザクションに分かれていて、バッチ処理の途中で異常終了した時に、データが不整合のまま放置される場合が相当する。
そもそも、大量データを処理したり、複雑な処理をするために夜間バッチ処理するのだから、複数のジョブが正常終了して初めて一つの業務が完了する時が多い。
しかし、異常時にバッチをリランできるような仕組みにしておかないと、あるべき想定されるデータを復旧できなくなる。
しかも、異常終了したバッチの後に続くバッチが終わらなければ、翌朝のオンライン処理に必要なデータが設定されない制約があるため、バッチのリラン処理は短時間で終わらせる必要がある。
業務SEならば、夜間バッチのリラン処理は遭遇したくなくらい悪夢だ。

再構想の解決法としては、異常終了した時のバッチ設計をきちんと考慮しておくことが基本。
そして、システムテストや障害テストで、障害発生時の運用方法を事前にテストしてマニュアル化しておくのが大切。
そうすれば、本番運用時にバッチが異常終了した時でも、自信を持って対応できる。

【5】データの重複(データの分身の術……どれが本物?)

同じ意味のデータ(ホモニム、シノニム)が複数のテーブルに混在しているアンチパターン。
普通は、テーブルの正規化が不十分な場合が多い。

だが、よくある例は、一次開発後、次々にサブシステムを行き当たりばったりで開発して、個別最適化してしまい、システム全体の観点で見ると、あちこちにデータの重複が発生してしまう事例があるだろう。
特に昨今は社内Webシステムをどんどん作ったのは良いが、複数のサブシステムを連携する時に、重複するとは分かっているものの、開発の都合上、重複したデータを保持せざるを得ない場合があるかもしれない。
システム間接続ではありがちだ。

再構想の解決法としては、全体最適の観点(つまり、EA:Enterprise Architecture)でサブシステム内に散在する重複データをなくす正攻法しかない。
とはいえ、普通は、やっと安定運用させたサブシステムをいじることはできず、抜本的なシステムリプレースの案件が出てくるまで、重複データを放置して、システムをどんどん複雑化させてしまう場合が多いだろう。

【6】トランザクションスコープが不適切

アンチパターンの例としては、Webシステムの処理で、1トランザクションに不要な処理が混じって、処理が重くなりがちだったりする。
あるいは、1トランザクションの観点では、分離して後回しにして良い処理が混じっていて、応答時間が長くなりがちだったりする例があるだろう。
すると、障害発生時に処理が遅延していつまでも処理が終了しなくなったり、データの不整合が発生したりする危険がある。
原因はいずれも、トランザクションの設計が悪い。

再構想の解決法としては、タイムアウトの場合の処理を実装して、障害発生時にいつまでも処理が終わらない事態にならないようにする。
あるいは、重くなりそうな処理を分離して非同期処理にすることで、ユーザへの応答時間を短くする。
昨今なら、JavaScriptの非同期処理が使いやすくなっているので、ユーザにとって使いやすいユーザインターフェイスにすることもできるだろう。
あるいは、処理が重くなりがちなトランザクション処理はサービス監視対象として、障害を検知しやすくする方法もある。
最近は、Zabixなどオープンソースの優れた監視ツールが揃ってきているので、運用ノウハウが色々出てきた。

【7】引きずられるアーキテクチャ

よくある例は、外部システムとデータをやり取りする時に、応答時間が遅すぎたり、リクエストのデータ量が多いためにリソースを浪費してしまったり、閾値を超えるためにエラーになってしまう場合があるだろう。
あるいは、外部システムとの通信障害のエラー処理が甘いために、タイムアウトしているのにいつまでも応答を待ち続けたり、不正データ取得の処理がまずくて障害が起きやすかったりする場合もある。
最近は、複数システム間のデータのやり取りはSOAPやJSONなどが多いだろうが、特にSOAPはXML形式ゆえに、無駄にデータ量が増えやすい。

再構想の解決法としては、外部システムとの方式設計(アーキテクチャ設計)を事前に考慮することや、外部接続テストや障害テストで十分に接続インターフェイスを検証することがあげられるだろう。

マネジメントの観点では、外部システムは別チームないし外部ベンダーの管轄になるため、プロジェクトの初期段階から外部ベンダを巻き込んだコミュニケーション計画を立てておき、事前に外部接続インターフェイスの情報を収集するような仕組み作りが重要になってくる。
駄目なプロマネは、この辺りのコミュニケーション計画や外部ベンダのような利害関係者のハンドリングが下手な時が多い。

【8】DBに格納されているテストデータ量が少ない/種類が少ない

よくある例は、システムテストで本番運用に近いテストをしたい時に、テストデータ量やテストデータの種類が少ないために、本番運用後に想定していない障害が多発する場合がよくあるだろう。

再構想の解決法としては、システムテストや性能テストでテストデータの種類や量を増やすことがあげられる。

性能テストの観点では、本番稼動後の業務要件を想定して、必要なテストデータ量を準備すべき。
そのために、増幅データを作るためのプログラムも別途作る工数が必要になるかもしれないので注意すべき。

システムテストの観点では、ERPのようなパッケージ製品を導入する場合、テストデータをERP自身で生成するパターンと、本番環境で運用中のデータを移行するパターンの2パターンが考えられる。
前者の場合、ERPで使われる全種類のテストデータが生成される保証があれば、採用した方が良い。
なぜならば、網羅性の高いデータを使ってシステムテストを実施できるので、運用品質を高めることができるからだ。

しかし、稼働中の本番データがあるならば、本番データを移行してシステムテストした方が良い場合が多い。
なぜなら、既に使われている本番データをシステムテストで使うことによって、ユーザが業務で使うデータに近くなるからだ。
運用後に想定外の障害が発生しないように、どちらのやり方を使うか、考えておくべき。

【10】自社に合ったDBAのあるべき姿が分からない、DBAが育たない

今の時代、DBAのような業務データだけの管理者は多分いない。
普通は、運用チームやアプリ共通チームなどのように、どこかのチームの一人だけにタスクが集中する時が多い。
すると、DBAが初心者だったり、経験が浅い開発者であれば、DB周りのトラブルがいつも発生しがちで、大きな障害の地雷原になっているだろう。

原因としては、運用時の体制が不十分だったり、DBAのスキル不足だったりする。
再構想の解決法としては、DBAを補佐するチームを含む体制をきちんと作ること。
44のアンチパターンに学ぶDBシステム」では、DBAを含む体制として、開発チーム、運用チーム、全てのサブシステムを管轄するインフラチームの3つが挙げられている。
最近は、全体最適の観点から、全てのサブシステムを統括するインフラチームがDBAの役割を持つ時が多いだろうと思う。

44のアンチパターンに学ぶDBシステム

|

« 高品質と高機能は同義ではない | トップページ | PMBOKにおけるプロジェクトファイナンスの考え方 »

ソフトウェア工学」カテゴリの記事

モデリング」カテゴリの記事

コメント

コメントを書く



(ウェブ上には掲載しません)


コメントは記事投稿者が公開するまで表示されません。



« 高品質と高機能は同義ではない | トップページ | PMBOKにおけるプロジェクトファイナンスの考え方 »