redis-cluster
Description
redis-cluster is redis cluster client for ruby that support pipelining.
Owner
SRE Bukalapak
Contact
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 installbundler
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 # 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.
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 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.
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.
# 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.ruby 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 argumentsruby 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') # 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 argumentsruby 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