#synchronization #erlang #state #external
#синхронизация #эрланг #состояние #внешний
Вопрос:
Допустим, есть онлайн-магазин билетов, в котором есть 100 билетов на продажу. Если одновременно может быть много запросов на покупку билетов, существует риск возникновения условий гонки, потому что одновременно может быть 2 (или более) запроса на покупку последнего билета. И если программное обеспечение подсчитывает уже проданные билеты, возможно, что счетчик вернет 99 (таким образом, остается один билет) для двух запросов, поступающих одновременно. Таким образом, существует риск того, что программное обеспечение продаст 101 билет (вместо всего лишь 100 билетов). В большинстве императивных языков вы, вероятно, будете использовать что-то вроде ключевого слова «synchronized» (например, в Java), чтобы убедиться, что подсчет и продажа — это «атомарная» операция, в которой никакой другой запрос не может поступить до завершения обработки предыдущего запроса, верно?
Но как бы вы это сделали в erlang?
Я имею в виду, что в функции нет «состояния», верно? И многие запросы могут поступать одновременно, получая число 99 из счетчика, который подсчитывает билеты (например, из базы данных), которые уже проданы…
Итак, каким путем идти в эрланге?
Ответ №1:
Атомарные операции в Erlang
Процессы Erlang не совместно используют свою память, поэтому нет необходимости синхронизировать доступ к памяти каждого процесса.
ETS, которые разрешают общий доступ, имеют свойства ACID в большинстве методов, например, ets:update_counter/3
Кроме того, поскольку использование ETS только для счетчика сопряжено с большими накладными расходами, в OTP21 был предоставлен более низкоуровневый интерфейс для общих атомарных целых чисел
Куда идти (это субъективно)
Обычно можно начать с использования одного процесса (или их пула), используя модель актера передачу сообщений для обеспечения атомарности. Поскольку процесс отвечает за свою собственную память, внутри него нет условий гонки. В вашем примере это означало бы наличие процесса для каждого магазина и взаимодействие клиентов с ними.
Чаще всего этого бывает достаточно (упреждающее планирование / разделение домена творит чудеса), но если это не так, вы исследуете решения на основе ETS / atomics (атомарные операции — не единственные интересные качества ETS и atomics, у них есть и другие применения)
Внешнее состояние
Я намеренно опустил любую ссылку на «внешнее» состояние, потому что там вам приходится иметь дело с реальным миром: несколькими узлами, аварийными узлами, разделениями сети… и «синхронизированный» не решает вашу проблему там.
Синхронизация распределенных состояний требует гораздо больше работы, иногда сложность того не стоит, иногда эта сложность переносится на другую систему, такую как база данных.