Читаем Создание микросервисов полностью

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

В системе управления реляционными базами данных (RDBMS), подобной MySQL или Postgres, данные могут копироваться из основного узла в одну или несколько реплик. Зачастую это делается с целью обеспечения безопасного хранения копий данных, но может использоваться также для распределения операций чтения. Сервис может направлять все запросы на запись к единственному основному узлу, но при этом распределять запросы на чтение между несколькими репликами, предназначенными для считывания данных (рис. 11.6). Резервное копирование из основной базы данных к репликам происходит через некоторое время после записи. Это означает, что при такой технологии считывания до завершения репликации данные могут быть устаревшими. Со временем операциям чтения станут доступны согласующиеся данные. Подобная настройка называется согласованностью, возникающей по прошествии некоторого времени, и если вы в состоянии справиться с временной несогласованностью, то ее можно признать довольно простым и весьма распространенным способом, содействующим масштабированию систем. Вскоре, когда дойдет очередь до теоремы CAP, мы рассмотрим его более подробно.

Рис. 11.6. Использование реплик для чтения с целью масштабирования операций считывания данных

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

Масштабирование для производства записей

Масштабирование чтения дается сравнительно легко. А как насчет записей? Один из подходов предусматривает применение фрагментации. При этом используются несколько узлов базы данных. Берется часть данных, подлежащих записи, к ним применяется некая функция хеширования для получения ключа данных, и на основании результата работы функции определяется, куда эти данные отправлять. Рассмотрим весьма упрощенный (и совсем негодный) пример: представим, что клиентские записи диапазона A — M попадают в один экземпляр базы данных, а записи диапазона N — Z — в другой. Этим можно управлять самостоятельно в своем приложении, но некоторые базы данных, например Mongo, многое в этом плане делают за вас.

Сложность с фрагментацией операций записи данных заключается в управлении запросами. Когда смотришь на отдельно взятую запись, все представляется несложным, поскольку можно просто применить функцию хеширования, чтобы найти нужный экземпляр данных, а затем извлечь его из соответствующего фрагмента базы. А как быть с запросами, данные которых разбросаны по нескольким узлам, например предписывающими найти всех клиентов старше 18 лет? Если требуется запросить все фрагменты базы, то нужно либо запросить каждый отдельно взятый фрагмент и объединить ответы в памяти, либо иметь альтернативное хранилище для чтения, в котором доступны данные из обоих наборов. Зачастую отправкой запросов, распространяющихся на несколько фрагментов, управляет асинхронный механизм с использованием кэшируемых результатов. Например, в Mongo для выполнения таких запросов используются задания отображения и свертки (map/reduce jobs).

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

Перейти на страницу:

Похожие книги