[Elixir in Action]Erlang Term Storageを知る

Getting Startedなどやっているとよく出てくる、定番な機能ですね。ETSは Erlang Term Storage の略です。



  • Positive
    • etsは、owner processが起動している間だけ使える(in-memoryで)
    • serialize(連続的に)なキャッシュに書き込める
    • 分けられたメモリ空間に書き込まれ、多くのprocessから並行にアクセス可能
      • globalでアクセス可能
    • mutable
    • 非常に高速なアクセスが可能
      • 末尾に内容を記載
  • Negative
    • client processとETS tableはコピーされる
      • ETSに保存されるデータが原因でprocessがcrashする場合、 Supervisorによってリカバリされたprocessも再びcrashする という、悪循環に陥ることがある
        • BEAMの良さであるリカバリシステムを崩す原因になる
      • ETSには、複雑で大きなデータは扱うべきではない
    • ETSはネットワーク越しの他BEAMインスタンスとは共有できない
    • 本当に性能/拡張性を改善したいときだけにするといった用途を制限するほうが良い
      • 高い性能で多くのprcessで共有したいデータか?など




  • table types
    • :set The table is a set table – one key, one object, no order among objects. This is the default table type.
    • :ordered_set The table is a ordered_set table – one key, one object, ordered in Erlang term order, which is the order implied by the operators. Tables of this type have a somewhat different behavior in some situations than tables of the other types. Most notably the ordered_set tables regard keys as equal when they compare equal, not only when they match. This means that to an ordered_set, the integer() 1 and the float() 1.0 are regarded as equal. This also means that the key used to lookup an element not necessarily matches the key in the elements returned, if float()’s and integer()’s are mixed in keys of a table.
    • :bag The table is a bag table which can have many objects, but only one instance of each object, per key.
    • :duplicate_bag The table is a duplicate_bag table which can have many objects, including multiple copies of the same object, per key.
  • table access permission
    • :public Any process may read or write to the table.
    • :protected The owner process can read and write to the table. Other processes can only read the table. This is the default setting for the access rights.
    • :private Only the owner process can read or write to the table.


iex(10)> a = :ets.new :neko, [:set]
iex(11)> :ets.insert a, {:neko, 1}
iex(12)> :ets.insert a, {:neko, 2}
iex(13)> :ets.lookup a, :neko
[neko: 2]
iex> a = :ets.new :neko, [:bag]
iex> :ets.insert_new a, {:neko, 1}
iex> :ets.insert_new a, {:neko, 2}
iex> :ets.liikup a, :neko
[neko: 1, neko: 2]
iex> a = :ets.new :neko, [:duplicate_bag]
iex> :ets.insert a, {:neko, 1}
iex> :ets.insert a, {:neko, 2}
iex> :ets.insert a, {:neko, 2}
iex> :ets.lookup a, :neko
[neko: 1, neko: 2, neko: 2]


:ets.select/2 には以下のような仕様が与えられています。要素を取り出すとき、様々な条件式を与えることができるのですね。

  • select(Tab, MatchSpec) -> [Match]
    • Types:
      • MatchSpec = [MatchFunction]
      • MatchFunction = {MatchHead, [Guard], [Result]}
      • MatchHead = “Pattern as in ets:match”
      • Guard = {“Guardtest name”, …}
      • Result = “Term construct”

:ets. fun2ms/1 を使うと、↑のMatchSpecを変数として定義もできるので、これで関数を定義して select で引数として要素を取得する、という流れができそうですね。


:ets を使ったキャッシュと、single processベースのキャッシュ。比較すると10倍程度の秒間リクエスト数が増加するらしいですね。:ets のほうが10倍程度多く秒間にアクセス/処理を実施できていました。スループットもetsのほうが高いとでていました。例は書籍をごらんください。

そのため、single processの処理性能が低いというボトルネックを解消する手段としては有効なのですね。なるほど。

ここら辺まで読んで、この書籍はGetting StartedやProgramming Elixirを読んで取り掛かると良いかなという感じですね。いきなりこの書籍は中々理解に時間がかかりそう。


One thought on “[Elixir in Action]Erlang Term Storageを知る

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )


Connecting to %s