使える!サーバ運用の実践テクニック

第11回[キャリアアップ編③]varnishを使おう

前回はCDNの話にフォーカスを当てすぎた感がありましたが、今回は少し肩の力を抜いて、前回少し紹介したvarnishを使って、コンテンツ配布のいろいろな構成を作ってみようと思います。

varnishというプロダクトの設定やチューニングに関しては、いろいろなサイトで記載されていたり、勉強会等の資料など充実しているかと思いますが、複数台をつなげたり、さまざまな構成を考えるときのヒントになれば良いな、(筆者を含めて)キャッシュ、varnishに詳しくない人でもそれなりにできることを目標に解説したいと思います。

本検証を行う時点でのvarnishのバージョンは2.1.3系のものです。varnish-2.1.3-1.el5.src.rpmをダウンロードし、インストールを実施しました。初めての方でもイメージがつかみやすいように、以下のような構成ができることを目標に考えてみます。

  • varnishとApacheを1台のサーバに入れてみる
  • varnishとApacheを別々のサーバに入れてみる
  • 親子関係varnish-varnish-Apacheの直列構成を構築する
  • さらにLVSを利用してvarnishを並列化する

varnishとApacheを1台のサーバに入れてみる

OSのインストール方法(環境)によって異なるかもしれませんが、varnish自体のインストールは非常に簡単です。

筆者の作業ログを掲載しようかと思いましたが、バージョンこそ異なるものの、下記サイトの情報がよくまとまっていますので省略します。xcirさん掲載許可ありがとうございます。

xcirさんによるvarnish関連wiki
URL:http://wiki.xcir.net/
vetnishインストール手順
URL:http://wiki.xcir.net/index.php?title=Varnish%E3%82%A4%E3%83%B3%E3%82%B9%E3%83%88%E3%83%BC%E3%83%AB%E6%89%8B%E9%A0%86

さて、実際のインストールですが、IPなどの設定が終わり、Apacheもインストールされている前提で、以下のような構成が完成していることになります。

図1 インストール後の構成
図1 インストール後の構成

インストール後、とりあえずvarnishを起動してみます。

# /etc/init.d/varnish start

稼働しているか確認します。

# ps -d |grep varnish*
3276 ?        00:00:00 varnishd

varnishのステータスを確認します。

# varnishstat

0+00:01:30                                                              testsrv01
Hitrate ratio:        0        0        0
Hitrate avg:     0.0000   0.0000   0.0000

           2          .            .   N struct sess_mem
           1          .            .   N struct smf
           1          .            .   N large free smf
          10          .            .   N worker threads
          10         0.00         0.11 N worker threads created
           1          .            .   N backends
          77         2.00         0.86 SHM records
          77         2.00         0.86 SHM writes
  1073741824          .            .   bytes free
           1         0.00         0.01 N vcl total
           1         0.00         0.01 N vcl available
           1          .            .   N total active purges
           1         0.00         0.01 N new purges added
          90         1.00         1.00 Client uptime

【control+Cで終了】

varnishを停止します。

# /etc/init.d/varnish stop

起動時のパラメータに関しては/etc/sysconfig/varnishに記載されており、バージョン2.1.3時点では以下のようになっています。

DAEMON_OPTS="-a :6081 \
             -T localhost:6082 \
             -f /etc/varnish/default.vcl \
             -u varnish -g varnish \
             -S /etc/varnish/secret \
             -s file,/var/lib/varnish/varnish_storage.bin,1G"

オプションそれぞれの意味

-a待ち受けポート
-T管理画面待ち受けポート
-fvarnishにて行いたいことを定義するファイル
-u実行ユーザ
-Sセキュリティファイル
-sキャッシュの格納先と指定容量

これらを必要に応じて書き換えることができます。たとえば、本番サービスなどで利用する場合、特にDMZセグメントで構成しようと考えるのであれば、-Tの管理画面待ち受けポートは変更するなどした方が良いでしょう。

また、サービスの規模に応じて、-sのキャッシュファイルの場所や容量を変更することになるかと思います。デフォルトでは、/var/lib/varnish/varnish_storage.bin に1Gバイトの容量を確保しますが、大規模コンテンツ、高トラフィックでキャッシュサーバ自体もかなりの台数並べるようなサービスであれば、このデバイス自体をメモリ上にやSSD、f-ioなどの高速デバイスにするかを検討します。

