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

Атомарность: A в ACID

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

Давайте представим, что наша база данных состоит из банковских счетов, и Элвин пытается отправить Бену 10 долларов. Мы могли бы применить это на практике, сначала вычтя 10 долларов со счета Элвина, а затем добавив 10 долларов на счет Бена.

Но что произойдет, если сразу после того, как мы выполним вывод, эта система выйдет из строя? После этого пополнение не обрабатывается, а деньги «выводятся» из системы. Мы называем это состоянием на полпути или частичным успехом, поскольку завершена только часть операции, а некоторые ее части остались незавершенными.

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

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

Консистенция: C в кислоте

Как и многие термины в программной инженерии, термин «согласованность» имеет несколько различных значений. Давайте рассмотрим два из них.

Согласованность данных

Согласованность данных относится к состоянию, в котором данные в системе точны, действительны и соответствуют всем желаемым ограничениям.

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

Свежесть Консистенция

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

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

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

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

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

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

Изоляция: I в ACID

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

Без гарантии изоляции данных

Возьмем предыдущий пример, где у нас есть база данных с банковскими счетами, и Элвин переводит 10 долларов Бену, и эта операция выполняется в рамках одной атомарной группы (или транзакции базы данных).

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

  • Запрос до начала перевода:если мы запросим общую сумму наличных до начала перевода, мы получим 200 долларов США.
  • Запрос после завершения перевода.Если мы запросим общую сумму наличных после завершения перевода, мы также получим 200 долларов США.
  • Запрос в середине перевода: если мы запрашиваем общую сумму наличных в середине перевода, существует критический момент между первой и второй операциями, когда система не находится в действительном состоянии. государство, потому что 10 долларов отсутствуют.

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

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

С гарантией изоляции данных

Давайте посмотрим, что происходит в базе данных с гарантиями изоляции. Когда транзакция перевода удаляет деньги со счета Элвина, это изменение изолировано и видно только внутри той же транзакции, скрытой от других транзакций. Таким образом, база данных может скрыть факт выполнения транзакции и позволить другой операции запрашивать учетные записи Элвина и Боба, как если бы передача еще не началась. Когда транзакция передачи завершается, ее последствия сразу становятся видимыми. Это означает, что никогда не бывает момента, когда одновременный запрос может увидеть неверную информацию, и поэтому транзакции изолированы друг от друга.

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

Долговечность: D в КИСЛОТЕ

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

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

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

Если база данных не использует пакетную обработку и записывает в постоянное хранилище при каждом запросе, является ли она надежной? Не совсем так. Постоянное хранилище на самом деле состоит из трех разных компонентов.

  1. Операционная система
  2. Контроллер дисковода
  3. Фактические физические атомы и электроны, используемые для хранения

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

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

Взглянув на реальную реализацию долговечности на примере Redis, можно выделить 3 основных уровня долговечности.

  1. Append Only File (AOF):записывает каждую запись, как только она получена. Несмотря на то, что он записывает каждую запись, он не всегда долговечен, поскольку это зависит от политики сброса. Redis использует термин fsync, сокращение от «синхронизация файловой системы», как синоним очистки.
  2. База данных Redis (RDB): создает снимки на определенный момент времени. Другими словами, через каждые N секунд он сохраняет все данные в базе данных на диск. Если у вас отключится электричество, вы потеряете все данные с момента последнего сохранения, которое было не более N секунд назад. Это не соответствует критериям долговечности, но показывает компромисс между настойчивостью и производительностью. Если вы сохраняете чаще, вы теряете меньше данных, но вам приходится тратить больше времени на сохранение.
  3. Без сохранения.При завершении процесса базы данных или отключении электроэнергии все данные теряются. Это достаточно легко понять. Это может быть полезно, если ваше приложение в порядке со всеми данными, которые стираются в любой момент, как недолговечный кеш.

Резюме

Напомним, что база данных считается долговечной, если она может гарантировать при каждой операции записи, что, когда база данных говорит «запись завершена», данные закодированы в реальных физических атомах и электронах. Недостатком этого является то, что принудительная физическая запись для каждого обновления делает обновления медленнее, поэтому существует компромисс между долговечностью и производительностью. Мы рассмотрели 3 основных способа, которыми Redis поддерживает надежность. Первый — всегда, который сбрасывается при каждой записи. Это долговечно! Но, как отмечает пост, это очень медленно. Второй вариант — каждые N секунд, что не является устойчивым, но обеспечивает не более N секунд потери данных, аналогично предыдущему подходу, сохраняющему каждые N секунд. И последнее не сбрасывает явно и оставляет на усмотрение операционной системы органическое решение о том, когда записывать на диск. Какая конфигурация является наиболее идеальной, должен решить разработчик приложения, исходя из того, для чего используется технология, принимая во внимание компромиссы.

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