Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Distributed Elixir

Distributed Elixir

Presentation about some of the tools for distributed programming in Elixir

Maciej Kaszubowski

July 07, 2018
Tweet

More Decks by Maciej Kaszubowski

Other Decks in Programming

Transcript

  1. It’s scary out there

    View Slide

  2. Organisational Matters

    View Slide

  3. View Slide

  4. We’re 1 year old!

    View Slide

  5. Summer break (probably)

    View Slide

  6. We’re looking for speakers!

    View Slide

  7. It’s scary out there
    Distributed Systems in Elixir
    Poznań Elixir Meetup #8

    View Slide

  8. View Slide

  9. Pid 1 Pid 2

    View Slide

  10. Pid 1 Pid 2
    Node A Node B

    View Slide

  11. The basics

    View Slide

  12. iex --name [email protected] --cookie cookie -S mix

    View Slide

  13. Node.connect(:’[email protected]')

    View Slide

  14. (DEMO)

    View Slide

  15. #PID<0.94.0>

    View Slide

  16. #PID<0.94.0>
    node identifier
    (relative to current node)

    View Slide

  17. #PID<0.94.0>
    node identifier
    (relative to current node)
    0 =a local process

    View Slide

  18. #PID<0.94.0>
    Process id
    node identifier
    (relative to current node)

    View Slide

  19. How does it work?

    View Slide

  20. Pid 1
    Node A
    Pid 2
    Node B

    View Slide

  21. Pid 1
    Node A
    Pid 2
    Node B
    TCP Connection

    View Slide

  22. send(pid2, msg)
    Pid 1
    Node A
    Pid 2
    Node B
    TCP Connection

    View Slide

  23. send(pid2, msg)
    Pid 1
    Node A
    Pid 2
    Node B
    destination_node = node(pid)
    TCP Connection

    View Slide

  24. send(pid2, msg)
    Pid 1
    Node A
    Pid 2
    Node B
    destination_node = node(pid)
    :erlang.term_to_binary(msg)
    TCP Connection

    View Slide

  25. send(pid2, msg)
    Pid 1
    Node A
    Pid 2
    Node B
    destination_node = node(pid)
    :erlang.term_to_binary(msg)
    TCP Connection

    View Slide

  26. send(pid2, msg)
    Pid 1
    Node A
    Pid 2
    Node B
    destination_node = node(pid)
    :erlang.term_to_binary(msg)
    TCP Connection
    :erlang.binary_to_term(encode)

    View Slide

  27. send(pid2, msg)
    Pid 1
    Node A
    receive msg
    Pid 2
    Node B
    destination_node = node(pid)
    :erlang.term_to_binary(msg)
    TCP Connection
    :erlang.binary_to_term(encode)

    View Slide

  28. Distributed Systems?

    View Slide

  29. Distributed Systems?
    Solved!

    View Slide

  30. Well, not exactly…

    View Slide

  31. Difficulties

    View Slide

  32. Node A
    Node B

    View Slide

  33. Node A
    Node B
    Node C

    View Slide

  34. Node A
    Node B
    Node C
    Node D

    View Slide

  35. View Slide

  36. A lot of messages

    View Slide

  37. us-east-1
    us-west-2

    View Slide

  38. 8 fallacies of
    distributed computing

    View Slide

  39. fallacies of distributed computing
    1. The network is reliable
    2. Latency is zero
    3. Bandwidth is infinite
    4. The network is secure
    5. Topology doesn’t change
    6. The is one administrator
    7. Transport cost is zero
    8. The network is homogenous

    View Slide

  40. CAP THEOREM

    View Slide

  41. CAP THEOREM
    us-west-2
    us-east-1

    View Slide

  42. CAP THEOREM
    us-west-2
    us-east-1
    Set X=5

    View Slide

  43. CAP THEOREM
    us-west-2
    us-east-1
    Set X=5
    Read X

    View Slide

  44. CAP THEOREM
    us-west-2
    us-east-1
    Set X=5
    Set X = 7

    View Slide

  45. Consistency or Availability
    (under network partition)

    View Slide

  46. Consistency or Speed
    In practice

    View Slide

  47. Guarantees

    View Slide

  48. Pid 1
    Pid 2
    Pid3
    Guarantees
    m1, m2, m3
    m4, m5, m6
    send(pid2, m1)
    send(pid2, m2)
    send(pid2, m3)
    send(pid2, m4)
    send(pid2, m5)
    send(pid2, m6)

    View Slide

  49. Pid 1
    Pid 2
    Pid3
    Guarantees
    m1, m2, m3
    m4, m5, m6
    send(pid2, m1)
    send(pid2, m2)
    send(pid2, m3)
    send(pid2, m4)
    send(pid2, m5)
    send(pid2, m6)
    Ordering between two processes
    is preserved

    View Slide

  50. Pid 1
    Pid 2
    Pid3
    Guarantees
    m4, m5, m6
    send(pid2, m1)
    send(pid2, m2)
    send(pid2, m3)
    send(pid2, m4)
    send(pid2, m5)
    send(pid2, m6)
    m1, m2, m3
    Delivery is not guaranteed

    View Slide

  51. Pid 1
    Pid 2
    Pid3
    Guarantees
    m1, m2, m3
    m4, m5, m6
    send(pid2, m1)
    send(pid2, m2)
    send(pid2, m3)
    send(pid2, m4)
    send(pid2, m5)
    send(pid2, m6)
    Ordering between different processes
    is not guaranteed

    View Slide

  52. [m1, m2, m3, m4, m5, m6]

    View Slide

  53. [m1, m2, m3, m4, m5, m6]
    [m4, m5, m6, m1, m2, m3]

    View Slide

  54. [m1, m2, m3, m4, m5, m6]
    [m4, m5, m6, m1, m2, m3]
    [m1, m4, m2, m5, m3, m6]

    View Slide

  55. [m1, m2, m3, m4, m5, m6]
    [m4, m5, m6, m1, m2, m3]
    [m1, m4, m2, m5, m3, m6]
    [m1, m2, m3]

    View Slide

  56. [m1, m2, m3, m4, m5, m6]
    [m4, m5, m6, m1, m2, m3]
    [m1, m4, m2, m5, m3, m6]
    [m1, m2, m3]
    [m1, m3, m5, m6]

    View Slide

  57. [m1, m2, m3, m4, m5, m6]
    [m4, m5, m6, m1, m2, m3]
    [m1, m4, m2, m5, m3, m6]
    [m1, m2, m3]
    [m1, m3, m5, m6]
    []

    View Slide

  58. [m1, m2, m3, m4, m5, m6]
    [m4, m5, m6, m1, m2, m3]
    [m1, m4, m2, m5, m3, m6]
    [m1, m2, m3]
    [m1, m3, m5, m6]
    []
    [m1, m3, m2, m4, m5, m6]

    View Slide

  59. [m1, m2, m3, m4, m5, m6]
    [m4, m5, m6, m1, m2, m3]
    [m1, m4, m2, m5, m3, m6]
    [m1, m2, m3]
    [m1, m3, m5, m6]
    []
    [m1, m3, m2, m4, m5, m6]
    [M3, M3]

    View Slide

  60. Phoenix
    Request A User Logged In

    View Slide

  61. Phoenix
    Request A
    Phoenix
    Request B
    User Logged In
    User Logged OUT

    View Slide

  62. Phoenix
    Request A
    Phoenix
    Request B
    User Logged In
    User Logged OUT
    This Can arrive first

    View Slide

  63. Unfortunately, things tend to work fine
    locally

    View Slide

  64. The Tools

    View Slide

  65. :global

    View Slide

  66. Pid 1
    Node A Node B
    Pid 2

    View Slide

  67. Pid 1
    Node A Node B
    Pid 2
    :global.register_name(“global”, self())

    View Slide

  68. Pid 1
    Node A Node B
    Pid 2
    :global.register_name(“global”, self())
    Register PId1 as “global”

    View Slide

  69. Pid 1
    Node A Node B
    Pid 2
    :global.register_name(“global”, self())
    Register PId1 as “global”
    Sure

    View Slide

  70. Pid 1
    Node A Node B
    Pid 2
    :global.register_name(“global”, self())
    Register PId1 as “global”
    Sure
    :global.whereis_name(“global”) = pid1

    View Slide

  71. Pid 1
    Node A Node B
    Pid 2
    :global.register_name(“global”, self()) :global.register_name(“global”, self())
    ?

    View Slide

  72. (DEMO)

    View Slide

  73. :global
    • single process registration (if everything works OK)
    • Favours availability over consistency
    • Information stored locally (reading is fast)
    • Registration is blocking (may be slow)

    View Slide

  74. :PG2

    View Slide

  75. Pid1
    Pid3
    Pid2
    []
    []
    []

    View Slide

  76. Pid1
    Pid3
    Pid2
    :pg2.create(“my_group”)
    []
    []
    []

    View Slide

  77. Pid1
    Pid3
    Pid2
    []
    []
    []
    join
    join
    :pg2.join(“my_group”, self()

    View Slide

  78. Pid1
    Pid3
    Pid2
    []
    [pid1]
    []
    Monitor
    Monitor
    :pg2.join(“my_group”, self()

    View Slide

  79. Pid1
    Pid3
    Pid2
    [pid1]
    [pid1]
    [pid1]
    Monitor
    Monitor
    :pg2.join(“my_group”, self()

    View Slide

  80. Pid1
    Pid3
    Pid2
    [pid1]
    [pid1]
    [pid1]

    View Slide

  81. Pid1
    Pid3
    Pid2
    :pg2.join(“my_group”, self()
    [pid1]
    [pid1, pid2]
    [pid1]

    View Slide

  82. Pid1
    Pid3
    Pid2
    join
    :pg2.join(“my_group”, self()
    join
    [pid1, pid2]
    [pid1, pid2]
    [pid1, pid2]

    View Slide

  83. Pid1
    Pid3
    Pid2
    [pid1]
    [pid2]
    [pid1]

    View Slide

  84. Pid1
    Pid3
    Pid2
    [pid1]
    [pid2]
    [pid1]

    View Slide

  85. Pid1
    Pid3
    Pid2
    [pid1]
    [pid2]
    [pid1]

    View Slide

  86. Pid1
    Pid3
    Pid2
    [pid1, pid2]
    [pid1, pid2]
    [pid1, pid2]

    View Slide

  87. It will heal, but the state in inconsistent for
    some time

    View Slide

  88. What does it matter?

    View Slide

  89. Node A
    Pg2
    Pg2
    Pg2
    Node B Node C

    View Slide

  90. Node A
    Pg2
    Pg2
    Pg2
    Node B Node C
    Phoenix Channels

    View Slide

  91. Node A
    Pg2
    Pg2
    Pg2
    Node B Node C
    Phoenix Presence

    View Slide

  92. Node A
    Pg2
    Pg2
    Pg2
    Node B Node C
    Phoenix Channels

    View Slide

  93. :pg2
    • Process groups
    • Favours availability over consistency
    • Information stored locally (reading is fast)
    • Registration is blocking (may be slow)

    View Slide

  94. Strongly consistent Solutions

    View Slide

  95. Strongly consistent Solutions
    • Consensus - Raft, Paxos, ZAB
    • Two-phase commit/THree-phase commit (2PC/3PC)
    • Read/Write quorums
    • Single database as a source of truth

    View Slide

  96. Summary

    View Slide

  97. Distributed Systems

    View Slide

  98. Well, not exactly…

    View Slide

  99. Asynchronous messages
    Distributed systems are all about

    View Slide

  100. Really, there’s no magic

    View Slide

  101. Just asynchronous messages between nodes

    View Slide

  102. Just asynchronous messages between nodes
    & node failures

    View Slide

  103. Just asynchronous messages between nodes
    & node failures
    & Communication failures

    View Slide

  104. Just asynchronous messages between nodes
    & node failures
    & Communication failures
    & Network partitions

    View Slide

  105. Tradeoffs
    Distributed systems are all about

    View Slide

  106. Where to go next

    View Slide

  107. Worth looking at
    • Riak_core
    • RAFT
    • Two-Phase Commit (2PC) / Three-Phase Commit (3PC)
    • CRDTs
    • LASP and Partisan

    View Slide

  108. Free online (click!)
    Elixir / Erlang

    View Slide

  109. Free PDF (Click!)
    Distributed Systems

    View Slide

  110. Theory (The hard stuff)

    View Slide

  111. • https://raft.github.io/ (Raft Consensus)
    • http://learnyousomeerlang.com/distribunomicon
    • https://www.rgoarchitects.com/Files/fallacies.pdf (Fallacies of distributed computing)
    • https://dzone.com/articles/better-explaining-cap-theorem (CAP Theorem)
    • https://medium.com/learn-elixir/message-order-and-delivery-guarantees-in-elixir-
    erlang-9350a3ea7541 (Elixir message delivery guarantees)
    • https://lasp-lang.readme.io/ (LASP)
    • https://arxiv.org/pdf/1802.02652.pdf (Partisan Paper)
    • https://bravenewgeek.com/tag/three-phase-commit/ (3PC)

    View Slide

  112. We’re looking for speakers!

    View Slide

  113. Thank You!
    Poznań Elixir Meetup #8

    View Slide