Да пошел ты, SQL! Как отказать от SQL баз данных и выиграть

Главные вкладки

Аватар пользователя misterpronin misterpronin 1 мая 2013 в 16:37

В общем наткнулся на одну статью в интернете и решил послушать мнения друпальчан... Интересно использует ли кто-нибудь нечто подобное на drupal?

Текст этой самой статьи:

Но как же без него? Если не привычный базы данных SQL, то что? Вот, что я тебе скажу. Первым кинь выиграть камень в того, кто скажет, что в большом проекте без, SQL не обойтись. Обойтись можно. И при этом - некисло выиграть!

Скажи честно, тебе ведь интересно, как устроены изнутри те суперпроекты, на которых висишь сутками ты и еще сотни миллионов пользователей сразу? Google, Amazon, eBay, Twitter тот же Facebook или наш Вконтакте? Они совсем не похожи на большинство обычных веб-сайтов, написанных на PHP+mySQL. База данных в них - все. Там и новости, и информация о товарах в интернет-магазине, и статьи с комментариями в блоге, и самое вкусное - логины и пароли.

База данных – вширь и ввысь

Очень многие разработчики и архитекторы также думали, что без базы не обойтись, продолжая создавать все более мощные сайты. Но вскоре столкнулись с тем, что сколько ни тужься, какие только хаки и умные штуки ни придумывай - но при нагрузке в сто миллионов пользователей, базы данных все равно мрут как мухи. Ребята тоже слышали о кластерах, и о распределенных системах, и даже об облачных вычислениях (подробнее читай статью "Заоблачные вычисления" в #125 номере ][). Если надо, чтобы больше людей скачало новый порно-ролик с Берковой, достаточно поставить еще пару серверов и скопировать на них файлы.

А вот базы данных так просто не работают. Вот тут-то и нарисовалась проблема масштабирования. Каждый решает ее по-своему.

Сначала ставят второй сервер: с него приложение только читает данные, записывая только на первый, а он уже сам, в фоновом режиме, переносит новые данные. Такая архитектура называется master-slave, но ничего связанного с BDSM здесь нет!

Позже можно доставить еще сервер, и еще, но это уже не поможет, если писать надо много и постоянно. Ведь каналы между серверами рано или поздно будут забиты так, что новые данные будут появляться на подчиненных узлах гораздо позже, чем это допустимо. А кому интересно ждать, пока же его комментарий появиться на странице (самые нетерпеливые тупо жмут рефреш, чем еще сильнее нагружают систему)?

Светлые умы подумали и решили, а что, если все базы данных будут сразу главными? То есть, у тебя есть три сервера, и на каждом из них есть вся информация, а приложение случайно или определенному алгоритму выбирает, с каким сервером работать.

Изменения на одном сервере сразу передаются на два других (это называется master-master или multi-master репликация), и в любой момент везде есть самые последние данные, при этом писать и читать информацию можно с любого сервера.

Но тут есть одна сложность – у самых популярных баз эта функция появилась только недавно, да и в настройке и поддержке очень уж сложная. И не дай бог, придется восстанавливать данные или потерянные транзакции - тут вообще без пива не разберешься.
Ну и, конечно, до бесконечности наращивать количество серверов также нельзя. Все будет неплохо, пока не дойдешь до десятка. А там уже не оберешься проблем с взаимной связью и трафиком внутри такого хозяйства. А результат тот же – медленно и ненадежно.

Скажи твердое "Нет" SQL-у!

А тем временем сайты растут, пользователей становится все больше, счет идет уже на десятки миллионов. Что же делать? А вот что - просто отказаться от обычной базы данных! Ведь что такое база данных? Это специальное хранилище данных (обычно, это просто файлы, но с собственной структурой и кешем в памяти) с движком, который принимает от тебя команды в виде языка SQL (например, на выборку данных) и выполняет их.
Особенно достают кривые руки разработчика или админа, когда для самого простого запроса «а сколько юзеров у меня на странице?» приходится тупо перебирать весь список пользователей и проверять, у кого статус он-лайн. Ведь юзеров может быть реально много, а если ты еще не озаботишься правильными индексами, то на каждый такой запрос придется серверу доставать всю табличку с данными (а это может и гигабайт быть) и считать снова и снова. А если в этот момент Вася скинул своим френдам в ЖЖ ссылку на твой суперпроект и пришла еще тысяча юзеров, каждого из которых надо записать в базу? Все - капут серверу!

Все потому, что и базы данных и язык SQL, которым эти данные выбираются, достаточно плохо приспособлен к масштабированию.
То есть, пока один-два сервера, все будет окей. Но как только больше - начинаются проблемы. Нельзя добавить еще машинку и гарантированно заставить работать все быстрее. В Гугле это давно поняли и изобрели свое решение, полностью отказавшись от применения таких обычных баз данных. Но это гугл со своими ноу-хау, а что делают остальные? Остальные используют key-value database!

По сути, это максимально упрощенная база данных. Скорее, даже просто хранилище, где все данные сведены к обычной паре: ключ (или индекс) и сами данные, которые обычно представляют собой строку и в некоторых случаях числа. То есть, вся база данных - это просто список ключей и сопоставленных с ними строк данных. Что именно хранится в такой базе, ей совершенно неважно - это забота самого приложения.

Интерфейс доступа к такой базе также максимально прост – обычно это простейшие команды типа get (получить данные по ключу), set (записать данные с ключем), delete (удаляет ключ и его данные), update (обновляет уже существующие данные).

Самым главным преимуществом является то, что если правильно все сделать, сложность таких операций (то есть, время вычисления результата) будет заранее известным и не зависит от объема данных или количества серверов. Более того, операции обычно атомарные (в обычных SQL базах данных это называется транзакциями). Т.е. задавая команду, ты можешь быть уверенным, что она либо успешно отработает, либо сразу вернет тебе ошибку - при этом другие пользователи не помешают тебе, даже если будут пытаться сделать то же самое.

Это самый обычный тип key-value баз данных. Подобных проектов существует много, но отличаются они как правила типами данных, возможных для хранения. Например, кроме строк, можно хранить числа или двоичные объекты (BLOB-ы), а также количеством команд-операций. Понятно, что описанные выше четыре операции самые простые, обычно поддерживается еще инкременент/декремент (счетчик в памяти), особо продвинутые могут хранить массивы и списки.

На низком уровне такие базы строятся на базе хеш-таблиц и их разновидности – распределенной хеш-таблицы (DHT). Это просто обычная, хоть и большущая таблица, которая может автоматически распределяться на любое количество компьютеров и поддерживает поиск и получение данных баз знания, где они конкретно (такой принцип в частности используется для бессерверного обмена пирами во время скачки файла через torrent). И хотя обычно для быстрой работы данные хранятся в оперативной памяти, некоторые сервера обеспечивают хранения на диске и бекап, так что после выключения такого сервера все данные сохраняются.

Светлые и темные стороны Силы

Сильной стороной таких решений – масштабируемость и скорость. Свойства DHT такие, что можно присоединять новые сервера постоянно, и такая база будет расти и расти. Столько - сколько надо. При этом в самих приложениях ничего менять не надо, все делается автоматически! Скорость также очень и очень высокая, так как практически все такие базы работают обычно в памяти, а на диск пишется лишь бекап (при этом, он может быть постоянным - в таком случае в него записывается только новая инфа). Показатели в сотни тысяч запросов в секунду на одном дохленьком сервере – это обычное дело для таких баз.

Но несмотря на восторги, есть и сложности. Первая – это скудность возможностей работы с данными. Ага, вот и расплата за скорость и расширяемость. Сервер знает только ключ и данные, которые с ним ассоциированы, а вот, что это за информация - номер кредитной карточки или дата регистрации - уже не ведает. Этим должно заниматься само приложение! Поэтому просто взять и, например, написать один SQL запрос, чтобы выбрать всех пользователей, которые регистрировались год назад и совершили больше одного платежа за это время, уже не получится.

В базе просто нет такой возможности выборки по какому-либо признаку, кроме ключа. Но не спеши отворачиваться - это ограничение легко решает за счет ввода дополнительных данных (так же как в SQL-базе выделяются постоянные данные в отдельную таблицу-справочник). Правда, в этом случае нужно с самого начала проектировать сайт под такие типы базы. Ведь то, что делается одной строкой на SQL, здесь потребует как нескольких запросов и обработки, так и предварительного форматирования данных при записи.

Увы, автоматически трансляторов SQL в key-value запросы пока нет, но работы в этом направлении ведутся. Еще одним недостатком таких баз является требовательность к параметрам сервера и в особенности оперативной памяти, которой, как известно, много не бывает. Прожорливость удается удовлетворить за счет хранения не используемых данных на диске. Подобным образом поступили разработчики MemcacheDB, где скрестили популярный сервер memcache и базу данных BerkleyDB, используемое как постоянное хранилище данных. В более молодом, но очень сильном проекте проекте - Redis - используется асинхронная запись в фоновом режиме на диск. Другие также не брезгуют использовать традиционные базы данных для хранения, ведь их совсем не видно за фасадом сервера и они работают локально, поэтому на скорость работы почти не влияют.

Сервера - подходи, выбирай!

Довольно теории! Давай посмотрим, какие есть базы и чем они отличаются.

Memcached/MemcacheDB (memcachedb.org) – наверное самый известный представитель семейства key-value DB. Многие используют его как кеширующую систему, что, по большому счету, то же самое. Проект хранит данные в оперативной памяти, занимает места столько, сколько ему выделили и может объединяться с другими серверами, чтобы распределить данные между собратьями.

Доступ к данным идет через UDP-порт и сокеты, что очень быстро, а с выходом последней версии, 1.4, добавлен и экономичный бинарный протокол. Хотя, в Facebook считают иначе и ускоряют, как могут, добиваясь нескольких сотен тысяч одновременных подключений! Кстати именно эта социальная сеть имеет самую большую инсталляцию Memcached-севреров – в архитектуре участвует более тысячи серваков! Недостаток мемкеша в том, что он, хранит все в памяти. По этой причине в местах, где необходима сохранность данных, придется использовать MemcacheDB, который использует обычную базу данных как постоянное хранилище данных. Другие недостатки – ограниченность на данные, которые понимает сервер (это только числа и строки), а также сложности выборки одним запросом множества ключей.

Project Voldemort (project-voldemort.com) – такой же мощный, как и Темный Лорд, только в царстве баз данных. Штука написана на Java и изначально нацелена на распределённость. Добавлять новые сервера можно без остановки - данные по ним "расползутся" без посторонней помощи. Кроме обычного сетевого доступа Project Voldemort, поддерживает JavaAPI и различные сетевые протоколы, например, Google ProtoBuf или Thrift, что сильно экономит трафик и повышает скорость. Данные хранятся как в памяти, так и на диске (можно использовать и обычные базы данных), так что сбои питания никак не нарушат целостности.

Сильной стороной является поддержка версионности, то есть каждая единица данных имеет историю версий и изменений, поэтому можно откатываться назад, если что-то записали не то или возникли ошибки. Быстродействие также на высоте: в среднем 10 – 20 тысяч операций в секунду, так что такой гигант, как соцсеть LinkedIn не прогадал, используя кластер из таких серверов для своей работы.

Apache CouchDB (couchdb.apache.org) - это уже тяжелое оружие из будущего! Шутка, CouchDB это представитель отдельного семейства баз данных, называемых документно-ориентированными. То есть, в этой штуке хранят документы, представляющий собой некоторую группу данных, которые вместе составляют один объект-документ. Например, статья (текст), краткая аннотация, имя автора, дата публикации и статус. По отдельности, это просто отдельные значения, а вот документная база позволяет их сгруппировать как один объект и производить над ним операции. Apache CouchDB написана на Erlang (просто замечательная платформа, если речь идет о расширяемости) и имеет HTTP REST-интерфейс или JSON API, так что можно получать данные сразу напрямую из JavaScripta-а на веб-странице! Кстати, она имеет встроенный язык запросов, какой ты думаешь? Да, JavaScript вместо традиционного SQL. Справедливости ради стоит сказать, что о промышленном применении базы пока не слышно. Уж сильно уж экспериментальная разработка, хотя и чрезвычайно перспективная.

Redis (code.google.com/p/redis) - проект хотя и молодой и в идее достаточно простой, но по возможностям мощнее всех предыдущих вместе взятых! Почему? Да взять хотя бы производительность. Более 100 запросов в секунду на простеньком сервере или мощном лаптопе. Знакомься, Redis или, как он сам себя называет, сервер структурированных данных. Проект позволяет хранить не только обычные ключи и значения, но и списки, наборы данных (то есть, группы пар ключ-значение), а также производить всего одной командой (и с гарантированным временем выполнения!) сложнейшие операции над такими списками.

Там, где для memcached надо писать вручную две, три или десяток команд и еще вычислять что-то в самом приложении, при использовании Redis-а можно обойтись одной! Поддерживается даже сортировка, что является самой сложной и практически не выполнимой командой для всех key-value баз (в отличии от SQL, где это самая тривиальная операция). Написанный на ANSI C, сервер умещается в паре десятков Кб исходных текстов (по лицензии BSD), работает на любой системе и сотворит с твоими данными чудеса. Команды посылаются по TCP или напрямую через telnet. Помимо есть и API или модули на любой вкус и язык. Не буду скрывать, что сам являюсь автором класса-интерфейса для PHP, расширяющего возможности сервера еще сильнее! Smile

Что в результате?

Сейчас реляционные базы данных (SQL СУБД) уже не правят миром, особенно если речь идет о высоконагруженных проектах или сайтах, где надо обслуживать клиентов без задержки. Если раньше все проблемы пытались решить кешированием, то сегодня мы видим, как гиганты индустрии просто уперлись в ограничения баз данных и в поисках выхода попробовали посмотреть на традиционные кеши с другой стороны. И получилось! Добавив чуточку смекалки и пару новых команд теперь можно делать почти все, что раньше требовало сложных SQL-запросов, используя всего пять-шесть команд. При этом не важно, один сервер, десять или тысяча, мы вообще никак не ограничены в масштабировании! Конечно, не стоит сразу бросать любимый мускул и переписывать под Redis или MemcachedDB, но если ты делаешь сайт, где надо что-то делать быстро, очень быстро, как можно быстрее (ну типа чата, твиттера или онлайн игры, а то и биржевой системы) – попробуй посмотреть на мир key-value баз данных!
Может это то, что надо! А SQL-базам оставим нудные дела вроде построения аналитики и анализа данных.

WWW

Подробнее о репликации: http://en.wikipedia.org/wiki/Multi-master_replication
Немного о архитектуре Google: http://highscalability.com/google-architecture
Разработка Google для хранения данных: http://labs.google.com/papers/bigtable.html
Информация о DHT: http://ru.wikipedia.org/wiki/DHT
Все о Memcached: http://www.danga.com/memcached/
Код кудесников из Facebook'а: http://github.com/fbmarc/facebook-memcached/tree/master
Мой класс на PHP для работы с Redis-сервером и написанный с его помощью чат в качестве примера: http://code.google.com/p/redis-ajax-chat/

Комментарии

Аватар пользователя misterpronin misterpronin 1 мая 2013 в 17:06

Мне вот просто интересно правда ли то, что пишут в статье? Т.е. становится ли MySQL узким местом на высокопосещаемом сайте...

Аватар пользователя NaZg NaZg 2 мая 2013 в 12:11

если сайт с кривым движком и неоптимизированным кодом, то его и 10 рыл в онлайне обвалят
статья - УГ

Аватар пользователя q2_faith q2_faith 2 мая 2013 в 12:19

"misterpronin" wrote:
Мне вот просто интересно правда ли то, что пишут в статье? Т.е. становится ли MySQL узким местом на высокопосещаемом сайте...

как выясняется не всегда и не совсем) многое зависит от того как и чем сайт делали)
"misterpronin" wrote:
Ну допустим хитов так 20-50 млн в сутки...

99,9% процентов разработчиков никогда не столкнутся с таким количеством хитов)