千萬級文檔全量重建索引耗時數小時,而日增量僅千條。採用「主索引 + 增量索引」雙層架構:
Query($q, "main;delta"),結果自動合併去重sph_counterCREATE TABLE sph_counter (
counter_id INTEGER PRIMARY KEY NOT NULL,
max_doc_id INTEGER NOT NULL
);
記錄每次主索引重建時的最大文檔 ID,增量索引以此為分水嶺。
source main_src {
type = mysql
sql_host = localhost
sql_user = user
sql_pass = pass
sql_db = test
sql_port = 3306
sql_query_pre = SET NAMES utf8
sql_query_pre = SET SESSION query_cache_type=OFF
# 更新計數器
sql_query_pre = REPLACE INTO sph_counter SELECT 1, MAX(id) FROM documents
# 僅索引歷史數據
sql_query = SELECT id, group_id, UNIX_TIMESTAMP(date_added) AS date_added, title, content
FROM documents WHERE id <= (SELECT max_doc_id FROM sph_counter WHERE counter_id=1)
}
source delta_src : main_src {
sql_query_pre = SET NAMES utf8
sql_query_pre = SET SESSION query_cache_type=OFF
# 僅索引新增數據
sql_query = SELECT id, group_id, UNIX_TIMESTAMP(date_added) AS date_added, title, content
FROM documents WHERE id > (SELECT max_doc_id FROM sph_counter WHERE counter_id=1)
}
index main {
source = main_src
path = /var/lib/sphinx/main
charset_type = utf-8
chinese_dictionary = /usr/local/sphinx/etc/xdict
}
index delta : main {
source = delta_src
path = /var/lib/sphinx/delta
}
searchd --stop
indexer -c /etc/sphinx/sphinx.conf --all
searchd -c /etc/sphinx/sphinx.conf
或熱構建:indexer --all --rotate(無需停止 searchd)。
build_delta_index.sh#!/bin/bash
searchd --stop
indexer -c /etc/sphinx/sphinx.conf delta
indexer -c /etc/sphinx/sphinx.conf --merge main delta --rotate
searchd
關鍵點:--merge main delta 將增量合併入主索引,--rotate 通知 searchd 載入新索引。
build_main_index.sh#!/bin/bash
searchd --stop
indexer -c /etc/sphinx/sphinx.conf main
searchd
crontab -e
# 每 30 分鐘增量
*/30 * * * * /bin/sh /usr/local/sphinx/etc/build_delta_index.sh > /dev/null 2>&1
# 每日 02:30 全量
30 2 * * * /bin/sh /usr/local/sphinx/etc/build_main_index.sh > /dev/null 2>&1
Query($q, "main;delta"),可將合併頻率降為每日 1-2 次path = /dev/shm/delta,極大提升重建與查詢速度,重啟後自動從主索引恢復distributed 索引聚合結果INSERT/REPLACE/DELETE 實時寫入,無需增量重建,適合極高實時性場景sql_query_pre 數量必須主增量一致,否則字段映射錯位REPLACE INTO sph_counter 需事務隔離級別支持,建議 READ COMMITTEDcharset_type=utf-8 + chinese_dictionarysetenforce 0 或配置策略