2 июля 2011, Я.Субботник в Екатеринбурге
Леонид Васильев "Python в инфраструктуре поиска"
О докладе:
Описание архитектуры и реализации внутренних инструментов для управления поисковым кластером.
Что такое инфраструктура поиска? Какие задачи приходится решать? Какие инструменты для управления кластером используются в поиске? Как они устроены изнутри? Что можно посоветовать проектам с большой инфраструктурой? Какие существуют open-source аналоги?
2. Инфраструктура поиска
Проблемы:
— Тысячи серверов в нескольких датацентрах
— Постоянный поток новых серверов
— Сервера ломаются и демонтируются
— Много активного сетевого оборудования
— Отключения питания и ошибки сети
— Разные ОС: Linux, FreeBSD
2
4. Как управляем кластером?
Наши инструменты:
— Skynet: выполение Python кода на кластере
— Sandbox: сборка, тестирование и выкладка
программ на кластер
— И т. д. Инструментов у нас много :)
4
6. Skynet: пример проблемы
Дедушкин метод:
#!/bin/sh
SCRIPT_NAME='/home/my_name/check_something.sh'
for host in serv{1..50}; do
echo "Checking $host"
scp "$SCRIPT_NAME" "$host:/$SCRIPT_NAME"
ssh $host "sh $SCRIPT_NAME"
done
6
7. Skynet: пример проблемы
Современный подход:
#!/usr/bin/env python
from skynet import client
class CheckSomething:
def __init__(self, config): self.config = config
def run(self): return self.check_something()
def check_something(self): pass # check using config
if __name__ == "__main__":
c = client.Client()
c.run("serv{1..50}", CheckSomething({'debug': True}))
c.wait()
print c.result()
7
8. Skynet: пример проблемы
Сравнение
Дедушкин метод: Современный подход:
системные требования системные требования
функционал функционал
поддержка поддержка
кроссплатформенность кроссплатформенноcть
8
9. Skynet: как это работает?
— code = pickle.dumps(Task())
— modules = Zipfile.PyZipFile(sys.modules)
— Передаем (code, modules) на клиента
— import modules.zip
— result = pickle.loads(code.pсkl).run()
— Передаем result на сервер
9
10. Skynet: копирование данных
Используем torrent:
#!/usr/bin/env python
from skynet import copier
def share(files):
c = copier.Copier()
return c.create(files).torrent
def download(torrent, dest_dir):
c = copier.Copier()
c.get(torrent, dest_dir).wait()
10
11. Skynet: зачем torrent?
— Хорошо ложится на распределённую
архитектуру
— Высокая отказоустойчивость
11
13. Sandbox: что это?
Небольшой кластер (десятки серверов) и среда
выполнения, которые нужны
Разработчикам: для сборки и отладки
программ на разных архитектурах (linux,
freebsd) и моделях CPU.
Тестировщикам: для проведения
ресурсоёмких тестов
Администраторам: для внедрения программ в
production систему
13
15. Sandbox:главные сущности
— Task: контейнер для кода и состояния,
который будет выполняться на клиенте
— Ресурс: описывает данные, которые Task'и
используют/создают в процессе работы
— Контекст выполения: параметры Task'а,
которые были заданы при его создании
(через веб-интерфейс или xmlrpc)
15
17. Sandbox: типовой сценарий
— Грузим файлы необходимые для сборки
— Собираем проект#1
— Собираем проект#2
— Тестируем проект#1 и проект#2
— Получаем результаты от проекта#1 и
проекта#2
— Сравниваем результаты проекта#1 и
проекта#2
17
18. Sandbox: использование API
Сборка проекта:
def build(branch, owner):
con = xmlrpclib.ServerProxy('http://sandbox/xmlrpc')
task_id = con.createTask({...})
while True:
status = con.getTaskStatus(task_id)
if not is_in_progress(status):
break
time.sleep(1)
if is_failed(status):
raise Exception(...)
return con.listTaskResources(task_id)
def main():
print build("branches/my_project/rel-1.0.0", "chin")
18
22. Полезные практики
Крайне полезно иметь в проекте:
— Хранилище файлов необходимых для сборки,
отладки, профилирования и тестирования.
— Список релизов с веб-интерфейсом в котором
есть иноформация о том, что, когда и куда
выкладывалось.
— Утилиту или framework для выполнения
скриптов на всем кластере.
22