Skip to content

Latest commit

 

History

History
228 lines (176 loc) · 7.49 KB

PITCHME.md

File metadata and controls

228 lines (176 loc) · 7.49 KB

Дистрибутиран Elixir


Image-Absolute


Съдържание

  1. Какво означава да сме дистрибутирани?
  2. Node-ове и функции за свързване и комуникация
  3. Проблемите на дистрибутираните системи
  4. Да си напишем чат!
  5. Да помислим за проблеми с чата...
  6. Тестване на дистрибутиран Elixir
  7. Кога да ползваме дистрибутиран Elixir

  • Дистрибутираност значи програмата ни да върви на повече от една виртуални машини.
  • Elixir ни дава добри инструменти за постигане на това. |

  • Виртуалните машини на Elang/Elixir наричаме ноудове (nodes).
  • Един node е една виртуална машина. |
  • Те може да са отворени за комуникация с други ноудове или не. |

Функции за статус на node

  • Как да видим името на node-a си? |
  • Как да направим node-а си 'жив'? |

Свързване на node-ове

  • Списък на свързаните node-ове. |
  • Свързване на node-ове. |
  • Връзките между node-ове са транзитивни. |

Създаване на процеси на отдалечени node-ове

  • Node.spawn и неговите версии. |
  • Основата на комуникацията между node-ове са процесите. |

# @slavi
defmodule DB do
  def tell_us_secret do
    IO.puts("Познавам всички и всеки!")
  end
end
# @valo
Node.spawn(:slavi@meddland, DB, :tell_us_secret, [])
#output: Познавам всички и всеки!
#=> #PID<9473.144.0>

Наблюдаване на Node-ове

Node.monitor(some_node, true)

Извикване на отдалечени функции

  • Използва се Erlang модула :rpc. |
  • Отдолу работим с процеси. |

:rpc.call/4 (Има и cast версия)

# @valo

:rpc.call(:slavi@meddland, DB, :tell_us_secret, [])
#=> Познавам всички и всеки!
#=> :ok

async_call и yield

# @valo
pid = :rpc.async_call(:meddle@meddland,
                      Enum,
                      :sort,
                      [(1..2_000_000) |> Enum.shuffle])
#=> #PID<0.115.0>

# Това няма да забие текущия процес докато резултата е готов.

:rpc.yield(pid)
# Ще чака за резултат, или ако е готов ще го върне

nb_yield

# @valo
pid = :rpc.async_call(:slavi@meddland, Process, :sleep, [50_000])
#=> #PID<0.108.0>

# По подразбиране timeout-a е нула.
# Пробва и ако няма резултат - :timeout
:rpc.nb_yield(pid)
#=> :timeout
:rpc.nb_yield(pid, 1_000)
#=> :timeout

:rpc.nb_yield(pid, 50_000)
#=> {:value, :ok}

multicall и eval_everywhere

# @slavi
Node.list()
#=> [:meddle@meddland, :valo@meddland]

:rpc.multicall([Node.self() | Node.list()], Node, :self, [])
#=> {[:slavi@meddland, :meddle@meddland, :valo@meddland], []}

EPMD

Image-Absolute


  • Когато стартираме node с име или пък му дадем име в последствие, той ще се свърже към програма, наречена EPMD или Erlang Port Mapper Daemon.
  • Такава програма върви на всеки компютър на който има поне един 'жив' Erlang или Elixir node.

  • EPMD е нещо като сървър за имена, който позволява регистриране, комуникация и връзка между node-ове.
  • EPMD map-ва имена на node-ове към машинни адреси. |
  • Програмата пази само name частта от name@host, защото си знае хоста. |

Кога се стартира EPMD?

  • Ако няма вървящ EPMD и стартираме node с име, автоматично се стартира. |
  • Портът му по подразбиране е 4369, но може да се конфигурира друг. |
  • Не е добра идея, защото Ericsson са го регистрирати официално за EPMD и би трябвало да е свободен. |

iex --sname andi --erl \
  "-kernel inet_dist_listen_min 54300 inet_dist_listen_max 54400"

PID

Image-Absolute


# От valo@meddland

Node.spawn(
  :meddle@meddland,
  fn -> send(pid(0, 86, 0), "Hello from valo!") end
)
# #PID<9107.110.0>

  • Това, което Node.spawn/2 връща е pid, но изглежда малко странно.
  • Свикнали сме първото число да е 0, а тук не е. |
  • Това е така защото първото число на pid-а е свързано с node-а, на който процеса му се изпълнява. |

  • Ако процесът върви на текущия node, то винаги е 0.
  • Ако обаче процесът върви на друг node, числото уникално ще идентифицира този друг node. |
  • Тази стойност за един и същи node ще е различна на различни node-ове, свързани с него. |

Типа данни PID

  • Първото число на pid показва на кой node върви процеса.
  • Второто е брояч, а третото допълнение към този брояч.
  • Когато минем максималния брой процеси за дадения node, третото число се увеличава с едно.

Демонстрация

binary_pid = :erlang.term_to_binary(pid)

Дистрибутирани програми - проблемите


Image-Absolute


  • На мрежата не винаги може да се разчита. Node-ове могат да изчезнат.
  • Мрежата може да бъде бавна от време на време. Резултатите от извиквания могат да се забавят. |
  • Bandwidth. Малки и прости съобщения! |
  • Security. Това трябва да си го постигнем сами! |

  • Топологията на мрежата не е константа - имена и локации - трябва да внимаваме.
  • Рядко ние имаме пълен контрол над физическите машини в мрежата. |
  • Транспортът е скъп. Малки, прости съобщения! |
  • Мрежата няма определен формат. Трябва ние да определим формат и протокол. |

CAP

Image-Absolute


Image-Absolute


Image-Absolute


Coding Time!

Image-Absolute