0Pricing
Erlang OTP: Distributed & Fault-Tolerant Systems Programming · 강의

분산 합의 패턴

분산 시스템의 일관성을 유지하는 데 필수적인 분산 합의 알고리즘과 패턴을 이해하고 구현합니다.

분산 합의 패턴은(는) CoddyKit의 무료 Erlang OTP: Distributed & Fault-Tolerant Systems Programming 강의입니다. 이것은 4개 중 2번째 강의입니다. 아래에서 전체 강의를 무료로 읽을 수 있으며, 내장 코드 에디터와 24/7 AI 튜터와 함께 브라우저에서 직접 실습할 수 있습니다. 이 강의는 Erlang OTP: Distributed & Fault-Tolerant Systems Programming 학습 경로의 일부이며, 진행 상황이 웹과 CoddyKit 앱에 동기화됩니다. Erlang OTP: Distributed & Fault-Tolerant Systems Programming 강의에는 총 4개의 강의가 포함되어 있습니다.

이 강의의 일부는 아직 번역되지 않았으며 영어로 표시됩니다.

Agreeing in a Distributed World

Imagine multiple computers (nodes) needing to agree on a single outcome, even if some nodes fail or messages get lost. This challenge is called Distributed Consensus.

It's vital for maintaining data consistency and ensuring all parts of a system see the same "truth". Without it, your system might end up in a confused, inconsistent state.

The Hard Problem of Coordination

Achieving consensus is difficult because:

  • Network Delays: Messages don't arrive instantly or in order.
  • Node Failures: A computer might crash at any moment.
  • Message Loss: Messages can be dropped by the network.

How do you ensure everyone agrees when communication is unreliable and participants can vanish?

Where Consensus Shines

Distributed consensus patterns are foundational for many critical system features:

  • Leader Election: Deciding which node is the primary coordinator.
  • Atomic Commits: Ensuring a transaction either fully completes on all nodes or completely fails on all.
  • State Machine Replication: Keeping identical copies of data or application state across multiple nodes.

CAP and Consensus Trade-offs

The CAP Theorem states that a distributed system can only guarantee two out of three properties: Consistency, Availability, or Partition Tolerance.

Consensus algorithms typically prioritize Consistency and Partition Tolerance. This means during a network partition, the system might become unavailable for writes to prevent inconsistencies.

A Simple Agreement Protocol: 2PC

The Two-Phase Commit (2PC) protocol is a basic way to achieve atomic transactions across distributed nodes. It's often used in databases.

While not fully fault-tolerant (it can block if the coordinator fails), it's a great conceptual stepping stone to understanding more complex consensus algorithms.

The Coordinator: Orchestrating the Vote

In 2PC, one node acts as the Coordinator. Its job is to:

  1. Phase 1 (Prepare): Send a "prepare" or "vote request" message to all participating nodes.
  2. Phase 2 (Commit): Based on the votes, send a "commit" message if all voted "yes", or an "abort" message if any voted "no" (or timed out).

Participants: Deciding & Acting

Each Participant node in 2PC has these responsibilities:

  1. Phase 1 (Vote): When receiving "prepare", perform necessary checks. If ready to commit, reply "yes" and lock resources. Otherwise, reply "no".
  2. Phase 2 (Act): When receiving "commit", finalize the transaction. If "abort", roll back any changes and unlock resources.

Erlang Coordinator: Voting Process

Let's simulate a basic 2PC coordinator in Erlang. It spawns participants, sends a message, and collects their replies. This example simplifies error handling for clarity.

Note: This isn't production-ready 2PC, just an illustration of the message flow.

-module(coordinator).
-behaviour(gen_server).

-export([start_link/0, init/1, handle_call/3, handle_cast/2, handle_info/2, terminate/2, code_change/3]).
-export([propose/2]).

start_link() ->
    gen_server:start_link({local, ?MODULE}, ?MODULE, [], []).

init([]) ->
    {ok, []}.

propose(CoordinatorPid, Value) ->
    gen_server:call(CoordinatorPid, {propose, Value}).

handle_call({propose, Value}, _From, _State) ->
    % In a real system, participants would be registered or known
    Pids = [
        spawn(fun participant:start/0),
        spawn(fun participant:start/0)
    ],
    
    io:format("Coordinator: Proposing ~p to participants: ~p~n", [Value, Pids]),
    
    % Phase 1: Prepare
    Responses = [rpc:call(Pid, participant, prepare, [Value]) || Pid <- Pids],
    
    FinalDecision = 
        case lists:all(fun(ok) -> true; (_) -> false end, Responses) of
            true -> commit;
            false -> abort
        end,

    io:format("Coordinator: All participants voted, decision: ~p~n", [FinalDecision]),

    % Phase 2: Commit/Abort
    [rpc:call(Pid, participant, FinalDecision, []) || Pid <- Pids],

    {reply, FinalDecision, _State}.

handle_cast(_Msg, State) -> {noreply, State}.
handle_info(_Info, State) -> {noreply, State}.
terminate(_Reason, _State) -> ok.
code_change(_OldVsn, State, _Extra) -> {ok, State}.

% To run this example:
% 1. Compile both coordinator.erl and participant.erl
% 2. Start Erlang shell: erl
% 3. coordinator:start_link().
% 4. coordinator:propose(whereis(coordinator), "My Transaction").
% You should see output from both coordinator and participants.

