Настраиваем сервер для LiveStreet. Часть VIII. APC, Memcached & Sphinx.

Предыдущие части:

На мой взгляд, на данный момент, есть только два осмысленных варианта настроить кэширование кода и данных (учитывая то, что LiveStreet поддерживает, конечно). Первый вариант — APC + Memcached. Второй вариант — XCache.

Почему?
  • Во-первых все остальные PHP оптимизаторы(eAccelerator, например) сильно проигрывают современным версиям APC и XCache. Всесторонне, особенно в разрезе надёжности. ( Особый случай это ZendOptimiser+ — оно, по отзывам, быстрое и надёжное, но не очень открытое и не очень бесплатное. И я, лично, не тестировал )
  • Во-вторых, как opcode кэшер APC, актуальных версий, лучше XCache. И быстрее и стабильней. Да, это субъективное мнение. Да, выигрыш незначителен. Но лучше. :)
  • А вот с кэшированием данных XCache справляется намного лучше Memcached. И поэтому если говорить именно об общей производительности, то выигрывает XCache. И это вполне ожидаемо, учитывая что Memcached — софт предназначенный, прежде всего, для многосерверных конфигураций.

Из вышеописанного проистекает моё личное мнение:
  • Высокая надежность и хорошая производительность = APC + Memcached( и ниже будет описан именно этот вариант).
  • Максимально возможная производительность с приемлемой надёжностью = XCache.

Еще одно важное замечание: коммуникации между сервисами лучше настраивать не через TCP/IP, а через UNIX socket. В рамках «всё на одном сервере» это и быстрее и надёжней. Именно таким образом настраивалась связка Apache + php-fpm в прошлых частях. Таким же образом, по возможности, будем действовать и дальше.

Читать дальше →

Sphinx и PHP 5.3.21

Пытаюсь завести сфинкс на PHP 5.3.21, где API сфинкса уже впилено в сам PHP:
sphinx support	enabled
Version	1.1.0

Конечно, стало ругаться на то, что классы уже определены. Закомментил следующую строку в /classes/modules/sphinx/Sphinx.class.php:
require_once(Config::Get('path.root.engine').'/lib/external/Sphinx/sphinxapi.php');

Ошибки ушли, но поиск не дает результатов.

Самое странное, что подобной ситуации со встроенным в PHP сфинксапи вообще не гуглится.

Индексы создаются, но на сайте поиск выдает пустой результат. В какую сторону копать?

config.php поиска:
source site1
{
    type				= mysql
	sql_host			= localhost
	sql_user			= site1_user
	sql_pass			= 123123123
	sql_db				= site1
	sql_port			= 3306	# optional, default is 3306
	sql_query_pre		= SET CHARACTER_SET_RESULTS=cp1251
}

source elements: site1
{
    sql_query_range		= SELECT MIN(topic_id), MAX(topic_id) FROM phpbb_topics
    sql_range_step		= 1000

	sql_query = SELECT \
                    topic_id, \
                    forum_id, \
                    topic_title, \
                    topic_poster, \
                    topic_replies, \
                    topic_views, \
                    topic_last_post_id  \
                FROM \
                    phpbb_topics \
                WHERE topic_id >= $start AND topic_id <= $end

	sql_attr_uint	= topic_poster
    sql_attr_uint   = topic_replies
    sql_attr_uint   = topic_views
	sql_attr_uint	= forum_id
    sql_attr_uint	= topic_last_post_id
}

source posts: site1
{
    sql_query_pre		= SET CHARACTER_SET_RESULTS=cp1251
    sql_query_pre       = REPLACE INTO sph_counter SELECT 1, MAX(post_id) FROM phpbb_posts_text
    
    sql_query_range		= SELECT MIN(post_id), (select max_doc_id from sph_counter) FROM phpbb_posts_text
    sql_range_step		= 1000

	sql_query = SELECT \
                    pt.post_id, \
                    p.poster_id, \
                    p.post_time, \
                    t.topic_id, \
                    t.forum_id, \
                    f.cat_id, \
                    p2.post_time as last_post_in_topic_time, \
                    pt.post_text as text, \
                    t.topic_title as title \
                FROM \
                    phpbb_posts_text pt \
                INNER JOIN \
                    phpbb_posts p on p.post_id = pt.post_id \
                INNER JOIN \
                    phpbb_topics t on p.topic_id = t.topic_id \
                INNER JOIN \
                    phpbb_posts p2 on t.topic_last_post_id = p2.post_id \
                INNER JOIN \
                    phpbb_forums f on t.forum_id = f.forum_id \
                WHERE pt.post_id >= $start AND pt.post_id <= $end

    sql_attr_uint       = last_post_in_topic_time
	sql_attr_uint       = poster_id
    sql_attr_uint       = topic_id
    sql_attr_uint       = forum_id
    sql_attr_uint       = cat_id
	sql_attr_timestamp	= post_time
}

