『[24時間365日]サーバ/インフラを支える技術』とSIのインフラを比べる

僕はSIerで、インフラやることが多いのだが、ふとWeb系のインフラとの違いが気になって、『24時間365日 サーバ/インフラを支える技術』を読んだ。そこで見えた違いや共通点をまとめてみる。
ただ、僕がSI側として見えているのは、自分の関わったプロジェクトが主で、たぶん全然毛色の違うシステムもあるとは思うので、その辺はご注意下さい。

前提

まずは、システムの差異の前提となる、web系とSI系の差異に触れておきたい。簡単にまとめると、こうだ。

web SI
自分たちで面倒を見る 引き渡して終わり
ブラックボックスを嫌う 作り込みを嫌う
OSSを好む OSSを嫌う
負荷が予測できない 負荷はほぼ予測できる
状況に合わせて変化する リプレースまで手を入れない

本書で触れられているweb系のシステムは、基本的に構築も運用も自社で行っている。一方SIerは、要件に従ってシステムを構築したあと、顧客に引き渡して完了。もちろん保守も一貫して行うこともあるが、その場合も構築した要員が運用者として残るとは限らない。システムに関する知識がほとんどない運用者に引き継ぐこともある。
SIにおいて、このような引き継ぎが可能なのは、納入した後にシステムに変更が入ることがほぼ無いためだ。このため、運用マニュアルさえしっかり作っておけば、運用者はそれに従うだけでよい。
一方Web系は、システムが本番を迎えた後も、システム自身に変更が入ること、システムへの負荷が変化することが前提としてある。このため、運用者は状況に応じてシステムを変更し続けなければならない。そのため技術力や対象のシステムについての知識が必要となる。
Web系では、システムで何か問題があった場合も、自分たちで作ったものだから自分たちで解決するのが基本だ。そのためにはブラックボックスはなるべく少ない方がよい。
一方SIでは、ブラックボックスであれ保守契約が結べるものであれば導入を厭わない。問題があっても問い合わせて解決してもらえればよいのだ。逆に、なにか作り込んだものに問題があると、構築した要員でなければ対応できない場合もあるため、なるべく作り込みをしないようにする。同じく保守契約がないという理由で、OSSも導入したがらない。


以下、本の各章ごとに、web系とSI系との差異に触れてゆくが、こういった前提が、システムの差異に現れてくる。

1章 サーバ/インフラ構築入門 ……冗長化/負荷分散の基本

1.1 冗長化の基本

本書では冗長化の基本を「予備機を用意する」としている。これをベースに、以降の章で様々な冗長化の方法を紹介していく。
一方SIでは、同じように冗長化の構成を取ることもあれば、予備機の用意だけで済ませることもあり、予備機すら用意しないこともある。どのくらいの時間で復旧できればよいかという要件によって、冗長化の構成を決める。サーバが故障しても、保守契約があるから修理・交換してくれるしね。


冗長化する際のポイント「SPOFを作らない」というのは、webもSIもいっしょ。
ただ、SI側がSPOFを考える範囲が広いような気がする。サーバの電源ユニットとかファンとかも対象にする。可能な限り1台のサーバが落ちない構成を考えて、冗長化できるところは全て冗長化する。クラスタも用意しないシングル構成や、Active/Standbyのクラスタに限らず、どんなに規模が大きいインフラでも、各サーバはこういったHW構成にしているので、慣習的なものかもしれない。もちろんこれをやる分、1台あたりのサーバの値段は高くなる。

1.2 Webサーバを冗長化する ……DNSラウンドロビン
1.3 Webサーバを冗長化する ……IPVSでロードバランサ
1.4 ルータやロードバランサの冗長化

クライアントからのリクエストを複数のサーバに振り分けることで、負荷分散と冗長化を兼ねる。順番にリクエストを振り分けるのが、もっとも単純な負荷分散か。本書ではこういった機能を、Linuxでサーバを立てて、その上で実現している。
一方SIでは、たいていロードバランサの専用機を入れます。単純なラウンドロビンなら、サーバ構築するSIerがマニュアル見ながら設定することもある。けど、たいていの場合はネットワーク専門の人が入るか、ネットワークチームがあればそこの担当になるので、私のようなサーバインフラ担当にとってはほぼブラックボックスです。

