class
Redis::Cluster
- Redis::Cluster
- Reference
- Object
Overview
Use in place of a Redis::Client when talking to Redis clusters. This class
will discover all nodes in a Redis cluster when given a URI for any of them,
route commands to appropriate shards based on the keys they operate on, and
route commands which do not change state to shard replicas to spread the
load across the cluster.
As nodes are added or removed, replicas are promoted, or hash slots migrate
between shards, the cluster client will adapt to the new topology
automatically. Commands that receive a MOVED redirection are retried
against the new node, and topology is re-discovered in the background so
subsequent commands route correctly without requiring another redirection.
Commands that receive an ASK redirection (slot mid-migration) are retried
against the importing node with an ASKING prefix.
It's important that, when using commands which operate on multiple keys (for
example: MGET, DEL, RPOPLPUSH, etc) that all specified keys reside
on the same shard in the cluster. Usually, this means designing your key
names with curly braces around parts of them to ensure they hash to the same
key slot. For example:
redis.del "{comment}:1", "{comment}:2"
value = redis.rpoplpush "{queue}:default", "{queue}:default:pending"
If you want to use a Redis module that provides custom commands, you can
register them as read-only with Redis::Cluster.register_read_only_commands
and they will automatically be routed to replicas. See
redis/cluster/json.cr
for example usage.
Included Modules
Defined in:
cluster.crerrors.cr
Constructors
-
.new(uri : URI = URI.parse(ENV["REDIS_CLUSTER_URL"]? || "redis:///"), topology_refresh_throttle : Time::Span = 1.second)
Pass a
URI(defaulting to theREDIS_CLUSTER_URLenvironment variable) to connect to the specified Redis cluster — the URI can point to any server in the cluster andRedis::Clusterwill discover the rest.
Class Method Summary
-
.register_read_only_command(command : String)
Tell the cluster driver that the specified Redis command can be routed to read-only replicas.
-
.register_read_only_commands(commands : Enumerable(String))
Tell the cluster driver that all the specified Redis commands can be routed to read-only replicas.
Instance Method Summary
-
#close
Close all connections to this Redis cluster
-
#flushdb
Executes
#flushdbon each shard in the cluster. -
#keys : Array(String)
Get all key across all shards.
-
#pipeline(key : String, &)
Run a pipeline for the specified key
-
#psubscribe(*patterns : String, &)
Subscribe to one or more pubsub channel patterns.
-
#refresh_topology(force : Bool = true) : Nil
Force a refresh of the cluster's topology.
-
#run(command full_command)
Execute the given command and return the result from the server.
-
#scan_each(*args, **kwargs, &) : Nil
Execute
Commands#scan_eachon each shard, yielding any matching keys. -
#slot_for(key : String)
Return the Redis hash slot for the given key.
-
#spublish(channel : String, message : String)
Publish a message to a sharded pubsub channel.
-
#ssubscribe(*channels : String, &)
Subscribe to one or more sharded pubsub channels.
-
#subscribe(*channels : String, &)
Subscribe to one or more pubsub channels.
-
#sunsubscribe(*channels : String)
Unsubscribe from sharded pubsub channels on the shard that owns their hash slot.
Instance methods inherited from module Redis::Commands::Immediate
cms
cms,
get!(key : String) : String
get!,
info
info,
topk
topk
Instance methods inherited from module Redis::Commands
bf
bf,
cms
cms,
dbsize
dbsize,
decr(key : String)
decr,
decrby(key : String, amount : Int | String)
decrby,
del(keys : Enumerable(String))del(*keys : String) del, dump(key : String) dump, eval(script : String, keys : Enumerable(String) = EmptyEnumerable.new, args : Enumerable(String) = EmptyEnumerable.new) eval, eval_ro(script : String, keys : Enumerable(String) = EmptyEnumerable.new, args : Enumerable(String) = EmptyEnumerable.new) eval_ro, evalsha(sha : String, keys : Enumerable(String) = EmptyEnumerable.new, args : Enumerable(String) = EmptyEnumerable.new) evalsha, evalsha_ro(sha : String, keys : Enumerable(String) = EmptyEnumerable.new, args : Enumerable(String) = EmptyEnumerable.new) evalsha_ro, exists(keys : Enumerable(String))
exists(*keys : String) exists, expire(key : String, ttl : Time::Span)
expire(key : String, ttl : Int) expire, expireat(key : String, at : Time) expireat, flushall flushall, flushdb flushdb, ft ft, get(key : String) get, getdel(key : String) getdel, incr(key : String) incr, incrby(key : String, amount : Int | String) incrby, incrbyfloat(key : String, amount : Float | String) incrbyfloat, info(section : String) info, json json, keys(pattern = "*") keys, mget(keys : Enumerable(String))
mget(*keys : String) mget, mset(data : ::Hash(String, String)) mset, pexpire(key : String, ttl : Time::Span)
pexpire(key : String, ttl : Int) pexpire, pexpireat(key : String, at : Time) pexpireat, ping(message : String | Nil = nil) ping, pttl(key : String) pttl, publish(channel : String, message : String) publish, run(command) run, scan(cursor : String = "0", match : String | Nil = nil, count : String | Int | Nil = nil, type : String | Nil = nil) scan, script_exists(shas : Enumerable(String))
script_exists(*shas : String) script_exists, script_flush(mode : ScriptFlushMode)
script_flush script_flush, script_kill script_kill, script_load(script : String) script_load, set(key, value, *, ex : Time, nx = false, xx = false, keepttl = false, get = false)
set(key, value, *, ex : Time::Span, nx = false, xx = false, keepttl = false, get = false)
set(key : String, value : String | Bytes, *, ex : String | Int | Nil = nil, px : String | Int | Nil = nil, nx = false, xx = false, keepttl = false, get = false) set, strlen(key : String) strlen, tdigest tdigest, ts ts, ttl(key : String) ttl, type(key : String) type, unlink(keys : Enumerable(String))
unlink(*keys : String) unlink, wait(numreplicas replica_count : Int | String, timeout : Time::Span)
wait(numreplicas replica_count : Int | String, timeout : Int | String) wait
Instance methods inherited from module Redis::Commands::Vector
vadd(key : String, vector : Enumerable(Float32), element : String, *, reduce : Int | String | Nil = nil, setattr attributes = nil)
vadd,
vcard(key : String)
vcard,
vdim(key : String)
vdim,
vemb(key : String, element : String)
vemb,
vgetattr(key : String, element : String, as type : T.class) : T | Nil forall Tvgetattr(key : String, element : String) vgetattr, vinfo(key : String) vinfo, vrange(key : String, start : String, end stop : String, count : Int | String | Nil = nil) vrange, vsim(key : String, element : String, *, epsilon : Float | String | Nil = nil, withscores : Bool = false, count : Int | String | Nil = nil)
vsim(key : String, vector : Array(Float32), *, epsilon : Float | String | Nil = nil, withscores : Bool = false, count : Int | String | Nil = nil) vsim
Instance methods inherited from module Redis::Commands::HyperLogLog
pfadd(key : String, values : Enumerable(String))pfadd(key : String, *values : String) pfadd, pfcount(keys : Enumerable(String))
pfcount(*keys : String) pfcount, pfmerge(destination_key target : String, source_keys sources : Enumerable(String))
pfmerge(destination_key target : String, *source_keys : String) pfmerge
Instance methods inherited from module Redis::Commands::Geo
geoadd(key : String, entries : Enumerable(Redis::Geo::Member), nx = nil, xx = nil, ch = nil)geoadd(key : String, *entries : String, nx = nil, xx = nil, ch = nil) geoadd, geodist(key : String, member1 : String, member2 : String, unit : Redis::Geo::Unit | Nil = nil) geodist, geopos(key : String, members : Enumerable(String))
geopos(key : String, *members : String) geopos, geosearch(key : String, *, fromlonlat lonlat : Tuple(String, String), byradius radius : Redis::Geo::Radius, sort : Redis::Geo::Sort | Nil = nil, count : Int | String | Nil = nil, withcoord : Bool = false, withdist : Bool = false)
geosearch(key : String, *, fromlonlat lonlat : Tuple(String, String), bybox box : Redis::Geo::Box, sort : Redis::Geo::Sort | Nil = nil, count : Int | String | Nil = nil, withcoord : Bool = false, withdist : Bool = false)
geosearch(key : String, *, frommember member : String, byradius radius : Redis::Geo::Radius, sort : Redis::Geo::Sort | Nil = nil, count : Int | String | Nil = nil, withcoord : Bool = false, withdist : Bool = false)
geosearch(key : String, *, frommember member : String, bybox box : Redis::Geo::Box, sort : Redis::Geo::Sort | Nil = nil, count : Int | String | Nil = nil, withcoord : Bool = false, withdist : Bool = false) geosearch
Instance methods inherited from module Redis::Commands::Stream
xack(key : String, group : String, id : String)xack(key : String, group : String, ids : Enumerable(String)) xack, xackdel(key : String, group : String, delete_mode : DeleteMode | Nil, ids : Enumerable(String))
xackdel(key : String, group : String, ids : Enumerable(String)) xackdel, xadd(key : String, id : String, fields : NamedTuple | ::Hash(String, String), *, idmpauto : String | Nil = nil, idmp : Tuple(String, String) | Nil = nil)
xadd(key : String, id : String, *, maxlen, fields : NamedTuple | ::Hash(String, String), idmpauto : String | Nil = nil, idmp : Tuple(String, String) | Nil = nil)
xadd(key : String, id : String, *, minid, fields : NamedTuple | ::Hash(String, String), idmpauto : String | Nil = nil, idmp : Tuple(String, String) | Nil = nil)
xadd(key : String, id : String, **fields : String)
xadd(key : String, id : String, *, maxlen, **fields : String)
xadd(key : String, id : String, *, minid, **fields : String) xadd, xautoclaim(key : String, group : String, consumer : String, min_idle_time : Time::Span, start : String, count : Int32 | String | Nil = nil) xautoclaim, xdel(key : String, ids : Enumerable(String))
xdel(key : String, *ids : String) xdel, xgroup(command : String, key : String, groupname : String)
xgroup(command : XGroup, key : String, groupname : String, *, id : String | Nil = nil, mkstream = false, consumer_name : String | Nil = nil)
xgroup(command : String, key : String, groupname : String, *args : String) xgroup, xgroup_create(key : String, groupname : String, *, id : String = "$", mkstream = false) xgroup_create, xgroup_create_consumer(key : String, groupname : String, consumer_name : String) xgroup_create_consumer, xgroup_del_consumer(key : String, group : String, consumer : String) xgroup_del_consumer, xgroup_destroy(key : String, group : String) xgroup_destroy, xinfo_consumers(key : String, group : String) xinfo_consumers, xinfo_groups(key : String) xinfo_groups, xinfo_stream(key : String) xinfo_stream, xinfo_stream_full(key : String, *, count : Int | String | Nil = nil) xinfo_stream_full, xlen(key : String) xlen, xnack(key : String, group : String, mode : NackMode, ids : Enumerable(String)) xnack, xpending(key : String, group : String, start : String, end finish : String, count : String | Int32, idle : String | Time::Span | Nil = nil)
xpending(key : String, group : String) xpending, xrange(key : String, start min : String, end max : String, count : String | Int32 | Nil = nil) xrange, xread(*, count : Int | String | Nil = nil, block : Time::Span | Int | String | Nil = nil, streams : NamedTuple)
xread(*, count : Int | String | Nil = nil, block : Time::Span | Int | String | Nil = nil, streams : ::Hash(String, String)) xread, xreadgroup(group : String, consumer : String, count : String | Int32 | Nil = nil, block : Time::Span | String | Int32 | Nil = nil, claim : Time::Span | String | Int32 | Nil = nil, no_ack = false, streams : ::Hash(String, String) = {} of String => String)
xreadgroup(group : String, consumer : String, count : String | Int32 | Nil = nil, block : Time::Span | String | Int32 | Nil = nil, claim : Time::Span | String | Int32 | Nil = nil, no_ack = false, streams : NamedTuple = NamedTuple.new) xreadgroup, xrevrange(key : String, end max : String, start min : String, count : String | Int32 | Nil = nil) xrevrange, xtrim(key : String, *, maxlen : Tuple(String, String), limit : String | Int32 | Nil = nil, delete_mode : DeleteMode | Nil = nil)
xtrim(key : String, *, minid : Tuple(String, String), limit : String | Int32 | Nil = nil, delete_mode : DeleteMode | Nil = nil) xtrim
Instance methods inherited from module Redis::Commands::SortedSet
zadd(key : String, score : String | Int64 | Float64, value : String, *, nx = false, xx = false, gt = false, lt = false, ch = false, incr = false)zadd(key : String, values : Enumerable(String), *, nx = false, xx = false, gt = false, lt = false, ch = false, incr = false)
zadd(key : String, *values : String, nx = false, xx = false, gt = false, lt = false, ch = false) zadd, zcard(key : String) zcard, zcount(key : String, min : String, max : String) zcount, zrange(key : String, start : String | Int64, stop : String | Int64, by order : ZRangeOrder | Nil = nil, rev : Bool | Nil = nil, limit : Tuple(String | Int, String | Int) | Nil = nil, with_scores : Bool = false) zrange, zrangebyscore(key : String, min : String | Float64, max : String | Float64, with_scores = false, limit : Enumerable(String) | Nil = nil) zrangebyscore, zrem(key : String, value : String)
zrem(key : String, values : Enumerable(String))
zrem(key : String, *values : String) zrem, zremrangebylex(key : String, min : String, max : String)
zremrangebylex(key : String, range : Range) zremrangebylex, zremrangebyrank(key : String, start : Int64 | String, stop : Int64 | String)
zremrangebyrank(key : String, range : Range) zremrangebyrank, zremrangebyscore(key : String, min : String | Float64, max : String | Float64)
zremrangebyscore(key : String, range : Range) zremrangebyscore, zrevrange(key : String, starting : String | Int64, ending : String | Int64, with_scores : Bool = false) zrevrange, zscan(key : String, cursor : String, match pattern : String | Nil = nil, count : String | Nil = nil) zscan, zscore(key : String, value : String) zscore
Instance methods inherited from module Redis::Commands::Set
sadd(key : String, values : Enumerable(String))sadd(key : String, *values : String) sadd, scard(key : String) scard, sdiff(first : String, second : String) sdiff, sinter(keys : Enumerable(String))
sinter(first : String, *others : String) sinter, sismember(key : String, value : String) sismember, smembers(key : String) smembers, srem(key : String, members : Enumerable(String))
srem(key : String, *values : String) srem, sscan(key : String, cursor : String, match pattern : String | Nil = nil, count : String | Nil = nil) sscan
Instance methods inherited from module Redis::Commands::List
blpop(keys : Enumerable(String), timeout : Time::Span)blpop(*keys : String, timeout : Time::Span)
blpop(*keys : String, timeout : Int | Float)
blpop(*keys : String, timeout : String) blpop, brpop(keys : Enumerable(String), timeout : Int)
brpop(*keys : String, timeout : Time::Span)
brpop(*keys : String, timeout : Number)
brpop(*keys : String, timeout : String) brpop, brpoplpush(source : String, destination : String, timeout : Time::Span)
brpoplpush(source : String, destination : String, timeout : Int | String) brpoplpush, llen(key : String) llen, lmove(from source : String, to destination : String, from_side source_side : Side, to_side destination_side : Side) lmove, lpop(key : String, count : String | Nil = nil) lpop, lpush(key : String, values : Enumerable(String))
lpush(key, *values : String) lpush, lrange(key : String, start : String | Int, finish : String | Int) lrange, lrem(key : String, count : Int, value : String) lrem, ltrim(key : String, start : String | Int, stop : String | Int)
ltrim(key : String, range : Range(String, String))
ltrim(key : String, range : Range(Int32, Int32)) ltrim, rpop(key : String) rpop, rpoplpush(source : String, destination : String) rpoplpush, rpush(key : String, values : Enumerable(String))
rpush(key, *values : String) rpush
Instance methods inherited from module Redis::Commands::Hash
hdel(key : String, fields : Enumerable(String))hdel(key : String, *fields : String) hdel, hget(key : String, field : String) hget, hgetall(key : String) hgetall, hincrby(key : String, field : String, increment : Int | String) hincrby, hmget(key : String, fields : Enumerable(String))
hmget(key : String, *fields : String) hmget, hmset(key : String, data : ::Hash(String, String)) hmset, hscan(key : String, cursor : String, *, match pattern : String | Nil = nil, count : String | Int | Nil = nil) hscan, hset(key : String, fields : Enumerable(String))
hset(key : String, fields : ::Hash(String, String))
hset(key : String, *fields : String)
hset(key : String, **fields : String) hset, hsetnx(key : String, field : String, value : String) hsetnx
Constructor Detail
Pass a URI (defaulting to the REDIS_CLUSTER_URL environment variable)
to connect to the specified Redis cluster — the URI can point to any
server in the cluster and Redis::Cluster will discover the rest.
topology_refresh_throttle controls the minimum interval between
automatic background topology refreshes. When MOVED redirections come
in faster than this interval, refreshes are coalesced.
Class Method Detail
Tell the cluster driver that the specified Redis command can be routed to read-only replicas.
Redis::Cluster.register_read_only_command "mymodule.get"
Tell the cluster driver that all the specified Redis commands can be routed to read-only replicas.
Redis::Cluster.register_read_only_commands %w[
mymodule.get
mymodule.mget
]
Instance Method Detail
Get all key across all shards. This executes a #keys command on every
shard in the cluster. Probably not a good idea in production since this
will block every Redis shard or replica for the duration of the query, but
we're supporting it because you may have a reasonable use case for it at
some point and it's just not easy to do otherwise.
Run a pipeline for the specified key
cluster.pipeline "{widgets}" do |pipe|
widget_ids.each do |id|
pipe.get "{widgets}:#{id}"
end
end
WARNING All keys that this pipeline operates on MUST reside on the same
shard. It's best to pass a pre-hashed key (one containing {}) to this
method. See the example above.
Subscribe to one or more pubsub channel patterns. Like #subscribe,
messages are propagated across the cluster.
Force a refresh of the cluster's topology. This is normally done
automatically in response to MOVED redirections, but it can be useful
to call this method explicitly when an external process tells you that
the cluster has changed.
Execute the given command and return the result from the server. Commands
must be an Enumerable and its size method must be re-entrant.
run({"set", "foo", "bar"})
Execute Commands#scan_each on each shard, yielding any matching keys.
Return the Redis hash slot for the given key. This is useful for seeing which shard your command will be routed to.
Publish a message to a sharded pubsub channel. The message is delivered
only to subscribers on the shard that owns the channel's hash slot —
unlike publish, it is not propagated across the cluster.
Subscribe to one or more sharded pubsub channels. All channels must hash
to the same slot (use {} to force co-location). The block yields a
Subscription and the underlying Connection, which holds the
subscription for its duration.
cluster.ssubscribe "orders" do |subscription, connection|
subscription.on_message do |channel, message|
# ...
end
end
Subscribe to one or more pubsub channels. Regular (non-sharded) pub/sub messages are propagated across the cluster, so the subscriber will receive messages regardless of which node a publisher targets.
Unsubscribe from sharded pubsub channels on the shard that owns their
hash slot. Typically called from inside an #ssubscribe block via the
yielded Connection; calling this on the cluster directly routes a
standalone SUNSUBSCRIBE to the shard and has no effect on a
subscription held by a different connection.