Erlangの世界ではmemcachedとか要らない
Erlangを始めてから感じたことは,今までPerlでやっていた時に比べて,いろいろなやり方が出来るようになる,ということ.
Webアプリに限らず,いろいろなアプリケーションで,より柔軟な設計が出来るようになると思う.
Perl(や同種のスクリプト言語では)基本的に1プロセス1スレッドの範囲内に縛られていて,コストを考えるとコードの一部の処理だけ並列処理することは出来なかったし,複数のプロセスでデータを共有しようと思うと基本的にはDBに入れるしかなかった.
たとえば,Perlで作られている大規模なサイトでは,DBの負荷を軽減するためにmemcachedが使われていることが多い.
もしErlangでサイトを作っていれば,memcachedなどをわざわざ使うまでもなく,同様のことが簡単に書けてしまう.
単にmemcachedと同じ事をするだけであれば大きなメリットは無いけれども,自前で書いた場合は仕様を簡単に変えられる.
たとえば,
・ワイルドカード指定でデータを消したい
・複数のデータの更新をatomicに行いたい
・複数台に分散するときの分散アルゴリズムを自前のものに差し替えたい
・キーの長さが250文字じゃ足りない
・2次元もしくは多次元のデータを入れて,行単位・列単位などでキャッシュデータを削除したい
なんて事をやりたくなったとき,自前で用意していれば容易に実装することが出来る.
ちなみに,非常に単純な場合,以下のようなコードで可能.
サーバ側:
クライアント側:
ちょっとテストした限りでは,性能もそれなりに出る模様.
(とりあえずPerlからmemcachedを呼び出したら,Perl側がボトルネックになってmemcached側にたいした負荷をかけられなかったので,詳しい測定は諦めた)
上のErlangのサンプルコードでは,キーは任意のデータ構造が使えるので,文字列だけじゃなく,{RowID, ColumnID} とか {CommunityID, ThreadID, ArticleID} みたいな構造でもOK.長さの制限も特になし.
これだけでも結構魅力的なのではないかと思う.
memcachedは一例だけれども,これ以外にも,たとえばレスポンスタイムを速くしたいために,処理の一部(たとえばアクセスログの記録)を別プロセスで非同期に行うようにするとか,今まで言語の仕様で縛られて出来なかったことが,Erlangだと色々出来る.
Erlangで書いていたら,こう出来たのに…という風に最近考えてしまうことが多い.
Webで使おうとすると,日本語対応のフレームワークとかが無いようなので,その辺が難しいところだけども...
Webアプリに限らず,いろいろなアプリケーションで,より柔軟な設計が出来るようになると思う.
Perl(や同種のスクリプト言語では)基本的に1プロセス1スレッドの範囲内に縛られていて,コストを考えるとコードの一部の処理だけ並列処理することは出来なかったし,複数のプロセスでデータを共有しようと思うと基本的にはDBに入れるしかなかった.
たとえば,Perlで作られている大規模なサイトでは,DBの負荷を軽減するためにmemcachedが使われていることが多い.
もしErlangでサイトを作っていれば,memcachedなどをわざわざ使うまでもなく,同様のことが簡単に書けてしまう.
単にmemcachedと同じ事をするだけであれば大きなメリットは無いけれども,自前で書いた場合は仕様を簡単に変えられる.
たとえば,
・ワイルドカード指定でデータを消したい
・複数のデータの更新をatomicに行いたい
・複数台に分散するときの分散アルゴリズムを自前のものに差し替えたい
・キーの長さが250文字じゃ足りない
・2次元もしくは多次元のデータを入れて,行単位・列単位などでキャッシュデータを削除したい
なんて事をやりたくなったとき,自前で用意していれば容易に実装することが出来る.
ちなみに,非常に単純な場合,以下のようなコードで可能.
サーバ側:
start() -> proc_lib:start(?MODULE, memcache_start, []), ok. memcache_start() -> global:register_name(memcache, self()), proc_lib:init_ack(ok), memcache_process(). memcache_process() -> receive {get, From, Key} -> From ! get(Key), memcache_process(); {put, Key, Val} -> put(Key, Val), memcache_process(); {shutdown} -> % 終了用 ok end.
クライアント側:
init() -> io:format("ping. ~w~n", [net_adm:ping('server@ipaddress')]), global:sync(), % すぐにglobalnameが反映されないので, % pingしたあとsyncしてから利用する io:format("register ~w~n", [global:registered_names()]). write() -> global:send(memcache, {put, N, <<"DATA">>}). read() -> global:send(memcache, {get, self(), N}), receive _Any -> ok end.
ちょっとテストした限りでは,性能もそれなりに出る模様.
(とりあえずPerlからmemcachedを呼び出したら,Perl側がボトルネックになってmemcached側にたいした負荷をかけられなかったので,詳しい測定は諦めた)
上のErlangのサンプルコードでは,キーは任意のデータ構造が使えるので,文字列だけじゃなく,{RowID, ColumnID} とか {CommunityID, ThreadID, ArticleID} みたいな構造でもOK.長さの制限も特になし.
これだけでも結構魅力的なのではないかと思う.
memcachedは一例だけれども,これ以外にも,たとえばレスポンスタイムを速くしたいために,処理の一部(たとえばアクセスログの記録)を別プロセスで非同期に行うようにするとか,今まで言語の仕様で縛られて出来なかったことが,Erlangだと色々出来る.
Erlangで書いていたら,こう出来たのに…という風に最近考えてしまうことが多い.
Webで使おうとすると,日本語対応のフレームワークとかが無いようなので,その辺が難しいところだけども...
The comments to this entry are closed.
Comments