Erlang Participant: Voting & Acting

Here's how a participant process might respond to the coordinator. It simulates a "vote" and then acts on the "commit" or "abort" instruction.

This participant always votes 'ok' in this simplified version, but in reality, it would check its own state.

-module(participant).
-behaviour(gen_server).

-export([start_link/0, start/0, init/1, handle_call/3, handle_cast/2, handle_info/2, terminate/2, code_change/3]).
-export([prepare/1, commit/0, abort/0]).

start_link() ->
    gen_server:start_link(?MODULE, [], []).

start() -> % Used by coordinator to spawn
    {ok, Pid} = start_link(),
    Pid.

init([]) ->
    io:format("Participant ~p: Started.~n", [self()]),
    {ok, #{} % State could hold transaction details
    }.

prepare(_Value) ->
    % In a real system, participant would check resources, lock them etc.
    % For simplicity, always vote 'ok' here.
    io:format("Participant ~p: Received prepare, voting 'ok'.~n", [self()]),
    ok.

commit() ->
    io:format("Participant ~p: Received commit, finalizing transaction.~n", [self()]),
    ok.

abort() ->
    io:format("Participant ~p: Received abort, rolling back transaction.~n", [self()]),
    ok.

handle_call(_Msg, _From, State) ->
    {reply, ok, State}. % Placeholder for any calls

handle_cast(_Msg, State) -> {noreply, State}.
handle_info(_Info, State) -> {noreply, State}.
terminate(_Reason, _State) -> ok.
code_change(_OldVsn, State, _Extra) -> {ok, State}.

The Pitfalls of 2PC

While illustrative, 2PC has significant drawbacks:

  • Single Point of Failure: If the coordinator crashes during Phase 2, participants might be left waiting indefinitely, holding locked resources. This is known as the "blocking problem".
  • Performance: It requires multiple rounds of communication, which can be slow in high-latency networks.

These limitations necessitate more robust, non-blocking consensus algorithms like Paxos or Raft for truly fault-tolerant systems.

Quick Check: Consensus Roles

In the Two-Phase Commit (2PC) protocol, what is the primary responsibility of a Participant node in Phase 1 (Prepare)?

Recap: Agreement is Key

We've explored Distributed Consensus, understanding its importance for consistency in distributed systems and the challenges it presents.

We looked at Two-Phase Commit (2PC) as a basic protocol, understanding the roles of the Coordinator and Participants, and its key limitations. Erlang's message passing is a great foundation for building these patterns, but true fault-tolerant consensus requires more advanced algorithms.

자주 묻는 질문

“분산 합의 패턴” 강의는 무료인가요?

네 — “분산 합의 패턴” 전체 내용을 이 웹사이트에서 무료로 읽을 수 있습니다. 인터랙티브하게 실습하려면(내장 코드 에디터와 24/7 AI 튜터), CoddyKit PRO로 업그레이드하면 Erlang OTP: Distributed & Fault-Tolerant Systems Programming 강의 전체를 잠금 해제할 수 있습니다. Erlang OTP: Distributed & Fault-Tolerant Systems Programming 강의에는 총 4개의 강의가 포함되어 있습니다.

“분산 합의 패턴”에서 뭘 배우나요?

분산 시스템의 일관성을 유지하는 데 필수적인 분산 합의 알고리즘과 패턴을 이해하고 구현합니다. 브라우저에서 직접 실행하는 실습 코드로 Erlang OTP: Distributed & Fault-Tolerant Systems Programming을(를) 배우며, 24/7 AI 튜터가 강의를 진행하면서 질문에 답변해줍니다.

Erlang OTP: Distributed & Fault-Tolerant Systems Programming을(를) 시작하는 데 경험이 필요한가요?

사전 경험은 필요하지 않습니다. CoddyKit의 Erlang OTP: Distributed & Fault-Tolerant Systems Programming은(는) 초급자부터 고급 학습자까지를 위해 구성되어 있으므로, 여기서 시작하거나 처음부터 시작할 수 있으며 자신의 속도대로 진행할 수 있습니다. 이것은 4개 중 2번째 강의입니다.

“분산 합의 패턴” 강의는 얼마나 걸리나요?

대부분의 CoddyKit 강의는 약 5~10분이 소요됩니다. 각 강의는 간결하고 인터랙티브하여 꾸준한 진행이 가능하며, 웹과 앱에서 중단한 부분부터 바로 시작할 수 있습니다.

이 Erlang OTP: Distributed & Fault-Tolerant Systems Programming 강의에서 코드를 작성하고 실행할 수 있나요?

네. 모든 Erlang OTP: Distributed & Fault-Tolerant Systems Programming 강의에는 내장 코드 에디터가 포함되어 있으므로, 브라우저에서 바로 실제 코드를 작성하고 실행한 후 즉시 AI 피드백을 받을 수 있습니다 — 로컬 설정이 필요 없습니다.

이 강의의 모든 강의

  1. 고가용성을 위한 설계
  2. 분산 합의 패턴
  3. Erlang OTP 사례 연구
  4. 백프레셔와 부하 조절 패턴
← Erlang OTP: Distributed & Fault-Tolerant Systems Programming(으)로 돌아가기