source delta: posts
{
    sql_query_pre		= SET CHARACTER_SET_RESULTS=cp1251
    sql_query_range		= SELECT (select max_doc_id from sph_counter), MAX(post_id) FROM phpbb_posts_text
}

index topics
{
    docinfo			= extern
	morphology		= stem_enru
	stopwords			=
	min_word_len		= 1
	charset_type		= sbcs
	charset_table		= 0..9, A..Z->a..z, _, a..z, U+A8->U+E5, U+B8->U+E5, U+C0..U+DF->U+E0..U+FF, U+E0..U+FF
	min_prefix_len		= 0
	min_infix_len		= 0
    
    path			= /var/lib/sphinx/site1/topics
    source			= elements
    
    html_strip      = 1
}

index doubles: topics
{
    source          = elements
    path			= /var/lib/sphinx/site1/doubles
}

index posts: topics
{
	path			= /var/lib/sphinx/site1/posts
    source			= posts
}

index delta: posts
{
    path			= /var/lib/sphinx/site1/delta
    source			= delta
}

source site2
{
        type            = mysql
        sql_host        = localhost
        sql_user        = site2ls_user
        sql_pass        = 123123123
        sql_db          = site2ls
        sql_port        = 3306
#        sql_sock        = /var/run/mysqld/mysqld.sock
   
       
        mysql_connect_flags     = 32 
   
        sql_query_pre                   = SET NAMES utf8
        sql_query_pre                   = SET SESSION query_cache_type=OFF    
}
 
source topicsSource : site2
{
        sql_query               = \
                SELECT t_fast.topic_id, t_fast.topic_title, UNIX_TIMESTAMP(t_fast.topic_date_add) as topic_date_add, \
                tc.topic_text, t_fast.topic_publish \
                FROM prefix_topic as t_fast, prefix_topic_content AS tc \
                WHERE t_fast.topic_id=tc.topic_id AND t_fast.topic_id>=$start AND t_fast.topic_id<=$end
 
        sql_query_range         = SELECT MIN(topic_id),MAX(topic_id) FROM prefix_topic
        sql_range_step          = 1000
        sql_attr_uint = topic_publish
        sql_attr_timestamp      = topic_date_add
        sql_attr_multi  = uint tag from query; SELECT topic_id, topic_tag_id FROM prefix_topic_tag
        sql_ranged_throttle     = 0
}
 
source commentsSource : site2
{
        sql_query               = \
                        SELECT comment_id, comment_text, UNIX_TIMESTAMP(comment_date) as comment_date, comment_delete \
                        FROM prefix_comment \
                        WHERE target_type='topic' AND comment_id>=$start AND comment_id<=$end AND comment_publish=1
 
        sql_query_range         = SELECT MIN(comment_id),MAX(comment_id) FROM prefix_comment
        sql_range_step          = 5000
 
        sql_attr_uint = comment_delete
        sql_attr_timestamp      = comment_date
}
 
index topicsIndex
{
        source                  = topicsSource
        path                    = /var/lib/sphinx/site2/topicIndex
        docinfo                 = extern
        mlock                   = 0
        morphology = stem_enru
        charset_type            = utf-8
        html_strip                              = 1
        html_remove_elements = style, script, code
}
 
index commentsIndex
{
        source                  = commentsSource
        path                    = /var/lib/sphinx/site2/commentsIndex
        docinfo                 = extern
        mlock                   = 0
        morphology = stem_enru
        charset_type            = utf-8
        html_strip                              = 1
        html_remove_elements = style, script, code
}

indexer
{
    mem_limit           = 100M
}

searchd
{
    listen                  = localhost:3312
    log                     = /var/log/sphinx/searchd.log
    query_log               = /var/log/sphinx/query.log
    read_timeout            = 5
    max_children            = 30
    pid_file                = /var/run/sphinx/searchd.pid
    max_matches             = 10000
    seamless_rotate         = 1
    preopen_indexes         = 0
    unlink_old              = 1
}
 

Sphinx - результаты поиска (сортировка - сначала новые)

Здравствуйте, очень остро встал вопрос по Sphinx и его результатам поиска, он выводит по какому своему алгоритму, но топики выводятся сначала старые, может кто-нибудь задавался вопросом, как можно перевернуть результаты, а именно сделать сортировку по дате добавления топика.
Данный вопрос очень важен так как сайт новостной и пользователь должен видеть все новинки в первую очередь а не новости за 2010 год, догадаться пролистать на последнюю не у всех к сожалению ума хватит, вот и прошу подсказки и помощи у уважаемых пользователей полюбившегося мне проекта livestreet.ru, надеюсь не оставите без наводки или подсказке, где именно копать в конфиге ЛС, или перестройка запросов в conf файле Sphinx?

Sphinx - ограничение на поиск более 100 страниц [РЕШЕНО]

Здравствуйте, сегодня столкнуся с проблемой, на сайте более 70 тыс топиков, настроил Сфинкс, все работает, отдает результаты поиска, НО
когда ввожу запрос на который выводится более 4000 результатов, пробую перейти на последнюю страницу сайт отдает ошибку


Системная ошибка, повторите позже

Вернуться назад, перейти на главную



Проблема любого запроса начинается с 101 страницы, на 100ой пагинация есть и результаты.

Уважаемые гуру сайта помогите решить проблему, по логам сфинкса все окей, работает как часы, но с это проблемой не понимаю что делать.
Если кто-то знает куда копать отзовитесь буду вам очень признателен.

С помощью умельца 1099511627776 проблема была решена.

Спасибо вам 1099511627776 огромнейшее!

Оптимизация индексирования Shpinx для LiveStreet, исправляем древнюю проблему с закрытыми блогами

Суть проблемы — LS ищет и находит сфинксом заметки и комментарии из всех блогов, независимо от того имеете вы к ним доступ или нет.

Чинится это просто:
  1. вносим в поисковый индекс id закрытого блога к которому относится топик или комментарий, либо 0 если этот блог не закрытый.
  2. передаём в поиск id текущего пользователя
  3. находим список закрытых блогов в которые имеет доступ текущий пользователь.
  4. используем этот список расширенный нулём (что добавит все не закрытые блоги в результаты поиска для любого пользователя) со стандартной возможностью фильтрации Сфинкса


Читать дальше →

Настройки SphinxSearch 2.0.4 поставленного в Ubuntu 12.04 командой apt-get

