Dovecot と Solr で IMAP4 Search を高速化

古いメールをぶちこんだIMAP4サーバを立ち上げて,高速で検索したい…したかったのだった

背景

私は古いメールをとっておくタイプで,大学時代のメールも残ってたりする.
添付ファイルも含めたメールの総サイズは,45GBにのぼる.
メール総数は20万通くらい.

こうなってくると,目的のメールを検索するのも一苦労で,年別にフォルダをわけているものの,何年に受信したメールなのかという記憶の解像度も古いものほど落ちてきて,限界を感じていた.

また,これほどのメールを普段使いのPCに入れておくのは無駄で,自宅内に dovecot-imapd でメールサーバを立てて運用している.

こうした観点から,メールの検索を手軽に高速にするために,サーバサイドの検索手段を導入してみることにした.

手順

  • Solrのコンテナの実行
    • とりあえずテンポラリで動かす
      docker run --name solr --rm -p 8983:8983 solr:9.1.1
      
      これを実行中に、 http://hostname:8983 にアクセスして管理画面が表示されればOK
    • なお最新の9.8ではdovecotの配布するschemaがエラーで読み込みされないため,一旦,9.1.1でやってみた.
      どのバージョンからNGになるかは不明.
  • docker-compose.ymlの作成
    services:
    solr:
      image: solr:9.1.1
        volumes:
        - /opt/solr:/var/solr
        ports:
        - "8983:8983"  # 最終的には "127.0.0.1:8983:8983" とかにすれば,外部からのアクセスは防げる
        command:
        - solr-precreate
        - dovecot  # Coreの名前はdovecotにしておく.なんでもよい
    
  • dovecotのfts_solrを有効化
    • パッケージのdovecotはインストール済・設定済とする

    • プラグインをインストールし,設定を有効化する

      sudo apt install dovecot-solr
      sudo vi /etc/dovecot/conf.d/10-mail.conf
      sudo vi /etc/dovecot/conf.d/90-plugin.conf
      

      編集内容は

      --- 10-mail.conf.org
      +++ 10-mail.conf
      @@ -211,11 +211,11 @@
      #auth_socket_path = /var/run/dovecot/auth-userdb
      
      # Directory where to look up mail plugins.
      -#mail_plugin_dir = /usr/lib/dovecot/modules
      +mail_plugin_dir = /usr/lib/dovecot/modules
      
      # Space separated list of plugins to load for all services. Plugins specific to
      # IMAP, LDA, etc. are added to this list in their own .conf files.
      -#mail_plugins =
      +mail_plugins = fts fts_solr
      
      ##
      ## Mailbox handling optimizations
      
      --- 90-plugin.conf.org
      +++ 90-plugin.conf
      @@ -8,4 +8,16 @@
      
      plugin {
          #setting_name = value
      +  fts = solr
      +  fts_solr = url=http://127.0.0.1:8983/solr/dovecot/
      +  fts_decoder = decode2text
      +  fts_autoindex = yes
      +}
      +
      +service decode2text {
      +  executable = script /etc/dovecot/decode2text.sh
      +  user = nobody
      +  unix_listener decode2text {
      +    mode = 0666
      +  }
      }
      
  • solrの設定
  • インデックスの再作成
    • ユーザ名はIMAPのメールユーザ
      sudo doveadm fts rescan -u hoge  # ユーザhogeのインデックス破棄
      sudo doveadm index -u hoge Archive.2022  # サブフォルダのインデックス作成
      
      • フォルダ名の指定は,Maildirで .MAILDIRNAME.SUBDIRNAME となっているものに対して,先頭のピリオドだけ外して指定する
      • 受信箱は INBOX
  • 動作確認
    • メールサーバ上で行う場合は,こんな感じ
      openssl s_client -connect localhost:993
      1 LOGIN hoge PASSWORD
      2 SELECT Archive.2022
      3 SEARCH CHARSET UTF-8 TEXT "検索キーワード"
      4 FETCH 21 RFC822
      5 LOGOUT
      
    • FETCH の直後の数字は,検索でひっかかったメールの番号
    • ちゃんと動作していると,dockerのsolrコンテナのログ,または /opt/solr/logs/solr.log に検索クエリが流れる
    • solrの管理画面でcoreを選択し,queryのところから body:検索キーワード としても検索結果が出る

結果

検索はできるようになった.
しかし,IMAP4のSEARCHコマンドに対応しているMUA,つまりメーラがなかった.
例えば,SylpheedやThunderbirdなどのIMAP4に対応しているメーラは,メーラ自身がIMAP4からダウンロードしたキャッシュに対して検索インデックスを作成するため,全文検索をしてもsolrのログに検索ログが出てこない.
WebメールなどでIMAPのSEARCHを利用しているものもあるようだが,どれも非常に古くて最終更新から数年が経過しているものが多かった.
今でも更新されているWebメールは逆に,サーバー機能を内蔵していたり,IMAP4に対応していたとしても自前でメールキャッシュを作ってインデックスをはるものが多いようだ.
ということで,doveadmとかopensslで検索はできるのだが,実用はできなさそうである.

残念…

comments powered by Disqus