#php #sql #api #nosql
Закрыт. На этот вопрос невозможно дать объективный ответ. Ответы на него в данный момент не принимаются. Хотите улучшить этот вопрос? Переформулируйте вопрос, чтобы на него можно было дать ответ, основанный на фактах и цитатах, отредактировав его. Закрыт 3 года назад. Здравствуйте. Собираюсь приступить к разработке API для мобильного приложения, количество ежедневных пользователей которого по планам должно будет колебаться в районе десяти-двадцати миллионов. Какие технологии лучше всего использовать при разработке высоконагруженного API-сервиса? Допустимо ли использование "PHP" в качестве основного языка, или здесь непременно должен иметь место "NodeJS"/"Ruby"? Если да - то почему? Каковы минусы и плюсы SQL- и NoSQL-СУБД применительно к планируемой нагрузке? Какие средства кэширования редкообновляемой информации лучше всего использовать? Заранее благодарю за ответы.
Ответы
Ответ 1
Допустимо ли использование "PHP" в качестве основного языка, или здесь непременно должен иметь место "NodeJS"/"Ruby" Это все платформы одного порядка. С чуть большими возможностями у последних двух, но задаваться нужно вопросом выбора между "интерпретируемым языком общего назначения" и java-scala, c# и какими-то менее мейнстримовыми, о которых я не вспомнил. Упомянутые интерпретируемые (так уж повелось) более толерантны к ошибкам, временами сложнее в дебаге и проще в обновлении и непосредственно написании, упомянутые компилируемые нетерпимы к ошибкам, но имеют как желаемый прирост скорости, так и зачастую более интересный API. Какие технологии лучше всего использовать при разработке высоконагруженного API-сервиса? Те, которые отвечают вашим требованиям. Написать API, которое вытаскивает данные тысячу раз в секунду - не проблема, проблема - решить реальную бизнес-задачу. Пока неизвестно, что там, можно только гадать, где реально нужно стелить соломы, а так какая-нибудь связка php-mysql-redis спокойно сможет выдерживать эти пресловутые тысячи запросов и масштабироваться без кряхтения. В случае, если у вас начинается более интересная игра, начинают требоваться распределенные блокировки, сиюсекундное обновление кеша на всех хостах, параллельное перемалывание задачи на всех хостах без известности о том, сколько этих хостов и вообще прямой коммуникации между ними - тут начинается беда, которую надо разгребать конкретными решениями. Самая большая проблема, которая стоит перед разработкой этого сервиса - это shared-nothing архитектура, которая не предполагает закрепление за отдельным узлом какого-либо состояния, состояние хранится в базе данных. На первый взгляд кажется, что это условие и так выполняется, на практике все начинает выползать: при загрузке файла прогресс загрузки этого файла должен быть виден на всех узлах разом, кэширующий слой должен быть соединен воедино, чтобы все клиенты кэша видели одно и то же, простая блокировка ресурса превращается в целое приключение. Этому сложно научиться, не набив себе шишек, поэтому чем раньше вы присутпите к написанию на чем угодно и выкладке на несколько узлов, тем раньше прочувствуете эту проблему. Каковы минусы и плюсы SQL- и NoSQL-СУБД применительно к планируемой нагрузке? Как я уже написал, у SQL нет плюсов. По сравнению с NoSQL-решениями есть такая штука, как джойн, но от него отказались вполне сознательно, и он чаще вредит, чем помогает. Принципиальная разница для поставленной задачи в масштабировании: практически любое NoSQL-решение предлагает возможность горизонтального расширения из коробки, в то время как SQL этого не умеет. Перед тем, как вообще бросаться в выбор базы данных, надо понять, что от нее требуется. Кроме стандартного жестко стркутурированного типа SQL-совместимых баз данных есть четыре основных типов баз данных NoSQL: key-value (грубо говоря, доступ исключительно по первичному ключу без возможности осуществлять выборки), row-column (очень похоже на SQL, но, конечно, совершенно иная вещь под капотом), документоориентированные (т.е. без жестко заданной структуры) и графовые (предназначенные для работы со сложными связями). У вас, судя по всему, выбор стоит между документоориентированной и row-column БД: тут нельзя сказать что-то конкретное, и выбор остается за вами. Могу только сказать, что из row-column предпочтение обычно отдается Cassandra, а в документоориентированных любят монгу, но я слышал про нее довольно печальные отзывы (и в текущем проекте по ряду причин выбрали rethinkdb). Кроме всего это стоит помнить (и изучать) тот факт, что вся система теперь превращается в распределенную, и теперь у нее есть все любимые проблемы распределенных систем, в том числе разрыв сети и несинхронное обновление данных на разных узлах. Тут можно много сказать про проблемы производительности, про возможные подводные камни, но на самом деле все упирается банально в то, насколько хорошо ваша платформа масштабируется, и можете ли вы выкатить новый сервак в течение дня, потому что даже самый идеальный бэкенд имеет пропускной предел. Единственное, про что еще хотелось бы сказать - это то, что переход на распределенные системы, как правило, требует еще и смены парадигмы pull-on-demand на push-on-change.Ответ 2
Вы можете разработать такой сервис на любой технологии, в том числе с использованием PHP. Поставив рядом несколько серверов, вы можете практически бесконечно масштабировать операции чтения за счет репликации (как на уровне СУБД, так и на уровне NoSQL-решений). Проблемы начинаются, когда у вас очень много одновременных соединений, даже если вы можете под каждый из них выделить отдельный поток-запрос. Просто их так много, что процессор переключаясь между ними начинает терять слишком много времени. Так как вы работаете для мобильных приложений, у вас может быть очень не важная связь с клиентом, а значит много медленных клиентов. Чем страшен медленный клиент для классического сервера? Пусть у вас сервер может держать 1000 одновременных запросов, подключаются к вам 500 клиентов с EDGE и начинают в течение 10 минут ждать ответа. И вот у вас уже сервер обслуживает не 1000, а 500 одновременных запросов. Так как 500 повисли в ожидании ответа от клиентов. Оставшиеся соединения начинают не справляться, отдавать запросы медленнее, и вот у вас сервер может обслуживать только 250 запросов. А через некоторое время и вообще грохается. Это может не так актуально для Web, где клиенты в массе пошустрее, но в мобильной разработке это более частое явление – покрытие везде разное, связь от него зависит здорово. Когда говорят о NodeJS или серверах Ruby – там ничего волшебного нет, просто сервера более новые и проектировались немного по-другому. Вместо того, чтобы ждать каждое соединение отдельным запросом организуется один поток, который опрашивает соединения в неблокирующем режиме. Пришел ответ от клиента – он его обрабатывает, нет - пошел к следующему соединению. Этим убивается два зайца. Вы не переключаетесь между потоками/процессами (экономите время), вы решаете проблему медленных клиентов – у вас поток не ждет, он постоянно работает. Проблема только чтобы у вас сервер-сторона не тормозила, так как опрашивающий поток один. Это Event Driven архитектура, можно найти решения и для PHP. Просто в случае NodeJS или Ruby они идут чуть не из коробки, в случае PHP придется поискать решение. Однако, какой бы вы язык не выбрали, разобраться с этим важно. Event Driven архитектура позволяет вам задействовать WebSocket-ы, постоянные соединения от клиентов – вы можете позволить их сколько угодно, так как соединение в ожидающем режиме почти не расходует никаких ресурсов (ни памяти, ни процессора). И вот мы плавно подходим к тому, как вы будете писать. Даже если вы не используете EventDriven-решения, а поставили рядом много классических fork-серверов, реплицировали данные на уровне базы данных, у вас все равно остается проблема с записью, так как она не масштабируется репликацией. Вам нужно очень быстро писать, чтобы клиент не ждал ответа от сервера, не держал соединение, а шел по своим делам. Чем быстрее вы будете их обслуживать – тем вам будет проще. Писать непосредственно в базу данных – не вариант. Классические СУБД очень медленные и неторопливые, норовят все в транзакциях выполнять, а это тоже накладные расходы. Есть два пути – быстрое NoSQL-решение полностью распложенное в оперативной памяти (redis, MongoDB). Быстро записали в память, отпустили клиента, в фоне разбираемся, записываем. Очереди – позакидали все в очередь, в фоне не спеша события из очереди обрабатываются. Было бы здорово, если часть информации преобразовывалась, агрегировалась непосредственно в оперативной памяти и лишь потом поступала в медленную базу данных "оптом". Чем хороши современные NoSQL-решения – они почти все написаны с учетом неблокирующих соединений и могут держать тысячи одновременных соединений. Чем плохи – это не классическая СУБД, там сложно организовывать связи и ассоциации, вообще нужно работать немного по другому. В них плохо с транзакциями. Однако, они расположены в оперативной памяти и отлично кластеризуются. Принимать в них данные одно удовольствие – это не сурогат из 100 таблиц с последующим слиянием в СУБД, чтобы писать данные было проще, и не геморройная кольцевая архитектура в репликации. В общем на практике обычно используется все, что вы упомянули, можно часть написать на PHP, с WebSocket-ами вам возможно будет удобнее работать через NodeJS-сервер, очереди и PubSub-решения возможно будет проще организовать через Redis или RabbitMQ, "сырые" данные положить в то же Reids или MongoDB, а в качестве долговременного резервируемого хранилища использовать классическую СУБД (хотя можно вообще без классической СУБД обойтись). Если вы доведете свое API до заявленных нагрузок, вам скорее всего придется попробовать если не все, то почти все :)
Комментариев нет:
Отправить комментарий