kranonit S02E01 Дмитрий Свириденко- HTML5: Поздравляю, ты в новой реальности
Kranonit s16 (python). dmitry furzenko
1. Шардинг - что это и как
правильно его готовить.
автор: Дмитрий Фурзенко, Sandstorm NV
2. О себе:
●
●
●
●
●
в сети известен под ником - Dimonji
python developer over 3+ year expirience
pythonic way в разработке
highload системы
Мои инструменты:
○ Pycharm or Emacs
○ Python
○ Brain
○ И очень много разных python библиотек :)
3. Где работал/работаю:
c 08.2011 по текущее время - Sandstorm NV
с 05.2009 по 08.2011 ООО Любимое такси, разработчик
программного обеспечения, системный администратор
4. О чем будет доклад:
● Теория построения шардинга
● SQLAlchemy
● gevent
5. Ингредиенты для шардинга:
● python 2.7
● SQLAlchemy >= 0.7.9
● MySQL or PostgreSQL
● четкое понимание архитектуры приложения
● немного магии
6. Зачем нужен шардинг:
● практически бесконечное горизонтальное
масштабирование production платформы
● отказоустойчивость
● более дешевый production
8. Минусы:
● выборка и обработка всех данных становиться
самым узким местом
● требуется более тщательное проектирование
приложения
● в некоторых моментах приходится пренебрегать т.н
нормальной формой БД
9. Обобщенные принципы построения:
● все данные которые будут расшардены должны
иметь общий ключ т.н сегмент
● отдельная структура которая будет знать какой
сегмент какому шарду принадлежит
● единый алгоритм распределения сегментов по
шардам
10. SQLAlchemy
● мощная орм, которая при минимуме усилий
позволяет абстрагировать разработчика от БД и
работать на уровне объектов
● если алхимию неправильно использовать она может
принести много головной боли разработчику
11. Установка соединения с БД и pool соединений:
● umysqldb
● sqlalchemy.create_engine
● sqlalchemy.orm.sessionmaker
12. Пример организации соединения с одной
БД
import umysqldb
from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker
umysqldb.install_as_MySQLdb()
SHARD_ENGINE = { 'engine': 'mysql', 'host': 'localhost', 'name': 'kranonit_shards', 'login': 'root', 'password': ''}
_DSN = '%(engine)s://%(login)s:%(password)s@%(host)s/%(name)s?charset=utf8'
SHARD_CONNECTION = create_engine(
_DSN % SHARD_ENGINE, echo=False, pool_recycle=3600, pool_size=5, max_overflow=0, isolation_level="READ COMMITTED")
SESSION = sessionmaker(bind=SHARD_CONNECTION, autocommit=True)
S_SESSION = SESSION()
13. Организация соединения с БД для шардовых БД:
● pool соединений к шардовым базам
● shard class
○ shard_chooser
○ query_chooser
○ id_chooser
14. Пример организации соединения с
шардовыми БД
CONNECTIONS = list()
_DSN = '%(engine)s://%(login)s:%(password)s@%(host)s/%(name)s?charset=utf8'
for shard in S_SESSION.query(Shard).all():
engine = create_engine(
_DSN % {'engine': shard.engine, 'host': shard.host, 'name': shard.name, 'login': shard.login, 'password': shard.password},
echo=False, pool_recycle=3600, pool_size=shard.pool_size, max_overflow=shard.max_overflow, isolation_level=shard.
isolation_level)
CONNECTION[shard.id] = engine
createfunc = sessionmaker(class_=DeepShardedSession, autoflush=False)
scoped = scoped_session(createfunc, scopefunc=getcurrent)
scoped.configure(shards=CONNECTIONS)
session = scoped()
15. Логика распределения shard
● uuid
● балансировка
● выбор емкости сегментов
○ 1 разряд uuid дает 16 записей на сегмент
○ минимальный ключ для сегмента два разряда
uuid
○ максимальноя количество записей в сегменте
21. Немножко про gevent
Gevent - green event, микропотоки в python
Плюсы
●
●
●
Псевдо многопоточность
Забываем про ужасы callback и deffered из Twisted
пишем код в обычном стиле и двумя строчками делаем его асинхронным
Минусы
●
●
●
сложно профилировать
не все библиотеки можно им пропатчить
требует определенных навыков в использовании
Применение
●
Практически везде где уместна работа с сетью, потоками и очередями