Nebulex v1.2.0 Nebulex.Adapters.Replicated View Source

Built-in adapter for replicated cache topology.

The replicated cache excels in its ability to handle data replication, concurrency control and failover in a cluster, all while delivering in-memory data access speeds. A clustered replicated cache is exactly what it says it is: a cache that replicates its data to all cluster nodes.

There are several challenges to building a reliably replicated cache. The first is how to get it to scale and perform well. Updates to the cache have to be sent to all cluster nodes, and all cluster nodes have to end up with the same data, even if multiple updates to the same piece of data occur at the same time. Also, if a cluster node requests a lock, ideally it should not have to get all cluster nodes to agree on the lock or at least do it in a very efficient way (:global is used for this), otherwise it will scale extremely poorly; yet in the case of a cluster node failure, all of the data and lock information must be kept safely.

The best part of a replicated cache is its access speed. Since the data is replicated to each cluster node, it is available for use without any waiting. This is referred to as "zero latency access," and is perfect for situations in which an application requires the highest possible speed in its data access.

However, there are some limitations:

  • Cost Per Update - Updating a replicated cache requires pushing the new version of the data to all other cluster members, which will limit scalability if there is a high frequency of updates per member.

  • Cost Per Entry - The data is replicated to every cluster member, so Memory Heap space is used on each member, which will impact performance for large caches.

Based on "Distributed Caching Essential Lessons" by Cameron Purdy.

Options

These options can be set through the config file:

  • :primary - The module for the primary storage. The value must be a valid local cache adapter so that the partitioned adapter can store the data in there. For example, you can set the Nebulex.Adapters.Local as value, unless you want to provide another one.

Runtime options

These options apply to all adapter's functions.

  • :timeout - The time-out value in milliseconds for the command that will be executed. If the timeout is exceeded, then the current process will exit. This adapter uses Task.await/2 internally, therefore, check the function documentation to learn more about it. For commands like set_many and get_many, if the timeout is exceeded, the task is shutted down but the current process doesn't exit, only the result associated to that task is just skipped in the reduce phase.

  • task_supervisor_opts - Defines the options passed to Task.Supervisor.start_link/1 when the adapter is initialized.

Example

Nebulex.Cache is the wrapper around the cache. We can define the local and replicated cache as follows:

defmodule MyApp.ReplicatedCache do
  use Nebulex.Cache,
    otp_app: :my_app,
    adapter: Nebulex.Adapters.Replicated

  defmodule Primary do
    use Nebulex.Cache,
      otp_app: :my_app,
      adapter: Nebulex.Adapters.Local
  end
end

Where the configuration for the cache must be in your application environment, usually defined in your config/config.exs:

config :my_app, MyApp.ReplicatedCache.Primary,
  n_shards: 2,
  gc_interval: 3600

config :my_app, MyApp.ReplicatedCache,
  primary: MyApp.ReplicatedCache.Primary

For more information about the usage, check out Nebulex.Cache.

Extended API

This adapter provides some additional functions to the Nebulex.Cache API.

__primary__

Returns the local cache adapter (the local backend).

__task_sup__

Returns the task supervisor module that manages RPC calls.

__nodes__

Returns the nodes that belongs to the caller Cache.