Русский
Русский
English
Статистика
Реклама

Высокие нагрузки

Перевод Как справиться с более чем двумя миллиардами записей в SQL-базе данных

22.03.2021 18:15:22 | Автор: admin

В рамках набора группы учащихся на курс "Highload Architect" подготовили перевод интересной статьи.

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


У одного из наших клиентов возникла проблема с большой, постоянно растущей, таблицей в MySQL с более чем 2 миллиардами записей. Без модернизации инфраструктуры была опасность исчерпания дискового пространства, что потенциально могло сломать все приложение. С такой большой таблицей были и другие проблемы: низкая производительность запросов, плохая схема, и, из-за огромного количества записей, не было простого способа анализировать эти данные. Также нам нужно было решить эти проблемы без простоев в работе приложения.

В этом посте я хотел рассказать о нашем подходе к данной проблеме, но сразу хочу оговориться, что это не универсальное решение: каждый случай индивидуален и требует разных подходов. Но, возможно, вы найдете здесь некоторые полезные идеи для себя.

Спасение в облаках

После оценки нескольких альтернативных решений мы решили отправлять данные в какое-нибудь облачное хранилище. И наш выбор пал на Google Big Query. Мы выбрали его, потому что клиент предпочитал облачные решения от Google, а также данные были структурированными, предназначались для аналитики и нам не требовалась низкая задержка передачи данных (low latency). Поэтому BigQuery, казалась, идеальным решением (см. диаграмму ниже).

После тестов, о которых вы можете прочитать в посте Анджея Людвиковски (Andrzej Ludwikowski), мы убедились, что Big Query достаточно хорошее решение, отвечающее потребностям наших клиентов и легко позволяет использовать аналитические инструменты для анализа данных. Но, как вы, возможно, уже знаете, большое количество запросов в BigQuery может привести к увеличению стоимости, поэтому мы хотели избежать запросов в BigQuery напрямую из приложения и использовать его только для аналитики и как что-то вроде резервной копии.

https://cloud.google.com/solutions/infrastructure-options-for-data-pipelines-in-advertising#storing_data

Передача данных в облако

Для передачи потока данных есть много разных способов, но наш выбор был очень прост. Мы использовали Apache Kafka просто потому, что она уже широко использовалась в проекте и не было смысла внедрять другое решение. Использование Kafka дало нам еще одно преимущество мы могли передавать все данные в Kafka и хранить их там в течение необходимого времени, а затем использовать для миграции в выбранное решение, которое справилось бы со всеми проблемами без большой нагрузки на MySQL. С таким подходом мы подготовили себе запасной вариант в случае проблем с BigQuery, например, слишком высокой стоимости или сложностей и с выполнением необходимых запросов. Как вы увидите ниже, это было важное решение, которое дало нам много преимуществ без каких-то серьезных накладных расходов.

Потоковая передача из MySQL

Итак, когда речь заходит о передаче потока данных из MySQL в Kafka, вы, вероятно, думаете о Debezium или Kafka Connect. Оба решения отличный выбор, но в нашем случае не было возможности их использовать. Версия сервера MySQL была настолько старой, что Debezium ее не поддерживал, а обновление MySQL было невозможным. Мы также не могли использовать Kafka Connect из-за отсутствия автоинкрементного столбца в таблице, который мог бы использоваться коннектором для запроса новых записей без потери каких-либо из них. Мы знали, что можно использовать timestamp-столбцы, но при этом подходе могли быть потери строк из-за того, что запрос использовал более низкую точность timestamp, чем указано в определении столбца.

Конечно, оба решения хороши, и если нет никаких препятствий для их использования, то я могу рекомендовать их для передачи данных из вашей базы данных в Kafka. В нашем случае нам нужно было разработать простого Kafka Producer, который запрашивал данные без потери каких-либо записей и передавал их в Kafka. И Kafka Consumer, отправляющего данные в BigQuery, как показано на диаграмме ниже.

Отправка данных в BigQueryОтправка данных в BigQuery