2章 ワンランク上のサーバ/インフラの構築 ……冗長化、負荷分散、高性能の追求

2.1 リバースプロキシの導入 ……Apacheモジュール

これも負荷分散の一つで、URLを解析して、内部の各サーバにリクエストを振り分ける。本書ではこの機能は、Apacheモジュールのmod_proxyで実現している。
SIだと、これも専用機の守備範囲にするところだけど、あんまりリバースプロキシとして動かしているという話は聞かない。

2.2 キャッシュサーバの導入 ……Squidmemcached

DBの負荷を減らすための仕組み。DBへの問い合わせ結果を一時的にキャッシュする。本書では、memcachedを使ってキャッシュサーバを立てている。
SIだと、キャッシュサーバが入る構成は見たことがない。その代わり、DBサーバにメモリを積んで、それをキャッシュに充てることが多い。なので、性能を見るときは、DBのキャッシュヒット率を結構気にする。

2.3 MySQLレプリケーション ……障害から短時間で復旧する
2.4 MySQLのスレーブ+内部ロードバランサの活用例

DBサーバの冗長化は、DB内のデータをどう冗長化するかが問題になる。DBのデータが複数あり、常に同期した状態でなければ、随時更新されるDBの冗長化にはならない。
本書では、DBの冗長化に、MySQLレプリケーション機能を利用している。マスターとなるDBサーバが1台あり、そのDBに対する変更をスレーブに伝えて同じ変更を加え、同期を取るという仕組みだ。
スレーブは複数台持てるので、シングルマスタ・マルチスレーブという構成を取る。更新系の処理はマスタに対して行わなければDBの同期が取れなくなるが、読み取りだけならスレーブからも可能だ。従って、読み取り処理はスレーブの方に分散することができる。


ではSIはどうかというと、そもそもDBサーバのハードウェア構成に違いがある。Web系システムのDBサーバは、他のサーバと同様に内蔵ディスクを持ち、そこにDB領域を持つ。DBサーバが死ぬとその領域のデータは見えなくなる。
SIの場合は、DB領域を外部のストレージに持つ。接続形式はFCが多く、複数のサーバに接続される。DB領域には基本的に1台のサーバからしかアクセスできないが、マウントし直せば別なサーバからもアクセスできる。こんな感じです。


MySQL レプリケーション基礎 - shibainu55日記


ゼロから理解する「Oracle RAC」 (1/2):ゼロからのリレーショナルデータベース入門(7) - @IT

で、肝心のDBの冗長化、負荷分散というと、OracleRACの一択だ。先ほどDB領域には1台のサーバしかアクセスできないと書いたが、この機能を使うと複数のサーバからDB領域にアクセスできる。なので、DBサーバを増やせば、それだけ処理を分散させることができるし、サーバが1台が死んでも残りが生きてサービスが継続する冗長化構成になる。
それでもストレージ自身はSPOFだし、負荷分散もできてない。これにどこまで可用性を持たせるかはわりとシステムによって異なる。Oracle Data Guardによって、MySQLレプリケーションのような構成もできるが、あまり使うという話は聞かない。ストレージ自身の機能として、あるディスク領域を常時別な領域に同期するというものもある。これだとマスタ側のディスク領域が死んでも、ディスクを切り替えればすぐに復旧できる。ストレージ自身に可用性を持たせる場合は、RAID10構成にして、ホットスペアディスクを何本も積んでおく。
OracleRACやData Guardを導入する場合は、だいたい経験のある人をプロジェクトに入れて、その人に一任することが多い。僕はよくわかりません。

2.5 高速で軽量なストレージサーバの選択

各サーバで共有して使うファイルなどを格納しておくため、ストレージサーバを使用する。本書では普通のサーバのディスク領域をnfsで共有して使っている。
SIだと、ストレージサーバというのはあまり出てこない。各サーバで共有するデータは、たいてい外部ストレージに入れて、read onlyでアクセスさせる。

3章 止まらないインフラを目指すさらなる工夫 ……DNSサーバ、ストレージサーバ、ネットワーク

3.1 DNSサーバの冗長化
3.2 ストレージサーバの冗長化 ……DRBDでミラーリング

