4
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Elixirプロセス間通信/分散/並行は23種類もあるってご存じでした?

Last updated at Posted at 2025-12-06

この記事は、Elixir Advent Calendar 2023その4 の1日目です


piacere です、ご覧いただいてありがとございます :bow:

Elixirプロセス間通信/分散/並行の方式が23種類もあるってご存じですか?

2023年時点では18種類 でしたが、そこからの2年で更に5つ、増えました

新し目のフィーチャは動画が充実しており、連動した新たな実践コラムや Elixir実践入門 のような書籍も増えていますので、2023年版よりも分かりやすくなっているかと思います

なお、下記の皆さまの実践コラムをリンクさせていただきました(ありがとございます) :information_desk_person:

@kikuyuta さん
@pojiro さん
@twinbee さん
@32hero さん
@RyoWakabayashi さん
@koyo-miyamura さん
@mokichi さん
@mnishiguchi さん
@GeekMasahiro さん
@MzRyuKa さん
@nako_sleep_9h さん
@Yoosuke さん
@t-yamanashi さん
@myasu さん
@B_tanuki さん
@nanbut14 さん
@zacky1972 さん
@ekzemplaro さん
@Shintaro_Hosoai さん
@mito_mito さん
@hisaway さん

Elixirアドベントカレンダー、応援お願いします :bow:

今年もやっています

① Stream

遅延リスト処理を実行する Stream は、プロセス単位の分離/分散では無いものの、並行処理の最もシンプルな例です

from @GeekMasahiro さん

from @kikuyuta さん

② spawn/send/receive

spawnシリーズ(関数を定義しつつプロセスとして起動名前付き関数をプロセスとして起動親プロセスとリンクするプロセスを起動 など)によるプロセス起動と、プロセス間でメッセージパッシングするsend/receiveは、並行/分散の最小単位です

from @MzRyuKa さん

from @nako_sleep_9h さん

from @Yoosuke さん

from @piacerex

③ Parallel Map

リストの各要素に対し、上記したspawn/sendでマルチコア並列化し、各々をreceiveで受け取るよう非同期化したものがParallel Mapです

from @RyoWakabayashi さん

④ Task

上記spawn/send/receiveのイディオムを、async/awaitによるシンプルなワーカープロセスに置き換え、バックグラウンド実行や非同期処理に特化させたものが Task です

from @t-yamanashi さん

from @pojiro さん

⑤ GenServer

上記Taskに、状態を保持できるようサーバープロセス化したものが GenServer です ※正確には、GenSeverから状態保持をオミットして作られたものがTaskです

同期処理(handle_call)/非同期処理(handle_cast)を選択できます

from @B_tanuki さん

from @piacerex

⑥ Agent

上記GenServerの状態を保持する部分を簡略化したものが Agent です

オブジェクト指向のメンバー変数のような使い方ができますが、実装としてはサーバープロセスに状態を保持しており、メッセージパッシングで状態操作をしています

from @B_tanuki さん

from @GeekMasahiro さん

from @kikuyuta さん

⑦ ETS/Registry

上記GenServerやAgentのような、1つの状態だけを保持するのでは無く、複数の状態をまとめて保持できるようにしたサーバープロセスが、インメモリDBである ETSRegistry です

いずれも、単一マシン上でのローカルアクセスしか出来ませんので、複数マシンでの共有をしたい場合は、後述するMnesiaやRedixを使う必要があります

from @nanbut14 さん

from @mnishiguchi さん

from @kikuyuta さん

⑧ GenStage

データ群をGenServerで作られたPubプロセス群に渡し、GenServerで作られたSubプロセス群に非同期でバケツリレーするPubSunが GenStage です

キューやバックプレッシャーを簡単に構築できます

from @twinbee さん

⑨ Flow

上記GenStageを応用して、マルチコア並列データ処理のパイプラインをシンプルに実現するのが Flow です

リスト処理するEnumとほとんと同じ書き味で、データ処理を並列化できます

from @twinbee さん

from @t-yamanashi さん

from @zacky1972 さん

⑩ Broadway

上記GenStageによるPubSub/キュー処理を抽象化しつつ、QoSや障害時ハンドリング、外部キュー連携(Amazon SQS、Google Cloud PubSub、Kafka、RabbitMQ、AMQP、Redis、Redis Stream、Splunk)を加えたものが Broadway です

from @RyoWakabayashi さん

⑪ Mnesia

上記ETSをマルチクラスタ分散化し、冗長化と自動復旧を可能としたのが Mnesia です

from @32hero さん

from @piacerex

⑫ Redix

インメモリDBであるRedisをElixirから使うアダプターが、Redix です

