View Source Redlock
This library is an implementation of Redlock (Redis destributed lock)
installation
Installation
If available in Hex, the package can be installed
by adding redlock
to your list of dependencies in mix.exs
:
def deps do
[
{:redlock, "~> 1.0.21"}
]
end
Documentation can be generated with ExDoc and published on HexDocs. Once published, the docs can be found at https://hexdocs.pm/redlock.
usage
Usage
resource = "example_key:#{user_id}"
lock_exp_sec = 10
case Redlock.lock(resource, lock_exp_sec) do
{:ok, mutex} ->
# some other code which write and read on RDBMS, KVS or other storage
# call unlock finally
Redlock.unlock(resource, mutex)
:error ->
Logger.error "failed to lock resource. maybe redis connection got trouble."
{:error, :system_error}
end
Or you can use transaction
function
def my_function() do
# do something, and return {:ok, :my_result} or {:error, :my_error}
end
def execute_with_lock() do
resource = "example_key:#{user_id}"
lock_exp_sec = 10
case Redlock.transaction(resource, lock_exp_sec, &my_function/0) do
{:ok, :my_result} ->
Logger.info "this is the return-value of my_function/0"
:ok
{:error, :my_error} ->
Logger.info "this is the return-value of my_function/0"
:error
{:error, :lock_failure} ->
Logger.info "if locking has failed, Redlock returns this error"
:error
end
end
setup
Setup
children = [
# other workers/supervisors
{Redlock, [pool_size: 2, ...]}
]
Supervisor.start_link(children, strategy: :one_for_one)
options
Options
single-node-mode
Single Node Mode
readlock_opts = [
pool_size: 2,
drift_factor: 0.01,
max_retry: 3,
retry_interval_base: 300,
retry_interval_max: 3_000,
reconnection_interval_base: 500,
reconnection_interval_max: 5_000,
# you must set odd number of server
servers: [
[host: "redis1.example.com", port: 6379],
[host: "redis2.example.com", port: 6379],
[host: "redis3.example.com", port: 6379]
]
]
pool_size
: pool_size of number of connection pool for each Redis master node, default is 2drift_factor
: number used for calculating validity for results, see https://redis.io/topics/distlock for more detail.max_retry
: how many times you want to retry if you failed to lock resource.retry_interval_max
: (milliseconds) used to decide how long you want to wait untill your next try after a lock-failure.retry_interval_base
: (milliseconds) used to decide how long you want to wait untill your next try after a lock-failure.reconnection_interval_base
: (milliseconds) used to decide how long you want to wait until your next try after a redis-disconnectionreconnection_interval_max
: (milliseconds) used to decide how long you want to wait until your next try after a redis-disconnectionservers
: host, port and auth settings for each redis-server. this amount must be odd. Auth can be omitted if no authentication is reaquired
How long you want to wait until your next try after a redis-disconnection or lock-failure
the interval(milliseconds) is decided by following calculation.
min(XXX_interval_max, (XXX_interval_base * (attempts_count ** 2)))
cluster-mode
Cluster Mode
readlock_opts = [
pool_size: 2,
drift_factor: 0.01,
max_retry: 3,
retry_interval_base: 300,
retry_interval_max: 3_000,
reconnection_interval_base: 500,
reconnection_interval_max: 5_000,
cluster: [
# first node
[
# you must set odd number of server
[host: "redis1.example.com", port: 6379, auth: password],
[host: "redis2.example.com", port: 6379, auth: password],
[host: "redis3.example.com", port: 6379, auth: password]
],
# second node
[
# you must set odd number of server
[host: "redis4.example.com", port: 6379],
[host: "redis5.example.com", port: 6379],
[host: "redis6.example.com", port: 6379]
],
# third node
[
# you must set odd number of server
[host: "redis7.example.com", port: 6379],
[host: "redis8.example.com", port: 6379],
[host: "redis9.example.com", port: 6379]
]
]
]
Set cluster
option instead of servers
, then Redlock works as cluster mode.
When you want to lock some resource, Redlock chooses a node depends on a resource key with consistent-hashing way (ketama algorithm using md5).