При использовании sphinxsearch можно столкнуться с 2-мя неприятными моментами. Во-первых объем индекса не может превышать 4 GB и более этого количества проиндексировано быть не может. Это конечно достаточно не малый объем, но тем не менее играет роль, особенно если бд хранит не только ascii текст. К тому же, некоторые запросы могут отнимать массу времени и сильно нагружать цп. Время отведенное на запрос, а соответственно и нагрузку от него можно отрегулировать добавлением в конце запроса параметров OPTION max_query_time=500 В данном случае время выполнения будет ограничено 500 мс, которых в принципе должно хватать. Однако, когда объем большой за это время у нас может ничего не найтись. Решение двух проблем выше в разбиении индексов и многопоточной обработке. Разобьем сначала индексы нашей огромной бд на части, затем создадим под них распределенный(distributed) индекс. Все лишние параметры в этом конфиге я опущу, дабы не захламлять.
Разбиваем запросы формирующие индексы на основе id на 10 приблизительно равных частей:
source src_test_0
{
sql_query = SELECT id, field FROM table WHERE id % 10 = 0
}
source src_test_1
{
sql_query = SELECT id, field FROM table WHERE id % 10 = 1
}
source src_test_2
{
sql_query = SELECT id, field FROM table WHERE id % 10 = 2
}
source src_test_3
{
sql_query = SELECT id, field FROM table WHERE id % 10 = 3
}
source src_test_4
{
sql_query = SELECT id, field FROM table WHERE id % 10 = 4
}
source src_test_5
{
sql_query = SELECT id, field FROM table WHERE id % 10 = 5
}
source src_test_6
{
sql_query = SELECT id, field FROM table WHERE id % 10 = 6
}
source src_test_7
{
sql_query = SELECT id, field FROM table WHERE id % 10 = 7
}
source src_test_8
{
sql_query = SELECT id, field FROM table WHERE id % 10 = 8
}
source src_test_9
{
sql_query = SELECT id, field FROM table WHERE id % 10 = 9
}
И прописываем параметры индексов:
index index_test_0
{
source = src_test_0
path = /var/lib/sphinxsearch/data/index_test_0
}
index index_test_1
{
source = src_test_1
path = /var/lib/sphinxsearch/data/index_test_1
}
index index_test_2
{
source = src_test_2
path = /var/lib/sphinxsearch/data/index_test_2
}
index index_test_3
{
source = src_test_3
path = /var/lib/sphinxsearch/data/index_test_3
}
index index_test_4
{
source = src_test_4
path = /var/lib/sphinxsearch/data/index_test_4
}
index index_test_5
{
source = src_test_5
path = /var/lib/sphinxsearch/data/index_test_5
}
index index_test_6
{
source = src_test_6
path = /var/lib/sphinxsearch/data/index_test_6
}
index index_test_7
{
source = src_test_7
path = /var/lib/sphinxsearch/data/index_test_7
}
index index_test_8
{
source = src_test_8
path = /var/lib/sphinxsearch/data/index_test_8
}
index index_test_9
{
source = src_test_9
path = /var/lib/sphinxsearch/data/index_test_9
}
Объединяем их в один распределённый индекс:
index index_test {
type = distributed
local = index_test_0
local = index_test_1
local = index_test_2
local = index_test_3
local = index_test_4
local = index_test_5
local = index_test_6
local = index_test_7
local = index_test_8
local = index_test_9
}
Отлично! Проблема с объемом решена, сюда влезет 40 GB проиндексированных данных, что реально до хрена. Проведенные выше манипуляции позволяют нам настроить до 10 распаралелленных потоков, которые будут обрабатывать, каждый свою, часть распределенного индекса. Под каждый поток выделяется 1 ядро, поэтому если на борту меньше 10 ядер, придётся довольствоваться тем что есть и выставить кол-во потоков не более чем количество ядер. В моём случае ядер 16, поэтому смело прописываем:
searchd
{
dist_threads = 10
}