DNSについては自分の理解が追いついてないので割愛。
本書ではストレージサーバの冗長化を、DRBDによって、2台のサーバのディスクの同期を実現している。プライマリ側が死んだら、セカンダリ側に切り替える。
SIでは先ほど書いたように外部ストレージを使うので、そのストレージの冗長化をおこなう。方法は、RAIDとスペアディスクで可用性を高めるか、それに加えてストレージ自身の機能でバックアップ用ディスクと同期させておくといったところだ。

3.3 ネットワークの冗長化 ……Bondingドライバ、RSTP
3.4 VLANの導入 ……ネットワークを柔軟にする

ネットワークの冗長化は、WebもSIもあまり変わらない。サーバ側ではBonding機能を使って、サーバ-スイッチ間の冗長化を行う。スイッチ間のネットワークの冗長化は、RSTPによっておこなう。
WebとSIの差異は、冗長化構成より、NICの構成・ネットワーク構成にある。これもそもそもというところだが、web系ではサーバを汎用的に使用できるようにするため、HW構成をなるべく統一しようとする。サーバの役割を柔軟に変更できるし、故障した際に他のサーバを代替に使用しやすい。
接続するセグメントの多いサーバは余計にNICが必要になるため、他のサーバと構成が変わってしまう。本書では、それを避けるための構成を紹介していた。一方SIだと、そもそもサーバの構成を統一するという発想がない。そのためNICは必要な分だけ積む。さらに役割ごとに複数のネットワークセグメントを持つことも多い。例えばAP-DB間のセグメント、監視用のセグメント、バックアップ用のセグメントなど。

4章 性能向上、チューニング ……Linux単一ホスト、ApacheMySQL

4.1 Linux単一ホストの負荷を見極める
4.2 Apacheのチューニング
4.3 MySQLのチューニングのツボ

この章では、トップダウンで負荷を分析して、ボトルネックを発見し、それに対処する流れが解説されている。
ここでもWebとSIの前提の際が出てくる。Webでは、負荷が予測できないことが前提になっているから、稼働後の日々の負荷分析と、それに対するチューニングが必要になる。
一方SIだと、負荷は導入前に想定し、それを処理できる構成として納入する。納入前には性能テストをおこない、定められた時間内・ハードウェアの負荷以内で処理をこなせるかを検証する。性能監視の閾値もその時点で決められ、基本的には運用中に変更することはない。
本書には、性能テストに関する記載はなかった。

5章 省力運用 ……安定したサービスへ向けて

5.1 サービスの稼働監視 ……Nagios
5.2 サーバリソースのモニタリング ……Ganglia
5.4 デーモンの稼働管理 ……daemontools

このあたりは監視について。監視サーバを立てて、そこで各サーバを集中監視する。監視対象としては、死活監視、リソース監視、プロセス監視。
WebでもSIでも監視についての考え方は変わらない。違いは利用するソフトウェアで、Web系はOSSで、SI系はサーバと同じメーカー製品を使う。メーカー製品は前述の監視項目をまとめて監視できるものが多いが、カスタマイズは難しい。

5.3 サーバ管理の効率化 ……Puppet

サーバ管理を自動化するツールとして、Puppetが紹介されている。Puppetは、ファイルのパーミッションや、ソフトウェアパッケージ、ユーザ・グループなどのあるべき状態を定義し、自動的にその定義に適した状態にする。構築時から運用中も使えるツールだろう。
SIだと、このあたりの作業はほぼ手作業でやる。運用中の設定変更は、めったにおこなわれない前提だ。

5.5 ネットワークブートの活用 ……PXE、initramfs

ネットワーク経由でブートイメージを転送して、そのイメージでサーバを起動する。このネットワークブートによって、ディスクレスでサーバを動かし、故障率を下げるという手法が紹介されていた。また、サーバの役割を変更するにも、ネットワークブートを使えば別のブートイメージで起動し直すだけなので、容易に構成変更が可能と。
このへんはSIには縁のないところです。

5.6 リモートメンテナンス ……メンテナンス回線、シリアルコンソール、IPMI
5.7 Webサーバのログの扱い ……syslog、syslog-ng、cron、rotatelogs