Секционирование как способ экономии места

Итак, мы отправили все данные в Kafka (сжимая их для уменьшения полезной нагрузки), а затем в BigQuery. Это помогло нам решить проблемы с производительностью запросов и быстро анализировать большой объем данных. Но осталась проблема с доступным местом. Мы хотели найти решение с заделом на будущее, которое справилось бы с проблемой сейчас и могло быть легко использовано в будущем. Мы начали с разработки новой таблицы. Мы использовали serial id в качестве первичного ключа и секционирование по месяцам. Секционирование этой большой таблицы дало нам возможность создавать резервные копии старых секций и усекать (truncate) / удалять (drop) их, чтобы освободить место, когда секция больше не нужна. Итак, мы создали новую таблицу с новой схемой и использовали данные из Kafka для ее заполнения. После переноса всех записей мы развернули новую версию приложения, которая для INSERT использовала новую таблицу с секционированием и удалили старую, чтобы освободить место. Конечно, вам понадобится достаточно свободного места для переноса старых данных в новую таблицу, но в нашем случае во время миграции мы постоянно делали резервные копии и удаляли старые разделы, чтобы быть уверенными, что у нас хватит места для новых данных.

Передача данных в секционированную таблицуПередача данных в секционированную таблицу

Сжатие данных как еще один способ освободить пространство

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

Одна из идей была посмотреть, как различные данные распределены по таблице. После нескольких запросов выяснилось, что почти 90% данных никому не нужны. Поэтому мы решили их сжать, написав Kafka Consumer, который отфильтровал бы ненужные записи и вставлял только нужные в еще одну таблицу. Назовем ее сжатой таблицей (compacted table), что показано на приведенной ниже диаграмме.

После сжатия (строки со значением "A" и "B" в колонке type были отфильтрованы во время миграции).

Передача данных в compacted-таблицуПередача данных в compacted-таблицу

После этого мы обновили наше приложение и теперь выполняли чтение из новой таблицы (compacted table), а запись делали в секционированную таблицу (partitioned table), из которой мы непрерывно передавали данные с помощью Kafka в сжатую таблицу (compacted table).

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

Так как мы используем BigQuery только для аналитических запросов, а остальные запросы, отправляемые пользователями через приложение, по-прежнему выполняются в MySQL, то затраты оказались не такие и большие, как можно было бы ожидать. Еще одна важная деталь все было выполнено без простоев, ни один клиент не пострадал.

Резюме

Итак, подведем итоги. Мы начали с использования Kafka в качестве инструмента для потоковой передачи данных в BigQuery. Но так как все данные были в Kafka, это дало нам возможность легко решить другие проблемы, которые были важны для нашего клиента.


Узнать подробнее о курсе "Highload Architect".

Смотреть вебинар на тему Выбор архитектурного стиля.

Подробнее..

Перевод Как создать архитектуру для работы с высокой нагрузкой вашего веб-проекта?

26.05.2021 16:17:30 | Автор: admin

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

Помните "Черные Пятницы", которые так популярны среди людей? Знаете ли вы, что иногда сайты и веб-приложения не выдерживают такого огромного наплыва пользователей и в результате этого нередко теряют много денег?

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

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

Ознакомьтесь с некоторыми фактами о высокой нагрузке:

  • Высокая нагрузка возникает, когда один физический сервер становится не в состоянии эффективно выполнять обработку данных.

  • Если один экземпляр (instance) одновременно обслуживает 10 000 соединений - это высокая нагрузка. Высокая нагрузка - это одновременное обслуживание тысяч и миллионов пользователей

  • Если вы развертываете веб-решение на AWS (Amazon Web Services), Microsoft Azure или Google Cloud Platform, вы поддерживаете архитектуру для работы с высокой нагрузкой.

Вы можете столкнуться со следующими проблемами, если ваше веб-решение не выдерживает высоких нагрузок:

  • Медленная или бесконечная загрузка страниц

  • Случайные ошибки

  • Разрывы соединений с веб-сервером

  • Неполная загрузка контента

  • Снижение активности пользовательской аудитории

  • Потери клиентов

