こんにちは、masm11 です。
Postfix3 から、テーブルの種類が増えましたね。 inline, randmap, unionmap, pipemap ですね。
今回、pipemap を使うことで Postfix から PostgreSQL へのクエリを削減 できましたので、ご紹介します。
PostgreSQL へのクエリ
弊社サービス Re:lation は、メールの受信方法として、 「POP受信」と「転送受信」の2種類があります。 POP受信は、メールサーバに POP3 でアクセスしてメールを取得する方法です。 一方、転送受信は、fwd-xxxxxx などというメールアドレスにメールサーバから 転送することで受信する方法です。 今回は転送受信の方についての話になります。
fwd-xxxxxx はお客様によってまた受信箱によって異なり、たくさんあります。 中には解約もしくは受信箱削除等によって既に使えなくなったものもあります。 使えなくなったものをいつまでも処理するわけにはいきませんので、 メールが転送されてきた時に、その fwd-xxxxxx が生きているものかどうかを 判断する必要があります。そのために PostgreSQL にアクセスしています。 この時、pgsql テーブルを使用しています。
PostgreSQL にクエリを投げ、その結果として foo+fwd-xxxxxx
(サンプル) が返るように
してあります。そうすれば、メールはうちのサーバ上では foo というユーザ
宛に届きます。
しかし、このままではいろいろな文字列を PostgreSQL を使って変換しようとして しまいます。
fwd-xxxxxx
foo+fwd-xxxxxx
foo
- From: ドメイン
~.relationapp.jp
等々。
意図しているのは fwd-xxxxxx
→ foo+fwd-xxxxxx
だけですが、
その他のいろいろなものについてクエリを PostgreSQL に投げては失敗しています。
めっちゃ無駄です。
memcache の利用
まず memcache を使う方法が思い浮かびます。
しかしこれはほとんど意味がありません。 Postfix の memcache 対応は、返り値がない場合にはキャッシュしてくれません。
foo+fwd-xxxxxx
や foo
に対応する値は存在しませんので、
これらについてのクエリを何度でも PostgreSQL に投げてしまいます。
(fwd-xxxxxx
→ foo+fwd-xxxxxx
はキャッシュしてくれます)
pipemap の利用
そこで pipemap です。
pipemap は、pipemap:{type1:table1, type2:table2, ...}
という書式で
書きます。こう書くことで、入力をまず type1:table1
に与え、
その出力を次は type2:table2
に与え、そうして最終的な出力を結果とします。
途中で出力がなかった場合は、そこで中断し、出力なしを結果とします。
なので、まず正規表現で文字列をチェックし、 それにパスした場合のみ pgsql に与えればいいわけです。
1つめは、regexp:test-fwd.regexp
とし、test-fwd.regexp の中身は、
/^(fwd-.*)$/ $1
とします。2つめは、pgsql:forward-addresses.pgsql
とし、
forward-addresses.pgsql の中身はこれまでどおりです(省略します)。
こうすることで、まず入力が fwd-
で始まるかをチェックし、
その場合のみ PostgreSQL に投げることができます。
fwd-
で始まらない場合は test-fwd.regexp からの出力がありませんので、
そこで pipemap 処理が中断され、PostgreSQL には投げられません。
これで PostgreSQL へのクエリが削減されました!