from @ekzemplaro さん

from @koyo-miyamura さん

⑬ Erlang分散(Node/global/EPMD/pg)

Node は、マルチクラスタ分散化されたElixirノードを制御するためのモジュールです

遠隔地にあるクラスタ上のプロセスとの通信を行う前のElixirノード間接続やその確認を行うのに使用します

マルチクラスタのプロセス名管理と分散ロックに global が使われます

分散化されたプロセスのグループ管理に pg が使われます

これら分散環境における名前解決を行うサーバープロセスがEPMDで、各クラスタごとに起動されます

from @piacerex

from @zacky1972 さん

⑭ libcluster

TCP/IP上でのマルチクラスタ分散化されたElixirノードを実現するのが libcluster です

下記ディスカバリ戦略を選択できます

  • Gossip … スケーリングは固定
  • EPMD … スケーリングは固定、Elixirネイティブ
  • k8s … オートスケーリング、自己修復
  • ECS統合 … オートスケーリング
  • EC2統合 … オートスケーリング

from @piacerex

from @mokichi さん

from @mnishiguchi さん

⑮ dns_cluster

DNSをディスカバリ戦略としてlibclusterと同様のことを実現するのが dns_cluster てす

Phoniex 1.6から標準装備となりました

⑯ Rustler/Port/ErlPort/KafkaEx

いずれもElixirから他システムと連携するライブラリで、RustやPython等の他言語のシステムや、Kafka経由でのリモートシステム分散化を叶えます

from @Shintaro_Hosoai さん

from @pojiro さん

⑰ Protobuf/gRPC

ElixirでProtobuf/gRPCを行うことでも他システムと連携できますが、protobufgrpc で実装できます

from @myasu さん

⑱ Channel

Channel は、WebSocketによって、何百万ものクライアントとの同時接続とメッセージ交換を叶えるPhoenix標準の仕組みです

HTTPベースのため高速では無いものの、複数クライアントで同一ステートを共有できる便利な分散システムです

⑲ LiveView

Channelを土台とし、Web SPAアーキテクチャを提供する LiveView は、複数フロントで1つの状態を共有/配信できるメカニズムでもあります

from @mito_mito さん

from @piacerex

⑳ LiveView stream

LiveView stream は、LiveViewで遅延処理を提供することで、大きなリストや絶え間なく更新されるデータ(連続データフィードやチャットアプリ等)を扱えるようにします

無限スクロール/遅延ロード/UIへのPubSub等の簡素化をもたらしつつ、パフォーマンス向上/メモリ使用量の劇的削減/フロントへの差分更新効率化も実現します

from @hisaway さん

from @mokichi さん

㉑ LiveView async

これまでTask等を使わなければ実現できなかったLiveViewのバックグラウンド/非同期処理をカンタンに書けるようにしたのが、LiveView async です

UIブロック解消によるUX向上とエラーハンドリング/タイムアウトの簡素化も実現します

from @t-yamanashi さん

from @piacerex

㉒ FLAME

FLAME は、Elixirの関数に対し、サーバーレス/FaaS同様のデマンド実行やスケーラビリティを実現するライブラリです

FLAMEは、サーバーレス/FaaSと比べ、既存システムのサーバーレス化/FaaS化のためのコード解体/再構成やマイクロ化が必要無く、サーバーレス/FaaSほど構成が複雑化しない点が大きなメリットです

from @kikuyuta さん

㉓ Livebookノード

Elixirは、iexやバイナリイメージ、escriptだけで無く、Web上開発環境の Livebook でも実行できますが、**Livebookは1つのElixirノードでもあり、分散クラスタのノードとして扱えます

つまり、通常コードの分散先にもできれば、Livebook/iex間での分散、Livebook間での分散等も可能ということです**

なおLivebook 0.13以降からは、Elixirノードとしてだけに限らず、REST API/GraphQL APIサーバーやExcelパーサーとしても構築可能となり、ますます分散環境として魅力的になっています

from @piacerex in ElixirImp#31「Elixirで作ったもの、何でもLT会」

終わりに

Elixirのバリエーションに富んだプロセス間通信/分散/並行の片鱗が伝わったら幸いです

ご興味ある方は、各イディオムで紹介した実践コラムを試して、その深淵を味わってください

なお今回、ご紹介したElixirプロセス間通信/分散/並行は、あなたのスキルからBright(輝き)とRight(正しさ)を引き出すプロダクト「Bright」でもスキル判定対象になっています

image.png

p.s.このコラムが、面白かったり、役に立ったら…

image.png にて、どうぞ応援よろしくお願いします :bow:

4
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?