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';
現場で学んだ「血肉となる」経験
- 常にデータをバックアップする: リアルタイムインデックスを使用している場合、データの整合性を保つために、
/var/lib/manticore内のデータファイルをコピーする前にFREEZEコマンドを使用してください。 - Columnar Libraryの活用: 数百万行に対して sum や group by などの計算が必要な場合は、
manticore-columnar-libをインストールしてください。分析スピードはClickHouseに匹敵します。 - システムの監視:
SHOW STATUSコマンドを活用しましょう。私はよく QPS(Query Per Second)や Latency(遅延)の数値を Grafana に送り、システムの健全性を監視しています。 - アプリにはHTTP JSON APIを使用する: デバッグにはSQLプロトコルが便利ですが、コード(Node.js, Go…)を書く際は、ポート9308のHTTP APIを使用する方がロードバランシングに適しています。
Manticore SearchはElasticsearchほど有名ではないかもしれませんが、コストパフォーマンス(P/P)に関しては間違いなく王者です。サーバーリソースを節約しつつ、超高速な検索スピードを維持したいのであれば、今すぐ移行を試してみてください。
設定でエラーが出たり、行き詰まったりしたことがあれば、ぜひ下のコメント欄で教えてください!

