Manticore Search:サーバーのRAM不足を解消するElasticsearchの「救世主」的代替案

Database tutorial - IT technology blog
Database tutorial - IT technology blog

Elasticsearchのメモリ消費量にお悩みの方へ…

約1年前、私は5,000万件ほどの記事を抱えるニュースサイトのシステム最適化を担当しました。当時、チームは16GBのRAMを搭載した VPS上でElasticsearchを運用していました。しかし、データの再インデックス(re-index)を行うたびに、あるいはトラフィックが急増するたびに、Java Virtual Machine (JVM) がオーバーロードでクラッシュするという事態に見舞われていました。

さまざまな方法を検討した結果、すべてのシステムを Manticore Search へ移行することに決めました。その結果は驚くべきものでした。RAMの消費量は14GBから2GB足らずにまで激減したのです。検索スピードは同等か、複雑なクエリに関しては以前よりもスムーズになりました。ManticoreはSphinx Searchから派生(fork)したプロジェクトですが、現代化が進んでおり、リアルタイムインデックス(Real-time index)に対応し、非常に軽量です。

5分でできるManticoreのインストール

今回はUbuntu 22.04/24.04で手順を進めます。Manticoreは現在普及している主要なLinuxディストリビューションのほとんどをサポートしています。

ステップ1:リポジトリの追加とインストール

# 公式リポジトリのインストール
wget https://repo.manticoresearch.com/manticore-repo.noarch.deb
sudo dpkg -i manticore-repo.noarch.deb
sudo apt update

# manticoreと追加パッケージのインストール
sudo apt install manticore manticore-extra -y

ステップ2:サービスの起動

sudo systemctl start manticore
sudo systemctl enable manticore

ステップ3:MySQLプロトコル経由でのクエリ

Manticoreの最大のメリットは、MySQLプロトコルをサポートしている点です。Elasticsearchのような複雑なJSON構文を学習する必要はありません。使い慣れたSQLコマンドを使用するだけです。

mysql -h 127.0.0.1 -P 9306

テーブルを作成してテストデータを挿入してみましょう:

-- テーブル作成とテストデータの挿入
CREATE TABLE products(title text, price float) realtime;
INSERT INTO products(title, price) VALUES ('iPhone 15 Pro Max', 1200.50);
SELECT * FROM products WHERE MATCH('iphone');

なぜElasticsearchではなくManticoreを選ぶのか?

ビッグデータを扱う際、インフラコストは死活問題です。Elasticsearchは強力ですが、JVM上で動作するためリソースを大量に消費します。対照的に、ManticoreはC++で記述されており、中間仮想化レイヤーなしでハードウェアの性能を最大限に引き出します。

  • RAMの節約: 同じデータセットでも, ManticoreのRAM消費量はElasticsearchの約10分の1です。4GB RAMのサーバーでも数千万件のレコードを容易に処理できます。
  • SQLフレンドリー: PHP、Python、Node.jsなどのMySQLライブラリを使用してポート9306経由で接続できます。Web開発者にとって非常に便利です。
  • 即時起動: Manticoreの再起動はわずか1〜2秒です。一方、Elasticsearchはステータスが「green」になるまで数分かかることがよくあります。
  • 高度な全文検索: 形態素解析、重み付け、非常に正確なファジー検索(曖昧検索)をサポートしています。

実践的な本番環境の設定

設定ファイルは /etc/manticoresearch/manticore.conf にあります。古い静的なファイル形式ではなく、より柔軟な Real-time (RT) index の使用をお勧めします。

MySQLやPostgreSQLから定期的にデータを読み込む必要がある場合は、以下の source 設定例を参考にしてください:

source src_products {
    type = mysql
    sql_host = localhost
    sql_user = your_user
    sql_pass = your_password
    sql_db = your_database
    sql_port = 3306
    sql_query = SELECT id, title, content, created_at FROM articles
}

index idx_articles {
    source = src_products
    path = /var/lib/manticore/idx_articles
    morphology = stem_en # 英語の語幹処理(ステミング)
    min_word_len = 1
}

設定を保存した後、以下のコマンドを実行してインデックス作成を開始します:

indexer --all --rotate

多言語対応とパフォーマンスの最適化

1. アクセントの有無を問わない検索

Manticoreが特殊文字を理解するには charset_table が必要です。特定の言語(ベトナム語など)で正確に検索するには、クエリ時にアクセントの有無を自動的に正規化する「folding」設定を定義する必要があります。

私の経験では、設定ファイルで完全な文字セットテーブルを使用することで、ユーザーがアクセントなしで入力しても、正しい結果を返せるようになります。

2. Distributed Index(分散インデックス)

データが数億行に膨れ上がると、1台のサーバーでは支えきれなくなります。その場合は、Distributed Index を使用して複数のノードからの結果を統合します。

CREATE TABLE remote_index TYPE='distributed' local='idx_part1' remote='192.168.1.10:9312:idx_part2';

現場で学んだ「血肉となる」経験

  1. 常にデータをバックアップする: リアルタイムインデックスを使用している場合、データの整合性を保つために、/var/lib/manticore 内のデータファイルをコピーする前に FREEZE コマンドを使用してください。
  2. Columnar Libraryの活用: 数百万行に対して sum や group by などの計算が必要な場合は、manticore-columnar-lib をインストールしてください。分析スピードはClickHouseに匹敵します。
  3. システムの監視: SHOW STATUS コマンドを活用しましょう。私はよく QPS(Query Per Second)や Latency(遅延)の数値を Grafana に送り、システムの健全性を監視しています。
  4. アプリにはHTTP JSON APIを使用する: デバッグにはSQLプロトコルが便利ですが、コード(Node.js, Go…)を書く際は、ポート9308のHTTP APIを使用する方がロードバランシングに適しています。

Manticore SearchはElasticsearchほど有名ではないかもしれませんが、コストパフォーマンス(P/P)に関しては間違いなく王者です。サーバーリソースを節約しつつ、超高速な検索スピードを維持したいのであれば、今すぐ移行を試してみてください。

設定でエラーが出たり、行き詰まったりしたことがあれば、ぜひ下のコメント欄で教えてください!

Share: