3. Типичные задачи для Web
Массовый импорт данных
Массовый экспорт данных
Расчет рейтингов (например, лучшие вопросы)
Очистка устаревших данных
И вообще все периодические работы
Статистика, статистика, статистика
3
6. Проблемы
1. Скрипт может работать долго
2. Скрипт может в принципе не успевать
обработать нужный объем данных
3. Скрипт может потреблять много ресурсов
4. В каждом скрипте нужно настраивать
окружение: соединение с базой, пути к файлам
и т.п.
5. Не чаще раза в минуту
6
7. Решения
1. Использовать блокировку файлов (flock)
2. Распараллелить обработку. Запускать
несколько процессов
3. Запускать скрипты на отдельной машине.
Использовать scribe для перемещения логов
4. Использовать management command (в
Django), писать весь код в ./lib
Cron плохо масштабируется, дает задержки
7
14. Exchanges
fanout – отправляет во все очереди
direct - по совпадению routing_key
topic – по совпадению (c шаблонами)
headers – на основании аттрибутов
14
15. Что нужно еще ?
1. Протокол передачи параметров задач
2. Получение результатов
3. Слежение за worker – процессами
Нужное количество
Ограничение нагрузки
Борьба с падениями
Борьба с утечками памяти
Удобный мониторинг
15
16. Очередь задач - Celery
1. Работает поверх RabbitMQ, MongoDB, Redis, DB
2. Задача = функция python
3. Удобный интерфейс запуска задач
4. Замена Cron
16
20. Запуск задания
## views.py – код вашего приложения
## Нам нужны обертки для выполнения задач
from tasks import fib
fib.delay(10)
result = fib.delay(20)
print result.get(timeout=10)
PROFIT!!!
20
28. Основы Sphinx
Document – единица информационного
поиска, содержит id, поля
(полнотекстовые), атрибуты (не полнотекстовые).
Index – множество документов, по которым идет
поиск, можно считать «таблицей», физически
набор файлов на диске.
Source – способ пополнения индекса
28
29. Варианты установки
Stand-alone server (API, SphinxQL)
SQL
MySQL
SQL
Application
API, SphinxQL
Sphinx
MySQL storage engine (SphinxSE)
SQL
Application
MySQL
Sphinx
29
31. Пример конфигурации (source)
source ask_question_source {
type = mysql
sql_host = localhost ## и остальные опции
sql_query_range = SELECT MIN(id), MAX(id)
FROM questions
sql_range_step = 1000
sql_query = SELECT id, title, text, rating
FROM questions WHERE id>=$start AND id<=$end
sql_attr_uint = id
sql_field_string = title
sql_field_string = text
sql_attr_uint = rating
}
31
32. Использование API
use Sphinx::Search;
my $sph = Sphinx::Search->new();
$sph->SetMatchMode(SPH_MATCH_ALL);
$sph->SetRankingMode(SPH_RANK_PROXIMITY_BM25);
$sph->SetSortMode(SPH_SORT_RELEVANCE);
$sph->SetFieldWeights({ title => 100, text => 50 });
$sph->SetLimits(0, 10);
$results = $sph->Query("search terms");
my @ids = map { $_->{id} } @{ $results->{matches} };
print @ids;
32
33. Интеграция с Django
from djangosphinx import SphinxSearch
class Question(models.Model):
title = models.CharField(max_length=100)
text = models.CharField(max_length=1000)
rating = models.IntegerField()
search = SphinxSearch(
index='ask_question_idx',
weights={ 'title': 100, 'text': 50, }
)
def search_question(req):
results = Question.search.query(reg.GET['query'])
.order_by('@weight')
...
33
35. Ключевые особенности
1. Легкая интеграция с базами и приложениями
2. Batch и real-time индексы
3. Гибкий язык поисковых запросов
4. SQL – like syntax
5. Хорошие функции релевантности
6. Масштабирование
35
39. Типичный пример использования
import memcache
mc = memcache.Client(['127.0.0.1:11211'], debug=0)
def heavy_func(arg1):
result = db.get('complex sql') ** 100500;
result = template(result)
# some very heavy computation :)
return result
def fast_func(arg1):
result = mc.get(str(arg1))
if mc is None:
result = heavy_func(arg1)
mc.set(str(arg1), result)
return result
39