redis-cluster
Description
redis-cluster is redis cluster client for ruby that support pipelining.
Owner
SRE Bukalapak
Contact
Contributors
Onboarding and Development Guide
Getting started
-
Install redis-cluster
gem install 'redis-cluster'
-
Start irb
. This command will start a redis-cluster client from seed servers.
seed = ['127.0.0.1:7001', '127.0.0.1:7002']
redis = RedisCluster.new(
seed,
redis_opts: { timeout: 5, connect_timeout: 1 },
cluster_opts: { force_cluster: false, read_mode: :master_slave, silent: true, logger: Logger.new }
)
redis.middlewares.register(:commit) do |*args, &block|
puts "this is RedisCluster middlewares"
block.call
end
Development Guide
-
You need rvm and bundler to test.
See here to install rvm
.
And run these commands to install bundler
and other dependencies
gem install bundler
bundle install
-
You also need redis binary.
See here to install redis
-
Fork this repo
-
Make your change and it's test.
vim lib/**.rb
vim spec/**_spec.rb
-
Optionally, run the test in your local
rake
-
Commit and push your change to upstream
git commit -m "message"
git push
-
Open pull request in Github
-
If test in CI is success, ask someone to review your code.
-
If review is passed, your pull request can be merged.
Configuration
redis_opts
Option for Redis::Client instance. Set timeout, ssl, etc here.
cluster_opts
Option for RedisCluster.
force_cluster
: if true, RedisCluster will only work on clustered Redis or otherwise can also work on standalone Redis. The default value is false
.read_mode
: for read command, RedisClient can try to read from slave if specified. Supported option is :master
(default), :slave
, and :master_slave
.silent
: whether or not RedisCluster will raise error.logger
: if specified. RedisCluster will log all of RedisCluster errors here.reset_interval
: reset threshold. A reset can only happen once per reset_interval.circuit_threshold
: Threshold how many error that client will considered an unhealthy.circuit_interval
: How long failed count will be remembered.
Middlewares
Middlewares are hooks that RedisCluster provide to observe RedisCluster events. To register a middlewares, provide callable object (object that respond to call)
or give block in register method. Middlewares must give block result as return value.
class Callable
def call
start = Time.now
yield
rescue StandardError => e
raise e
ensure
Metrics.publish(elapsed_time: Time.now - start)
end
end
redis.middlewares.register(:commit, Callable.new)
redis.middlewares.register(:commit) do |*args, &block|
begin
res = block.call
rescue StandardError => e
Log.warn('failed')
raise e
end
Log.info('success')
res
end
Currently there are 3 events that RedisCluster publish.
:commit
RedisCluster will fire :commit
events when RedisCluster::Client call redis server. It give RedisCluster::Client
as arguments.
redis.middlewares.register(:commit) do |client, &block|
puts 'this is :commit events'
puts "client url: #{client.url}"
puts "first command: #{client.queue.first.first}"
puts "last command: #{client.queue.last.first}"
block.call
end
:call
This events is fired when command is issued in RedisCluster client before any load balancing is done. It give RedisCluster
and RedisCluster#call
arguments as arguments
redis.middlewares.register(:call) do |client, keys, command, opts = {}, &block|
puts "keys to load balance: #{keys}"
puts "redis command: #{command.first}"
puts "in pipelined?: #{client.pipelined?}"
block.call
end
redis.get('something')
:pipelined
This events is fired when pipelined method is called from redis client. It does give RedisCluster
as arguments
redis.middlewares.register(:pipelined) do |client, &block|
puts 'pipelined is called'
block.call
end
Limitation
All multi keys operation, cluster command, multi-exec, and some commands are not supported.
Pipeline
Can be used with same interface as standalone redis client. See redis pipeline
FAQ