Как видите, архитектура проекта влияет на его успешность. Нет довольных клиентов - нет успеха и прибыли. Чтобы реализовать масштабируемые веб-приложения, необходимо понимать принципы разработки высокопроизводительных программных решений.

Принципы построения высокоэффективных решений

Динамика и гибкость

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

Либо потребуется добавить различные функции. А может вы решите продвигать свое приложение и привлекать клиентов. Поэтому вы должны обеспечить возможность эластичного масштабирования и обработки высоких нагрузок.

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

Постепенный рост проекта

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

Если вы запускаете новый продукт, нет смысла сразу же создавать инфраструктуру, способную выдержать миллионы пользователей и одновременно обрабатывать их многочисленные запросы.

Используйте облако для размещения новых проектов, поскольку оно позволяет снизить стоимость сервера, упрощает управление им и легко развертывает приложения.

Кроме того, многие сервисы облачного хостинга предлагают услуги приватной сети, что позволяет разработчикам программного обеспечения безопасно использовать серверы в облаке и осуществлять масштабирование системы.

Масштабирование веб-решения - это постепенный процесс, состоящий из 4 основных этапов:

  • Анализ нагрузки

  • Определение областей, на которые в основном воздействует нагрузка

  • Передача этих областей отдельным узлам и их оптимизация

  • Анализ нагрузки

Разработка масштабируемой архитектуры веб-проекта

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

Такой подход поможет вам сэкономить время и снизить затраты на разработку. Ниже представлены некоторые способы, которые помогут вам создать высокопроизводительные масштабируемые веб-приложения.

Разделение базы данных

Чаще всего первым узлом, который подвергается нагрузке, является база данных. Каждый запрос от пользователя к приложению - это, как правило, от 10 до 100 запросов к базе данных. Вынесение базы данных на отдельный сервер повысит ее производительность и снизит негативное воздействие на другие компоненты (PHP, Nginx и т.д.).

Миграция базы данных

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

  • Используйте простое решение - разместите объявление о планируемых работах на сайте и сделайте перенос. Лучше сделать это ночью, когда активность пользовательской аудитории минимальна.

  • Используйте репликацию для синхронизации данных с одного сервера на другой. После настройки необходимо изменить IP-адрес базы данных в приложении на новый сервер. Затем - выключить старый сервер.

Разделение веб-сервера

Далее следует отделить веб-сервер, выделение которого на отдельный узел позволит оставить больше ресурсов для приложения. Если говорить о примере с PHP, то необходимо настроить развертывание продукта как на сервер Nginx, так и на сервер PHP, представляющий бэкенд.

Тогда Nginx сам отдаст статические файлы, а PHP-сервер будет занят только обработкой скриптов. Nginx обеспечивает подключение к бэкенду по IP-адресу:

server {server_name ruhighload.com;root /var/www/ruhighload;index index.php;location ~* .(php)$ {fastcgi_pass 10.10.10.1:9000;fastcgi_index index.php;include fastcgi_params;fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;}}

Имейте в виду, что если вы используете загрузку файлов, то для их хранения необходимо выделить отдельный узел.

Используйте несколько бэкендов

Когда нагрузка возрастает, веб-приложение начинает работать медленнее. В какой-то момент причина будет заключаться уже в самой имплементации. Чтобы избежать подобных проблем, следует использовать несколько бэкендов PHP.

При инсталляции бэкендов убедитесь, что они имеют одинаковую конфигурацию. Используйте Nginx для балансировки нагрузки между ними. Для этого следует определить список бэкендов в апстрим (upstream) и использовать его в конфигурации:

upstream backend {server 10.10.10.1;server 10.10.10.2;server 10.10.10.3;}server {server_name ruhighload.com;root / var / www / ruhighload;index index.php;location ~ * . (php) $ {fastcgi_pass backend;fastcgi_index index.php;include fastcgi_params;fastcgi_param SCRIPT_FILENAME $ document_root $ fastcgi_script_name;}}

