redis-cluster is redis cluster client for ruby that support pipelining.
SRE Bukalapak
-
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
-
You need rvm and bundler to test. See here to install
rvm
. And run these commands to installbundler
and other dependenciesgem 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 # run all test and lint
-
Commit and push your change to upstream
git commit -m "message" git push # add "--set-upstream branch_name" after "git push" if you haven't set the upstream
-
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.
Option for Redis::Client instance. Set timeout, ssl, etc here.
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 isfalse
.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 in second. 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 in second.
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.
# Using callable
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)
# Using proc
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 giveRedisCluster::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 giveRedisCluster
andRedisCluster#call
arguments as argumentsredis.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') # Output: # keys to load balance: something # redis command: get
:pipelined
This events is fired when pipelined method is called from redis client. It does giveRedisCluster
as argumentsredis.middlewares.register(:pipelined) do |client, &block| puts 'pipelined is called' block.call end
All multi keys operation, cluster command, multi-exec, and some commands are not supported.
Can be used with same interface as standalone redis client. See redis pipeline