Caching: ETS, Mnesia, Redis

Hi Michael,

We’ve used mnesia as a distributed cache quite a lot and it is good at
it. However this is from an erlang code base and not elixir. I’ve heard
mnesia is not quite as natural to use in elixir due to use of records.
In the simplest case like a cache you can use it fine
with just tuples, i.e only key/value instances in the database and don’t
have to define any records.

Potential pain points with mnesia.

  • Adding/removing nodes are not seamless and you have to write a little
    bit of logic to it.
  • The more nodes you have the slower writes are. If you have an almost
    static number of nodes (i.e not adding/removing nodes all the time)
    and not too frequent writes it is fine. Writes are not super slow but
    they can become a bottle neck. I think we had something like 3000 w/s
    on a three node cluster.
  • With distributed mnesia you run the risk of having node-splits which
    sort of can be handled (have a look at uwiger/unsplit) but the best thing is
    if you can afford to re-populate data from the database in case that
    happens.
  • If you have lots of data, when starting up mnesia sometimes (or
    everytime? can’t remember) and the data it holds is deemed out of
    data it copies the entire data set from another node). This can lead
    to bursts in traffic on startup.
  • Read time is blazingly fast (like ets). This can’t be achieved with
    any external data cache
  • You need to keep the cache data-set in memory. Mnesia do support table
    fragmentation so you can potentially spread it out over multiple node
    but it is quite a manual task to implement.

So a quick re-cap. If your data is temporary and can be recreated from
another data-source; You don’t have lots of nodes being added/removed
and you are on a stable network to avoid netsplits mnesia shines
as a distributed cache to your database

Cheers,
Martin

1 Like