メールの仕組みって、RFCに規定されたものを読めば理解出来る..と言いつつ、実は
読んでもいないし、読んでも何を言われているのかさっぱり??..ってことですかね
その前に、ソケット通信とはなんぞや..とか、TCPとUDPの違いは?..などと、事前
知識があってあたりまえってことで、それも説明し出すと聞く方が長くて耐えられ
ない..ってことなんでしょうか?
まぁ、なんか書くだけ書いてみます。当たり前の話で恥ずかしいんですけどね。
メールが、送信側サーバから受信側サーバに送られ、メールボックスにおさまるまで
の話に限定してみます。
まず、受信側のサーバですが、常時25番ポートという入り口を開けて、いつでもメー
ルが受け付けられるように動いています。
送信側サーバは、その入り口に向けて、メールを送ればいいのですが、世界中のどの
メールサーバに送ったらいいのか?というのを、何で判断するか….これを勘違いし
ている人が多いんですね
「そりゃ、To:とかCc:とかに書いた宛先を見て送るんだろうよ..」
「それがどこに書いてあるかって? ヘッダに書いてあるじゃんか!」
..って勘違いですね。
ヘッダにBccなんて書いていないのに、なぜ届くか?..と言えば、それが間違いである
のは理解いただけると思います。
実際には、エンベロープと呼ばれる「受信者のメールボックスには入らないけど、
サーバ上では付加されている情報」を見て判断しています。
メール1本のToやCcなどの中に、複数の会社の宛先を入れると、送信側のメールサーバ
は、複数の受信側メールサーバにメールを送ることになりますが、話を簡単にするため
に、そのうちの、1社に送られたものを対象に話を進めます。
受信側メールサーバに送られるメールには、同じ会社のAさん、Bさん、CさんにCcがつ
いていると思ってください。それでも、メールはまだ、その会社内の宛先を複数含む
1つのメールとして送られてきます。
このメールに、他社の社員のDさんにもCcがついていた場合であっても、受信側メール
サーバに到達した時点での、このメールの「エンベロープ」には、もうDさんの情報は
書かれていない状態になっています。送信側で、送り先の受信側サーバに配送を要求
することのないエンベロープ宛先を取り除くからです。
さて、受信側サーバに到着し始めたメール(メールは一瞬で届くわけではなく、メール
のサイズによっては結構な時間をかけて届きます)は、まずエンベロープやヘッダなど
から順に受け付けられ、メール本文や添付ファイルも全部受け取り、それを「メモリ上
ではなくハードディスクなどの不揮発記憶装置に書き込み終えてから」受け取り成功の
アンサを返すことになっています。
これ、厳密に言うと、ほとんどのソフトはそこまで本当に厳密には動いていなくて、
ライトバックキャッシュや、HDDに組み込まれているキャッシュに入りきり、OSに対す
る書き込み系システムコールが成功したら、成功としているんですけどね。
ハードウェアのキャッシュをライトスルーにして、かつ、OSでsyncモードでマウント
したファイルシステムに受信内容を書くのが、もっとも厳密なわけですけど、それを
やるとディスクの物理速度に足を引っ張られて、大幅にパフォーマンスダウンしてし
まうので、そこまではしないのが普通です。
良いRAIDはキャッシュをSRAMバッテリバックアップで持たせ、さらにサーバもUPSで守り、
停電ぐらいでは「書いたはずだが停電したら1ファイル無くなってる」なんてことを防ぐ
ようにするからです。
あ….話が脱線しました。
一般には、受信し終えたときにディスクに書き込まれるファイルは、メールボックスに
直接入るのではなく、一時ファイルとして記録されます。
大きなメールでは、受信完了までに長い時間がかかるため、別のサーバから、別のメー
ルが次々届くことになります。そういうことに対応できるように、メールサーバは、
マルチスレッドやマルチプロセスで並列処理を行い、1つのメールの受信中にも、別の
スレッドが25番ポートへの着信を待ち受け、次々並列処理で受信が行えるようになって
います。
とはいえ、サーバも無限大の能力があるわけではないですから、並列で受信できる数の
上限は定められているか、設定による可変の上限値が与えられています。
これを超えた並列度でメールが送りつけられてくると、「どのスレッドも25番ポートで
待ち受けていない」状態が生じます。すると、その状態で新たに接続しに来た別のサー
バにとっては、接続を受け付けてもらえない状態が生じるようになります。
….あぁ….どんどん脱線する….
そういうのを、ポートによる死活監視を行うタイプのクラスタリングソフトなんかで、
フェイルオーバー型クラスタにしちゃってると、生きているのにフェイルオーバーが
起こる..ってことになるんですが….濃い話なので先に進みます。
さてさて、とりあえずの受信が済み、一時ファイルになったメールは、宛先となる人
全てのメールボックスに格納されなければなりません。
メールボックスへの配送作業は、それ専用の別スレッドで行うソフトが多く、一時ファ
イルを順番に処理できるように工夫されています。
メールボックスに配送する時点で、エンベロープ情報はもう不要になり、取り除かれて
しまいます。
メールボックスは、mbox形式と、maildir形式に大きく二分されますが、1ファイルに
どんどんメールを追記していくmbox形式は、いくらメール数が増えてもファイル数が
増えず、ディレクトリエントリの取得時間が増加することがない反面、壊れると全部の
内容を失う危険もあるわけですが、maildirでは、よっぽどため込まなければ、処理
速度云々の問題までは出ないので、こっちの方が良いかなぁ..と思われます。
で、ここでCGPの「おぉ!」という部分の一つがあるんです。
Ccとか、グループ配信とかで、1つの同じ内容のメールが、多くの人に配送される場合、
CGPでは、maildir形式において、1個しか実体のファイルを配送しないんですね。
他のメールボックスには、あたかも同じファイルがあるかのように見えるような、
「ハードリンク」を貼るだけなんです。で、読み出されてサーバ上から1人が削除を
するたびにハードリンクが減っていき、最後の1人が消した時点で、メールの本体が
実際に削除される….と。
これにより、グループなどの一斉配信系を多用する場合に、ディスク消費量をうんと
少なくできるし、実際に書き込まないのでディスクの物理的動作を軽減することで、
より高速な配送が出来るようになっているんです。
….あぁ….ホントはまだまだ書きたいのに….
これ以上書いても読み切れないでしょうからこの辺で終わりにします。
既に、ここまで読む人は少ないのかなぁ(笑)
-
Pages
-
Categories
-
Archives
ブログロール
-
RSS Feeds
-
Meta