Когда вы начнете использовать несколько бэкендов, запросы от одного и того же пользователя будут отправляться на разные серверы. Это потребует единого репозитория для всех сессий.

Вы можете выбрать, например, Memcache. Также следует подключить кэш-серверы. Memcache будет самостоятельно распределять нагрузку между всеми серверами, используя постоянный алгоритм хэширования.

Очереди задач и балансировка DNS

Очереди задач позволяют асинхронно выполнять тяжелые операции, не замедляя работу основного приложения. Пока сервер очереди будет получать задания от веб-решения, другие серверы будут их обрабатывать. Если среднее количество задач в очереди будет расти, увеличьте количество серверов для балансировки нагрузки.

DNS поддерживает балансировку по принципу Round Robin, позволяя указать несколько IP-адресов принимающих веб-серверов, называемых фронтендами. В данном случае необходимо инсталлировать несколько одинаковых фронтендов, чтобы DNS выдавал разные IP-адреса разным клиентам. Таким образом, вы обеспечите балансировку между фронтендами.

Файловые хранилища

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

Более того, это может снизить производительность бэкенда. Чтобы избежать подобных трудностей, следует использовать отдельные серверы для загрузки, хранения и обработки файлов.

Сделать это можно следующим образом:

  • Определить отдельный поддомен для файлового сервера.

  • Развернуть на сервере Nginx и небольшое приложение, которое может хранить файлы и обрабатывать их

  • Масштабирование путем добавления новых серверов и поддоменов (например, images1, images2, images3 и т.д.)

  • Перенести загрузку файлов на сторону клиента, чтобы форма отправляла запрос на определенный сервер.

Нет ничего сложного в том, чтобы создать приложение, которое пропорционально масштабируется по серверам по мере роста потока трафика. Отсутствие статических данных, балансировка нагрузки, 90% кэширования, надежная сеть доставки контента и так далее - и у вас готова архитектура для работы с высокой нагрузкой.

Однако ключевым моментом является экономическая эффективность. Скажем, у вас 100 тысяч пользователей и один сервер. Значит, чтобы получить 130 тысяч из них, нужно разместить еще один сервер. Кажется, что это довольно сложно, не так ли?

Поэтому следует сделать один шаг назад и подумать - какая часть системы вызывает проблему? Если это база данных, то перед началом разработки проекта выберите высокомасштабируемую базу данных. Или вы можете использовать несколько баз данных, например, одну для записи и одну для чтения (CQRS).

Определение и решение подобных проблем производительности заранее и без резкого увеличения затрат на инфраструктуру является эффективной практикой для решения возникающих высоких нагрузок.


Перевод материала подготовлен в рамках запуска курса "Highload Architect".

Всех желающих приглашаем на бесплатный демоурок Выбор архитектурного стиля (микросервисы, СОА и монолиты).

- ЗАПИСАТЬСЯ НА ДЕМОУРОК

Подробнее..

Категории

Последние комментарии

  • Имя: Макс
    24.08.2022 | 11:28
    Я разраб в IT компании, работаю на арбитражную команду. Мы работаем с приламы и сайтами, при работе замечаются постоянные баны и лаги. Пацаны посоветовали сервис по анализу исходного кода,https://app Подробнее..
  • Имя: 9055410337
    20.08.2022 | 17:41
    поможем пишите в телеграм Подробнее..
  • Имя: sabbat
    17.08.2022 | 20:42
    Охренеть.. это просто шикарная статья, феноменально круто. Большое спасибо за разбор! Надеюсь как-нибудь с тобой связаться для обсуждений чего-либо) Подробнее..
  • Имя: Мария
    09.08.2022 | 14:44
    Добрый день. Если обладаете такой информацией, то подскажите, пожалуйста, где можно найти много-много материала по Yggdrasil и его уязвимостях для написания диплома? Благодарю. Подробнее..
© 2006-2024, personeltest.ru