Здравствуйте!
В этой статье я хочу рассказать о проблемах авторизации с которыми может столкнуться любой посещаемый веб-сайт в период роста.
Где хранить аутентификационную базу пользователей?
Как быстро авторизовать пользователя по его строковому логину?
Как собирать распределенные по нескольким шард-таблицам и нескольким базам данных пользовательские данные?
Как заставить все это работать и как в этом нам может помочь MemcacheDB?
Несколько месяцев назад на своем проекте мы стокнулись с тем, что изначально созданная архитектура базы данных оказалась неприспособленной для текущих нагрузок. Прежде всего это касалось базы пользователей.
Да, мы использовали memcached для кэширования запросов, многое мы хранили в сессиях, пользовательские данные мы разделяли с помощью шардинга по множеству таблиц и баз данных, однако такая базовая вещь как аутентификация пользователя на сайте стала выполнятся неприлично большое количество времени.
Кроме того, чтобы собрать в процессе работы пользователя данные о его друзьях, имея в наличии лишь их идентификаторы приложению приходилось обращаться к таблице пользователей, которых к тому моменту накопилось уже полтора миллиона.
При высокой нагрузке выборки по текстовому индексу логина пользователя стали занимать очень большое время. Большая часть приходящих на ресурс пользователей были новыми пользователями, а соотвественно количество регистраций составляло несколько десятков тысяч в день.
Путей решения было несколько.
С одной стороны мы рассматривали возможность разбиения пользователей по множеству таблиц аутентификации в MySQL наподобие user1,user2,...,userN где N каким-либо образом вычислялось из логина пользователя. Но что сделать когда число таблиц в пределах одной базы станет слишком велико для нормальной производительности реляционной базы данных?
Как нам добится гибкости в масштабировании? Крупные порталы создают собственные системы аутентификации, однако наша команда работает прежде всего на результат в ограниченных ресурсах, когда подобная работа заняла бы слишком много времени, и мы стали искать уже существующее решение.
Тогда мы обратили свой взгляд в сторону Key-Value баз данных о которых вы можете прочитать здесь (http://habrahabr.ru/blogs/hi/55077/)
В силу ряда обстоятельств, из которых, прежде всего, была относительная известность мы остановились на MemcacheDB.
Итак, теперь об архитектуре.
В качестве эксперимента мы решили сохранять в MemcacheDB не только базовые авторизационные данные, но и сведения о местоположении данных пользователя для их быстрого получения.
Основные операции записи в MemcacheDB решено было дублировать в MySQL базу, поскольку мы не были уверены в стабильности MemcacheDB в поддержании целостности, и не уверены до сих пор. Автор MemcacheDB — Steve Chu, в ответ на наше письмо, о котором мы расскажем позже рекомендовал то же решение.
Операции чтения совершались только из MemcacheDB, а в кроне раз в сутки была поставлена проверка идентичности базы MySQL и MemcacheDB.
Проект работает на PHP5, изначально в качестве клиента к MCDB мы использовали pecl-memcache модуль, однако в процессе нагрузочного тестирования на большом объеме данных выяснилось что модуль имеет склонности к разрыву соединения при большой (для memcache) задержки чтения. После ряда мучений и извращений, мы написали письмо автору, Steve Chu, который сообщил что знает о проблемах подобного рода и рекоммендовал использовать в качестве клиента недавно опубликованный модуль pecl-memcached (обратите внимание на добавленную d). Это решило наши проблемы, кроме того быстрый ответ автора окончательно убедил нас в правильности сделанного выбора.
Для быстрого восстановления в случае потери базы на отдельном сервере поднят еще один экземпляр MemcacheDB в который реплицируются данные основного. В случае сбоя данных мы организуем быстрое переключение на backup-сервер.
Итак, каждый пользователь сохраняется по данным ключ=>значение дважды.
В данных всегда сохраняются данные пользоватлея, а в качестве ключа выступают:
Таким образом процесс регистрации предстает в виде:
Процесс авторизации:
Процесс получения информации о друзьях пользователя:
Основные преимущества этого подхода:
1. MemcacheDB на и на малых и на больших объемах данных показывает производительность в разы превыщающую производительность MySQL на той же задаче.
2. MemcacheDB легко относится к большому числу пар ключ-значение в базе, в настоящий момент в базе порядка 4 миллионов пар ключ-значение.
3. Шардинг и разделение данных по сущностям также возможны в MemcacheDB, его можно представив запустив несколько экземляров MemcacheDB с разными базами данных.
Эти изменения работают в продакшене уже два месяца, и до настоящего времени проблем отмечено не было.
Очень надеюсь, что эта статья будет вам полезна, как в образовательных целях, так и в целях решения накопившихся проблем.
Спасибо за внимание!
В этой статье я хочу рассказать о проблемах авторизации с которыми может столкнуться любой посещаемый веб-сайт в период роста.
Где хранить аутентификационную базу пользователей?
Как быстро авторизовать пользователя по его строковому логину?
Как собирать распределенные по нескольким шард-таблицам и нескольким базам данных пользовательские данные?
Как заставить все это работать и как в этом нам может помочь MemcacheDB?
Несколько месяцев назад на своем проекте мы стокнулись с тем, что изначально созданная архитектура базы данных оказалась неприспособленной для текущих нагрузок. Прежде всего это касалось базы пользователей.
Проблема
Да, мы использовали memcached для кэширования запросов, многое мы хранили в сессиях, пользовательские данные мы разделяли с помощью шардинга по множеству таблиц и баз данных, однако такая базовая вещь как аутентификация пользователя на сайте стала выполнятся неприлично большое количество времени.
Кроме того, чтобы собрать в процессе работы пользователя данные о его друзьях, имея в наличии лишь их идентификаторы приложению приходилось обращаться к таблице пользователей, которых к тому моменту накопилось уже полтора миллиона.
При высокой нагрузке выборки по текстовому индексу логина пользователя стали занимать очень большое время. Большая часть приходящих на ресурс пользователей были новыми пользователями, а соотвественно количество регистраций составляло несколько десятков тысяч в день.
Поиск решения
Путей решения было несколько.
С одной стороны мы рассматривали возможность разбиения пользователей по множеству таблиц аутентификации в MySQL наподобие user1,user2,...,userN где N каким-либо образом вычислялось из логина пользователя. Но что сделать когда число таблиц в пределах одной базы станет слишком велико для нормальной производительности реляционной базы данных?
Как нам добится гибкости в масштабировании? Крупные порталы создают собственные системы аутентификации, однако наша команда работает прежде всего на результат в ограниченных ресурсах, когда подобная работа заняла бы слишком много времени, и мы стали искать уже существующее решение.
Тогда мы обратили свой взгляд в сторону Key-Value баз данных о которых вы можете прочитать здесь (http://habrahabr.ru/blogs/hi/55077/)
В силу ряда обстоятельств, из которых, прежде всего, была относительная известность мы остановились на MemcacheDB.
Архитектура
Итак, теперь об архитектуре.
В качестве эксперимента мы решили сохранять в MemcacheDB не только базовые авторизационные данные, но и сведения о местоположении данных пользователя для их быстрого получения.
Основные операции записи в MemcacheDB решено было дублировать в MySQL базу, поскольку мы не были уверены в стабильности MemcacheDB в поддержании целостности, и не уверены до сих пор. Автор MemcacheDB — Steve Chu, в ответ на наше письмо, о котором мы расскажем позже рекомендовал то же решение.
Операции чтения совершались только из MemcacheDB, а в кроне раз в сутки была поставлена проверка идентичности базы MySQL и MemcacheDB.
Проект работает на PHP5, изначально в качестве клиента к MCDB мы использовали pecl-memcache модуль, однако в процессе нагрузочного тестирования на большом объеме данных выяснилось что модуль имеет склонности к разрыву соединения при большой (для memcache) задержки чтения. После ряда мучений и извращений, мы написали письмо автору, Steve Chu, который сообщил что знает о проблемах подобного рода и рекоммендовал использовать в качестве клиента недавно опубликованный модуль pecl-memcached (обратите внимание на добавленную d). Это решило наши проблемы, кроме того быстрый ответ автора окончательно убедил нас в правильности сделанного выбора.
Для быстрого восстановления в случае потери базы на отдельном сервере поднят еще один экземпляр MemcacheDB в который реплицируются данные основного. В случае сбоя данных мы организуем быстрое переключение на backup-сервер.
Итак, каждый пользователь сохраняется по данным ключ=>значение дважды.
В данных всегда сохраняются данные пользоватлея, а в качестве ключа выступают:
- логин пользователя
- идентификатор пользователя
Таким образом процесс регистрации предстает в виде:
- Данные пользователя сохраняются в БД.
- Данные пользователя сохраняются в MemcacheDB с ключем user_login, где login — логин пользователя
- Данные пользователя сохраняются в MemcacheDB с ключем user_id, где id — идентификатор пользователя.
Процесс авторизации:
- Пользователь вводит свои аутентификационные данные — login и пароль.
- Система получает данные пользователя из MemcacheDB по ключу user_login и проводит аутентификацию.
Процесс получения информации о друзьях пользователя:
- Пользователь загружает список друзей.
- Система получив список идентфикаторов друзей пользователя (возможно из того же MemcacheDB) получает информацию о каждом друге по user_id и на основании этой информации собирает другие данные пользователя распределенные в БД.
Преимущества
Основные преимущества этого подхода:
1. MemcacheDB на и на малых и на больших объемах данных показывает производительность в разы превыщающую производительность MySQL на той же задаче.
2. MemcacheDB легко относится к большому числу пар ключ-значение в базе, в настоящий момент в базе порядка 4 миллионов пар ключ-значение.
3. Шардинг и разделение данных по сущностям также возможны в MemcacheDB, его можно представив запустив несколько экземляров MemcacheDB с разными базами данных.
Эти изменения работают в продакшене уже два месяца, и до настоящего времени проблем отмечено не было.
Очень надеюсь, что эта статья будет вам полезна, как в образовательных целях, так и в целях решения накопившихся проблем.
Спасибо за внимание!