varnishとApacheを別々のサーバに入れてみる

さて、1つの筐体にvarnishとApacheを入れ、稼働を確認することができたなら、次は同居していたApacheを別筐体へ移動してみます。

varnishが入っていた筐体のApacheのプロセスを停止し、新しい筐体にApacheまでイントール、初期設定を行います。ただし、このままでは、varnishを通じてApacheへ通信することができないため、varnish側の以下の設定を変更する必要があります。

/etc/varnish/default.vcl

上記default.vclの内容にApacheの場所を指定するのみですので見てみましょう。backend defaultブロックを見ると以下のようになっていると思います。

backend default {
  .host = "127.0.0.1";
  .port = "80";

backendは活字で想像できるように、varnishの後ろにあるIPとポートを定義します。そのため、127.0.0.1がローカルとして名前解決されれば80ポートへ通信するため、⁠varnishとApacheを1台のサーバに入れてみる」の際はローカル内で解決していたことになります。

図2 varnishとApacheの関係イメージ
図2 varnishとApacheの関係イメージ

今回はこのアドレスとポートをApacheの移動先にするだけで、別々のサーバに配置し疎通することができます。

図3 varnishとApacheの筐体を分けてみるイメージ
図3 varnishとApacheの筐体を分けてみるイメージ

親子関係varnish-varnish-Apacheの直列構成を構築する

先ほどはvarnishとApacheを別々のサーバに分けてみましたが、その間にもう1台varnish用のサーバ(192.168.1.20)を準備し、定義してみます。

サーバ1 192.168.1.10の/etc/varnish/default.vclのbackend定義
backend default {
  .host = "192.168.1.20";
  .port = "6081";
}
サーバ2 192.168.1.20の/etc/varnish/default.vclのbackend定義(新マシン)
backend default {
  .host = "192.168.1.11";
  .port = "80";
}
図4 親子関係(直列構成)のイメージ
図4 親子関係(直列構成)のイメージ

これでvarnish-varnish-Apacheの直列構成ができました。稼働確認に関しては、varnishはvarnishtatでキャッシュがヒットしているかを確認し、Apacheに関してはaccess_logなどからリクエストが届いているか確認します。

さらに、LVSを利用してvarnishを並列化する

LVS自体の機能や設定などについては本連載では省略させていただき、今回は最小限の手間で確認ができるよう、入口と出口のネットワークセグメントを分けることとしました。

yum -y install ipvsadm	※インストール
# ipvsadm ?v ※インストール確認(バージョン表示)
ipvsadm v1.24 2003/06/07 (compiled with getopt_long and IPVS v1.2.0)

# ipvsadm -a -t 192.168.1.10:80 -r 172.20.1.10:6081 ?m ※構成追加
# ipvsadm -a -t 192.168.1.10:80 -r 172.20.1.20:6081 ?m ※構成追加

# ipvsadm ?Ln ※確認
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
  -> RemoteAddress:Port           Forward Weight ActiveConn InActConn
TCP  192.168.1.10:80 rr
  -> 172.20.1.10:6081              Masq    1      0          0         
  -> 172.20.1.20:6081              Masq    1      0          0         

この状態でサーバ配置的には図5のような形となります。

図5 LVSのイメージ
図5 LVSのイメージ

これで172.20.1.xのネットワークは分断されました。取り急ぎ、構成を確認するためのテストとしては、図5の172.20.1.10と172.20.1.20のサーバにvarnishを入れ、172.20.1.100などのサーバにApacheを入れてクライアントからLVS経由にて接続を確認してみましょう。varnishのステータス、Apacheのログ以外に、LVSが正しく172.20.1.10と20に対して処理を与えているかどうかも確認できれば、LVCを入れた目的が果たせたことになります。

図6 varnish並列+親子構成のイメージ
図6 varnish並列+親子構成のイメージ

稼働確認としては、最初の構成から一貫してhttpリクエストを投げてレスポンスがあることを前提に、構成が変わるごとに確認する場所が異なるといったイメージになります。図6のパターンでは以下のようになります。

  • LVSサーバ192.168.1.10では、ipvsadm ?Lnコマンドにより、リクエストの回数が正しく振り分けられていくことを確認します。
y# ipvsadm ?Ln ※確認
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
  -> RemoteAddress:Port           Forward Weight ActiveConn InActConn
TCP  192.168.1.10:80 rr
  -> 172.20.1.10:6081              Masq    1      2          6         
  -> 172.20.1.20:6081              Masq    1      3          4         
  • varnish(172.20.1.10、20、100)では、varnishstatを利用して、Hitrate ratioなどの項目がカウントアップされていくことを確認します。
0+00:03:56                                                              testsrv02
Hitrate ratio:        2        2        2
Hitrate avg:     0.5000   0.5000   0.5000

          65         0.00         0.28 Client connections accepted
        1228         0.00         5.20 Client requests received
           4         0.00         0.02 Cache hits
           4         0.00         0.02 Cache misses
          24         0.00         0.10 Backend conn. success
        1200         0.00         5.08 Backend conn. reuses
          23         0.00         0.10 Backend conn. was closed
        1224         0.00         5.19 Backend conn. recycles  
        1224         0.00         5.19 Fetch with Length
          14          .            .   N struct sess_mem
           0          .            .   N struct sess
           0          .            .   N struct object
           2          .            .   N struct objectcore
           6          .            .   N struct objecthead
           1          .            .   N struct smf
           1          .            .   N large free smf
           1          .            .   N struct vbe_conn
          10          .            .   N worker threads
          10         0.00         0.04 N worker threads created
      236829         0.00      1003.51 N worker threads limited
           1          .            .   N backends
           4          .            .   N expired objects
           4          .            .   N LRU moved objects
         115         0.00         0.49 Objects sent with write
          65         0.00         0.28 Total Sessions
        1228         0.00         5.20 Total Requests
        1220         0.00         5.17 Total pass
        1224         0.00         5.19 Total fetch
      338453         0.00      1434.12 Total header bytes
      673650         0.00      2854.45 Total body bytes
          41         0.00         0.17 Session Closed
        1228         0.00         5.20 Session Linger
         278         0.00         1.18 Session herd
       95763         0.00       405.78 SHM records
        4323	     0.00        18.32 SHM writes
         119         0.00         0.50 allocator requests
           0          .            .   outstanding allocations
           0          .            .   bytes allocated
  1073741824          .            .   bytes free
        1224         0.00         5.19 Backend requests made
           1         0.00         0.00 N vcl total
           1         0.00         0.00 N vcl available
           1          .            .   N total active purges
           1         0.00         0.00 N new purges added
           8         0.00         0.03 HCB Lookups without lock
           4         0.00         0.02 HCB Lookups with lock
           4         0.00         0.02 HCB Inserts
         236         1.00         1.00 Client uptime
  • ApacheHTTPサーバ(192.168.1.100)に関してはあまり説明の必要は無いかと思いますが、varnish側が無応答(varnishstatなどでカウントアップされない)などの場合、/etc/httpd/logs/access_logの内容を確認し、リクエストが届いていることを確認します。

さて今回は、varnishを利用した構成の考え方、検証の行い方などについて書いてみました。実は筆者自信もvarnishを利用した経験が今回初となり、数ヶ月前から手探りで触ったりしています。その際、いろいろなサイトに助けを求めながら調べるのですが、大半のサイトではある程度の前提をもとに説明されていたので、varnishを知らない方でもある程度の構成が組めることができればと思って記載してみました。

ここまでできれば、次は実際の利用用途などを考えながらの構成設計となります。実際にサービスに利用する前提においては、各定義を入れていく必要があるかと思いますが、それらに関しては参考になるサイトがいくつもありますので、そちらを参照頂ければと思います。

また、実際にサービスで利用するページ、コンテンツなどの量によって、ハードウェアのスペックやキャッシュとして利用する容量を決定していく必要もあります。これらは実際にベンチマークなどを取得して傾向を分析する必要などもあり、定義内容以外の細かいtipsやポリシー決め、ベンチマーク方法などに関しては、次回紹介できればと思います。

おすすめ記事

記事・ニュース一覧