サーバに障害が発生した場合に、リモートから対応するための手段として、メンテナンス用の外部回線の用意、シリアルコンソールを別のサーバにつないでおく、といった手法が紹介されていた。
SIだと外部からアクセスするなんてもってのほかで、メンテナンス用のネットワークを組んでも、それは外部に抜けられない閉じたものとする。


ログに関しては、ログの集約やローテーションについて触れられていた。syslogサーバを立てて、そこにログを集約するという手法も紹介されていた。
SIでは、ログの集約を行うところは少ない。監視に使用しているソフトがログ監視も兼ねているため、監視段階では集約しているが、ログ自体は各サーバが個別に持っていることが多い。

6章 あのサービスの舞台裏 ……自律的なインフラへ、ダイナミックなシステムへ

6.1 はてなのなかみ
6.2 DSASのなかみ

ここは割愛。

本書で触れていないこと

バックアップ

バックアップの目的としては、二つ考えられる。随時更新されるデータの保全と、システム復旧時間の短縮だ。
データ保全という意味では、バックアップ対象は更新データとなる。ファイルの場合もあるが、ここではDBのバックアップについて触れる。
SIでDBのバックアップを取得する際は、データの完全性が求められる。DB稼働中にバックアップを取得しようとすると、取得中にデータが更新されてしまうことがあり、データの整合性がとれなくなってしまう。そのため、DBを止めてオフラインバックアップを取得する必要がある。DBを止められるタイミングが限られている場合にも、日次でオンライン、週次でオフラインといったように、必ずバックアップ計画にオフラインバックアップを組み込む。バックアップの際にDBを止める時間を如何に短くするかという課題があり、その課題を解決するため、たとえばレプリケーションしているDBを切り離して、そこからバックアップを取得するという方法もある。
どの段階までデータを戻せればよいかという要件も重要だ。データをもらって処理するようなシステムでは、その入力データさえあればDBのデータを復元できる場合もあり、そういう場合は1週間前までとか、1ヶ月まえに戻ればよいという要件もある。障害時の直近まで戻す必要がある場合は、バックアップから戻したあと、さらに多重化したDBのログを使って戻す。
バックアップの取得先には、LTOを使うことが多い。LTO5なら1巻に圧縮3TB格納できる。バックアップデータが大きい場合はLTOが多数格納できるテープライブラリを導入する。他に、外部ストレージをバックアップ先とする場合も、最近増えてきている。
バックアップデータについて、外部に持つ必要があるかどうか、という点を考慮する必要がある。サーバがある施設が全損した場合、外部にバックアップデータがないと復旧が難しい場合もある。LTOなら外部に搬送する場合もあるし、ネットワーク経由でバックアップセンターにバックアップを取得する場合もある。

ジョブ管理

SIで入れるシステムでは、定期的にバッチジョブを流す必要があるものがかなり多い。SIのインフラでは、そのバッチジョブを管理するソフトの導入も範囲に含まれる。こういったソフトは、コマンドをフローチャートのように組んで、一つのジョブを作る。各コマンドの実行結果によって処理を分岐させたり、いくつかのコマンドの終了を待ち合わせたりといったジョブ制御ができる。また、こういったジョブのスケジュールによる自動実行もできる。
もちろん同じようなことをスクリプトで組むこともできる。

まとめ

Web系もSI系も、互いのやり方を知って、よいところは取り入れればよいんじゃないのと思いながら書き進めてきた。SI側としては、高価な専用機やソフトウェアがOSSで置き換えられることに危機感を覚えると共に、大規模なストレージなど金をかけることで実現できている強みなども知ることができたのが収穫だった。だが、Web系の人がこの記事を読んでSIのやり方を知ったところで、参考になる部分があるかというと、ちょっと疑問だ。


繰り返しになるが、ここで取り上げたWeb系というのは以下の本で読んだ内容でしかないし、SI系は僕がこれまで携わったり耳に挟んだプロジェクトでしかないので、全然違うよこんな現場もあるよという指摘があればぜひ。

[24時間365日] サーバ/インフラを支える技術 ~スケーラビリティ、ハイパフォーマンス、省力運用 (WEB+DB PRESS plusシリーズ)
安井 真伸 横川 和哉 ひろせ まさあき 伊藤 直也 田中 慎司 勝見 祐己
技術評論社
売り上げランキング: 11042