Я ставил Sphinx на Ubuntu 12.04. Использую облачный сервер Selectel, поэтому все операции выполнялись под root.
  1. В Ubuntu SphinxSearch 2.0.4 ставится простой командой
    apt-get install sphinxsearch

  2. Правим файл /etc/default/sphinxsearch и ставим START=yes
  3. Создаем файл /etc/sphinxsearch/sphinx.conf
    Я изначально взял отсюда: Sphinx. Установка и первичная настройка, и поправил пути, а также заменил deprecated address на listen.

    Также оказалось что таблица topic_comment теперь называется comment, поправил это тоже.
    ## Конфигурационный файл Sphinx-а для индексации Живой улицы
    
    #######################
    #
    # Описываем индексы
    #
    #######################
    
    # Источник-родитель для всех остальных источников. Здесь указываются параметры доступа 
    # к базе данных сайта
    source lsParentSource
    {
    	type		= mysql
    	sql_host	= localhost
    	sql_user	= root
    	sql_pass	= 
    	sql_db		= livestreet
    	sql_port	= 3306
        	# Для ускорения работы прописываем путь до MySQL-го UNIX-сокета (чтобы 
    	# операции с БД происходили не через TCP/IP стек сервера)
        	sql_sock	= /var/run/mysqld/mysqld.sock
        
        	
    	mysql_connect_flags	= 32 # 32- включение сжатие при обмене данными с БД
        
    	# Включам нужную кодировку соединения и выключаем кеш запросов
    	sql_query_pre			= SET NAMES utf8
        	sql_query_pre			= SET SESSION query_cache_type=OFF    
    }
    
    # Источник топиков
    source topicsSource : lsParentSource
    {
    	# запрос на получения данных топиков
    	sql_query		= \
    		SELECT t_fast.topic_id, t_fast.topic_title, UNIX_TIMESTAMP(t_fast.topic_date_add) as topic_date_add, \
    		tc.topic_text, t_fast.topic_publish \
    		FROM prefix_topic as t_fast, prefix_topic_content AS tc \
    		WHERE t_fast.topic_id=tc.topic_id AND t_fast.topic_id>=$start AND t_fast.topic_id<=$end
    
    	# запрос для дробления получения топиков на неколько итераций
    	sql_query_range		= SELECT MIN(topic_id),MAX(topic_id) FROM prefix_topic
    	
    	# сколько получать объектов за итерацию
    	sql_range_step		= 1000
    
    	
    	# Указываем булевый атрибут критерия "топик опубликован". Для возможности указания этого критерия при поиске
    	sql_attr_bool		= topic_publish
    
    	# Атрибут даты добавления, типа "время"
    	sql_attr_timestamp	= topic_date_add
    
    	# мульти-аттрибут "теги топика"
    	sql_attr_multi	= uint tag from query; SELECT topic_id, topic_tag_id FROM prefix_topic_tag
    
    	sql_ranged_throttle	= 0
    }
    
    # Источник комментариев
    source commentsSource : lsParentSource
    {
    	sql_query		= \
    			SELECT comment_id, comment_text, UNIX_TIMESTAMP(comment_date) as comment_date, comment_delete \
    			FROM prefix_comment \
    			WHERE comment_id>=$start AND comment_id<=$end
    
    	sql_query_range		= SELECT MIN(comment_id),MAX(comment_id) FROM prefix_comment
    	sql_range_step		= 5000
    
    	sql_attr_bool		= comment_delete
    	sql_attr_timestamp	= comment_date
    }
    
    #######################
    #
    # Описываем индексы
    #
    #######################
    
    index topicsIndex
    {
    	# Источник, который будет хранить данный индекса
    	source			= topicsSource
    	path			= /var/lib/sphinxsearch/data/lstopics
    
    	# Тип хранения аттрибутов
    	docinfo			= extern
    
    	mlock			= 0
    
    	# Используемые морфологические движки
    	morphology		= stem_enru, soundex, metaphone
    
    	# Кодировака данных из источника	
    	charset_type		= utf-8
    
    
    	# Из данных источника HTML-код нужно вырезать
    	html_strip				= 1
    }
    
    # Индекс комментариев
    index commentsIndex
    {
    	source			= commentsSource
    	path			= /var/lib/sphinxsearch/data/lscomments
    
    	docinfo			= extern
    
    	mlock			= 0
    
    	morphology		= stem_enru, soundex, metaphone
    
    	charset_type		= utf-8
    }
    
    #######################
    #
    # Настройки индексатора
    #
    #######################
    
    
    indexer
    {
    	# Лимит памяти, который может использавать демон-индексатор
    	mem_limit			= 32M
    }
    
    #######################
    #
    # Настройка демона-поисковика
    #
    #######################
    
    searchd
    {
            # Адрес, на котором будет прослушиваться порт
            listen                  = 127.0.0.1:3312
    
    	# Лог-файл демона
    	log					= /var/log/sphinxsearch/searchd.log
    
    	# Лог поисковых запросов. Если закомментировать,то логировать поисковые строки не будет
    	query_log			= /var/log/sphinxsearch/query.log
    
    	# Время в секундах, которое ждет демон при обмене данными с клиентом. По исчерпании происходит разрыв коннекта
    	read_timeout		= 5
    
    	# Максимальное количество одновременно-обрабатываемых запросов. 0 означает дофига, а точнее без ограничения
    	max_children		= 30
    
    	# Файл, в который сохраняется PID-процесса при запуске
    	pid_file			= /var/run/sphinxsearch/searchd.pid
    }

  4. Правим настройки для соединения с базой
    source lsParentSource
    {
            type            = mysql
            sql_host        = localhost
            sql_user        = root
            sql_pass        =
            sql_db          = livestreet
            sql_port        = 3306
    

  5. Правим префикс таблиц. В моем случае я заменил все вхождения prefix_ на пустоту. (6 замен)
  6. Индексацию будем делать под пользователем sphinxsearch, для этого надо ему выставить /bin/sh в виде шелла
    chsh -s /bin/sh sphinxsearch

  7. Запускаем индексацию из-под юзера sphinxsearch
    su sphinxsearch -c 'indexer --all'

    Индерксатор не должен выдавать ошибок, и должны появиться файлы индексов в папке /var/lib/sphinxsearch/data/
  8. Запускаем искалку
    service sphinxsearch start

  9. Проверяем, что поиск работает. У меня заработал.
  10. Ставим переиндексацию на крон. Для этого редактируем кронтаб для пользователя sphinxsearch
    su sphinxsearch -c 'crontab -e'

    Выбираем редактор и вводим такие таски
    12 */3 * * *  indexer --rotate topicsIndex > /dev/null 2>&1
    */50 * * * *  indexer --rotate commentsIndex > /dev/null 2>&1

Вопрос к специалистам по sphinx

Требуется помощь специалистов по sphinx.
Ситуация следующая.
Установил все (где-то пол года назад) согласно инструкции в этом топике

Сразу после установки создал индекс, запустил, проверил, на сайте все прекрасно начало искаться.

И вот сегодня по прошествии полугода (поиском не пользовался или просто не обращался внимания) сегодня я выяснил, что он ищет только старые записи, т.е те, которые попали в индекс сразу после установки.
Читать дальше →