• Stars
    star
    45
  • Rank 603,552 (Top 13 %)
  • Language
    Crystal
  • License
    MIT License
  • Created almost 8 years ago
  • Updated almost 4 years ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Redis Cluster Manager in Crystal

rcm.cr Build Status

Redis Cluster Manager

Features

  • manage: creates cluster easily and provides many commands
  • monitor: watches nodes periodically on cli
  • httpd: provides http api service to redis

Why not use redis-cli?

Why not use redis-trib.rb?

  • That has ugly syntax. (why SHA1?)
  • That doesn't support AUTH and manual F/O and ....
  • That depends ruby and redis-cli.
redis-trib rcm
Replicate redis-cli -p 7004 cluster replicate 34f256... rcm -p 7004 replicate :7001
Manual F/O N/A rcm -p 7004 failover; rcm -p 7001 failback
Create with AUTH N/A rcm -a XXX create ...
Migrate (slow : send N-times commands for N keys) (bulk : send like 10000 keys in 1 command )
Portability docker run ruby:2.3 ruby redis-trib ... rcm ...

If you don't mind these points at all, I recommend you to use redis-trib.

Installation

Static Binary is ready for x86_64 linux

Compile from source

  • tested on crystal-0.34.0
% make
% cp bin/rcm /usr/local/bin/

Usage (information features)

schema

  • show cluster schema about node dependencies
% rcm -p 7000 schema
[0-3276     ] 192.168.0.1:7001 192.168.0.2:7002 192.168.0.3:7003
[3277-6553  ] 192.168.0.2:7001 192.168.0.3:7002 192.168.0.4:7003
[6554-9830  ] 192.168.0.3:7001 192.168.0.4:7002 192.168.0.5:7003
[9831-13107 ] 192.168.0.4:7001 192.168.0.1:7003 192.168.0.5:7002
[13108-16383] 192.168.0.5:7001 192.168.0.1:7002 192.168.0.2:7003
  • It can be used as continuous test for node dependencies.
  • For example, we can easily alert failover or node down by crontab.
% rcm -p 7000 schema > /data/redis-cluster-7000.schema
*/5 * * * * diff /data/redis-cluster-7000.schema $(rcm -p 7000 schema)

status

  • summarize nodes status in the cluster
% rcm -p 7000 status
[0-3000     ] master(127.0.0.1:7012) with 2 slaves
[3001-6000  ] master(127.0.0.1:7001) with 1 slaves
[6001-9000  ] master(127.0.0.1:7002) with 1 slaves
[9001-12000 ] master(127.0.0.1:7003) with 1 slaves
[12001-16383] master(127.0.0.1:7004) with 1 slaves

% rcm -p 7000 status -v
[0-3000     ] M(127.0.0.1:7012) S(127.0.0.1:7000) S(127.0.0.1:7014)
[3001-6000  ] M(127.0.0.1:7001) S(127.0.0.1:7006) S(127.0.0.1:7008) S(127.0.0.1:7011)
[6001-9000  ] M(127.0.0.1:7002) S(127.0.0.1:7007)
[9001-12000 ] M(127.0.0.1:7003) S(127.0.0.1:7013)
[12001-16383] M(127.0.0.1:7004) S(127.0.0.1:7009)

nodes

  • provides human-friendly output rather than redis-cli
% rcm -p 7001 nodes
b98ca1 [127.0.0.1:7001](0)  [0-5000     ] master(*)
835bea [127.0.0.1:7004](0)    +slave(*) of 127.0.0.1:7001
8a3c07 [127.0.0.1:7002](0)  [5001-10000 ] master(*)
0d0c75 [127.0.0.1:7005](0)    +slave(*) of 127.0.0.1:7002
33d324 [127.0.0.1:7003](0)  [10001-16383] master(*)
4a4da6 [127.0.0.1:7006](0)    +slave(*) of 127.0.0.1:7003
2581a1 [127.0.0.1:7007](0)  standalone master(*)
[OK] All 16384 slots are covered by 3 masters and 3 slaves.
[OK] All slots are available with 2 replication factor(s).
  • NOTICE: This sends INFO keyspace to all nodes.

info

  • summarize INFO for each nodes
% rcm -p 7001 info
edb22e [127.0.0.1:7001]  ver(3.2.0), cnt(7633), mem(2.27M;noev;0%), days(0)
f0da61 [127.0.0.1:7002]  ver(3.2.0), cnt(8751), mem(2.61M;noev;0%), days(0)
  • arg can be used to select a specific line like grep arg INFO
% rcm -p 7001 info role,cnt,day
edb22e [127.0.0.1:7001]  role(master), cnt(7633), days(0)
f0da61 [127.0.0.1:7002]  role(master), cnt(8751), days(0)
  • reserved field names for easy access

    • v , ver , version : delegate to redis_version
    • m , mem , memory : summarize used_memory_human , maxmemory_policy and maxmemory_human
    • cnt, count : extract db0:keys=(\d+)
    • d, day : delegate to uptime_in_days
  • NOTICE: This sends INFO to all nodes.

slot : calculate keyslot values

% rcm slot foo
12182

% rcm slot foo bar -v
foo     12182
bar     5061

% rcm slot foo "{foo}.bar" -v
foo     12182
{foo}.bar       12182

Usage (cluster feature)

  • create : ADDSLOTS, MEET, REPLICATE
  • join : just MEET and wait all nodes to join the cluster
  • forget : remove the node from cluster

create : create cluster automatically

% rcm create 192.168.0.1:7001 192.168.0.2:7002 -n  # dryrun
% rcm create 192.168.0.1:7001 192.168.0.2:7002
% rcm create --masters 5 192.168.0.1:7001 192.168.0.2:7002 ...
  • master size can be set by "--masters NUM"
  • otherwise hosts count is used in default

join : create cluster autmatically without addslots and replicate

% rcm join 192.168.0.1:7001 192.168.0.2:7002 ...

create cluster manually

% rcm -p 7001 addslots -5000       # means 0-5000
% rcm -p 7002 addslots 5001-10000
% rcm -p 7003 addslots 10001-      # means 10001..16383

% rcm -p 7002 meet 127.0.0.1:7001
% rcm -p 7003 meet 127.0.0.1:7001

forget : send "CLUSTER FORGET" to all nodes except the given node

For example, assume that a node (port :7004) is broken where rcm nodes prints like this.

a830a2 [192.168.0.1:7003](177877)    +slave(*) of 192.168.0.1:7002
3008b0 [127.0.0.1:0]   (    -1)  standalone master,fail,noaddr(!)

Here, we want to remove the node that was running on port:7004 (sha1: 3008b0...).

% rcm -p 7003 forget 3008b0

Usage (replication features)

start replication

  • meet and replicate (ex. make :7004 slaveof :7001)
% rcm -p 7004 meet 127.0.0.1:7001       # same as "meet :7001" for localhost
% rcm -p 7004 replicate 127.0.0.1:7001  # same as "replicate :7001" for localhost

switch master and slave

native redis cluster protocol

  • failover (slave feature) : becomes master with agreement
  • takeover (slave feature) : becomes master without agreement

rcm methods for graceful failover

  • wait : wait for replication to finish
  • fail (master feature) : becomes slave and wait a new master is up (linked)
  • failback (slave feature) : becomes master and wait data sync is finished
% rcm -p 7001 fail      # 7001: master -> slave (now we can stop 7001 gracefully)
% rcm -p 7001 failover  # 7001: slave -> master (now we can stop slaves gracefully)
  • Sequentially applying fail and failover means NOP

advise

  • In biased replications, nodes and advise advise a command to fix it.
% rcm -p 7001 nodes
...
[OK] All slots are available with 2+ replication factor(s).
advise: This can provide better replication. (rf of '127.0.0.1:7017': 2 -> 3)
  rcm -h '127.0.0.1' -p 7011 REPLICATE 127.0.0.1:7017

% rcm -h '127.0.0.1' -p 7011 REPLICATE 127.0.0.1:7017
REPLICATE 127.0.0.1:7017
OK

% rcm -p 7001 nodes
...
[OK] All slots are available with 3 replication factor(s).
  • advise --yes is suit for batch.
# NOP when replication is well balanced
% rcm -p 7001 advise --yes

# `replicate` command is executed automatically when unblanaced
% rcm -p 7001 advise --yes
2016-06-23 21:21:49 +0900: BetterReplication: rf of '127.0.0.1:7016': 2 -> 3
rcm -h '127.0.0.1' -p 7012 REPLICATE 127.0.0.1:7016
REPLICATE 127.0.0.1:7016
OK

Usage (utility features)

watch (experimental)

  • provides continual monitoring using curses
  • ex) rcm -p 7001 watch
2016-06-27 09:54:36 +0900

[0-5000     ] 127.0.0.1:7001(5001) .........++..................
    +slave    127.0.0.1:7004(5001) .........++..................
[5001-10000 ] 127.0.0.1:7005(5000) ..........++.................
    +slave    127.0.0.1:7002(5000) ..........++.....EEEEEEE.....
[10001-16383] 127.0.0.1:7003(6384) ...........++................
    +slave    127.0.0.1:7006(6384) .......EEEEEEE.+.............
 ( no slots ) 127.0.0.1:7007(0)    .............................

import

  • (experimental) This is too slow deu to step import by one by
  • works with using SET
% rcm -p 7001 import foo.tsv

migrate

For example, we can migrate from host1:6379 with pass1 to new cluseter cluster-broker1:7001 by following command.

% rcm -u pass1@host1:6379 migrate --to cluster-broker1:7001 --replace

Usage (httpd : provides web interfaces)

  • provides REST API that accepts "/CMD/args1/arg2/..." for redis
% rcm -p 7001 httpd :3000
% curl 127.0.0.1:3000/SET/hello/world  # same as "SET hello world"
OK
% curl 127.0.0.1:3000/GET/hello        # same as "GET hello"
world

# When redis requires AUTH(xxx), httpd automatically provides basic auth with "redis:xxx".
% rcm -u xxx@:7001 httpd :3000
% curl -u redis:xxx 127.0.0.1:3000/INCR/cnt
1

# The username of basic auth can be overwriten by listen arg like 'admin@'.
% rcm -u xxx@:7001 httpd [email protected]:3000
% curl -u admin:xxx 127.0.0.1:3000/INCR/cnt
2
  • output format is one of "txt", "raw", "resp", "json"
% curl 127.0.0.1:3000/GET/hello.txt  # => "world\n"
% curl 127.0.0.1:3000/GET/hello.raw  # => world
% curl 127.0.0.1:3000/GET/hello.resp # => $5\r\nworld\r\n
% curl 127.0.0.1:3000/GET/hello.json # => {"get":"world"}

Usage (redis commands)

  • All other args will be passed to redis as is.
  • In this case, standard or clustered redis is automatically guessed.
(standard redis is running on 6379)
% rcm config get maxmemory
["maxmemory", "10000000"]

(clustered redis is running on 7001,7002,... with AUTH `dev`)
% rcm -u dev@:7002 config get maxmemory
["maxmemory", "10000000"]

Connecting to nodes

various ways to connect to nodes

  • -h <host>
  • -p <port>
  • -a <password>
  • -u <uri>
% rcm ...                 # "127.0.0.1:6379" (default)
% rcm -h 192.168.0.1 ...  # "192.168.0.1:6379"
% rcm -p 7001 ...         # "127.0.0.1:7001"
% rcm -p 7001 -a xyz ...  # "127.0.0.1:7001" with AUTH "xyz"
% rcm -u redis://foo ...  # "foo:6379" (strict uri form)
% rcm -u foo ...          # "foo:6379" (scheme is optional)
% rcm -u :7001 ...        # "127.0.0.1:7001"
% rcm -u foo:7001 ...     # "foo:7001"
% rcm -u xyz@foo:7001 ... # "foo:7001" with AUTH "xyz"
% rcm -u xyz@foo:7001 ... # "foo:7001" with AUTH "xyz"
% rcm -u xyz@ ...         # "127.0.0.1:6379" with AUTH "xyz"
% rcm -u xyz@:7001 ...    # "127.0.0.1:7001" with AUTH "xyz"
% rcm -u xyz@foo ...      # "foo:6379" with AUTH "xyz"

Usage (as a replace of redis-cli)

  • --raw option is available.
% rcm --raw get foo > foo.bin

Usage (as a crystal library)

see examples/*.cr

But, you'd better use redis-cluster.cr rather than this for library.

TODO

  • Dryrun
  • Check
    • Nodes health check
    • Slots coverage check
    • detect orphaned master
    • detect orphaned slave
  • Schema
    • Dump cluster schema
    • Reset node dependencies by schema file
  • Advise
    • Rebalance nodes
    • Rebalance slots
  • Utils
    • Create cluster
    • Rebalance nodes
    • Rebalance slots
    • Bulkinsert on import
    • Watch monitoring
    • Graceful failover
  • Web UI
    • Command Api
    • Cluster Info
  • Debug
    • Scan slots

Development

  • for ubuntu
apt-get install libncursesw5-dev
apt-get install libgpm-dev        # needs only for static link

Contributing

  1. Fork it ( https://github.com/maiha/rcm.cr/fork )
  2. Create your feature branch (git checkout -b my-new-feature)
  3. Commit your changes (git commit -am 'Add some feature')
  4. Push to the branch (git push origin my-new-feature)
  5. Create a new Pull Request

Contributors

  • maiha maiha - creator, maintainer

More Repositories

1

kafka.cr

kafka utilities written in crystal
Crystal
34
star
2

rocksdb.cr

RocksDB client for Crystal
Crystal
34
star
3

crystal-examples

This has been completely rewritten in 2019. The old implementation has moved to the alpha branch.
Crystal
31
star
4

crt.cr

Bindings for libncursesw and crt class
Crystal
28
star
5

try.cr

Try monad for crystal
Crystal
26
star
6

pcap.cr

Crystal bindings for libpcap
Crystal
24
star
7

crb

A cucumber console that offers cucumber world enviroment on irb
Ruby
20
star
8

xq.cr

Command-line XML processor inspired by `jq`
Crystal
17
star
9

redis-cluster-benchmark.cr

Benchmark utils for Redis Cluster
Crystal
16
star
10

pretty.cr

Something attentive, conservative and pretty stuff for Crystal
Crystal
16
star
11

jq.cr

thin JSON::Any wrapper to emulate jq for crystal
Crystal
16
star
12

must

a runtime specification tool
Ruby
15
star
13

grafana-redis.cr

Grefana Datasource for Redis storage
Crystal
15
star
14

gatling-amqp

Gatling AMQP support
Scala
15
star
15

typed

A Ruby library for Typed variables
Ruby
14
star
16

redis-cluster.cr

redis-cluster library for Crystal
Crystal
13
star
17

htpasswd

ActionPack plugin for authorizing users with HTTP basic/digest authentications
Ruby
12
star
18

memoized.cr

Time-based memoized library for Crystal
Crystal
11
star
19

tokyocabinet

unofficial repository for TokyoCabinet
C
11
star
20

pg-copy-ch

Simply copy the current PostgreSQL data to ClickHouse
Crystal
10
star
21

clickhouse-cluster-examples

Examples of the cluster topologies in ClickHouse
Makefile
10
star
22

facebook.cr

CLI for the Facebook Marketing API.
Crystal
9
star
23

ircbot

old fashioned irc bot
Ruby
9
star
24

rrr

Ruby programming with RR
Ruby
9
star
25

mod_cband

mod_cband Apache2 module
C
8
star
26

dsl_accessor

Ruby
8
star
27

ccp

A Ruby library for Composite Command Programming
Ruby
7
star
28

hq.cr

a simple wrapper for crystal-xml
Crystal
7
star
29

sexy_auto_complete

Rails plugin for better auto_complete, especially it gets along with ActiveScaffold nested forms
Ruby
7
star
30

comment-spec.cr

Comment driven spec builder for Crystal
Crystal
6
star
31

shard.cr

compile-time shard.yml reader for Crystal
Crystal
6
star
32

http-gate

Quite simple http port forwarder
Crystal
6
star
33

auto_nested_layouts

Use multiple nested layout files in Rails
Ruby
6
star
34

curl.cr

high level curl library for crystal
Crystal
6
star
35

open-uri-mapping

a wrapper to open-uri that offers filename mapping, which is useful for test
Ruby
5
star
36

mjs

A Ruby library that offers quite easy-to-use Ajax actions like RJS with jQuery
Ruby
5
star
37

css_parser

hpricot helper that scrapes html easily by parser class defined css selector
Ruby
5
star
38

protobuf-storage.cr

A handy local storage library for Protobuf
Crystal
5
star
39

rows_logger

ActiveRecord plugin for writing rows count information in query log
Ruby
5
star
40

cuke-utils

Goodies for cuke
Ruby
5
star
41

chawan

A cup for chasen that provides an easy to use for extracting Japanese
Ruby
5
star
42

rails_log

Rails log analyzer application with Ext-JS
Ruby
5
star
43

redis-tsv.cr

import and export data from Redis in TSV format
Crystal
5
star
44

request_id

Rails plugin that adds a new method (Controller#request_id) to distinguish requests
Ruby
4
star
45

ext

ActionPack plugin for using Ext-JS
Ruby
4
star
46

tdiary_google_calendar_plugin

A tdiary plugin that shows event list from google calendar
Ruby
4
star
47

unicode_japanese

Japanese charset converter especially for hankaku and zenkaku characters
Ruby
4
star
48

selenium-chrome.cr

A handy and thin wrapper for `selenium-webdriver-crystal`
Crystal
4
star
49

kafka-utils

Simple Kafka Utils in Scala
Scala
4
star
50

clickhouse.cr

ClickHouse client for Crystal
Crystal
4
star
51

mvc-benchmark-2010

A sample applications to bench MVC frameworks
4
star
52

merb_inspector

no needs to prepare views, scaffold and pagination. just inspect it
Ruby
4
star
53

scoped_access

restrict database access by using with_scope
Ruby
4
star
54

pon.cr

Maiha's private ORM for Crystal
Crystal
4
star
55

tokyotyrant

unofficial repository for TokyoTyrant
4
star
56

ohm-arfreaks

Ohm::Model extensions for AR freaks
Ruby
3
star
57

night-time

A ruby gem that treats over-midnight time easily
Ruby
3
star
58

sexy_actions

defining actions by block
Ruby
3
star
59

hash-path

path accessor to hierarchical hash
Ruby
3
star
60

http-mock

Real http server for stubbing and expectations in Scala
Scala
3
star
61

innodb-cluster-docker

a helper for running InnoDB Cluster on docker
Shell
3
star
62

named_options

Ruby
3
star
63

merb_background

a merb slice for background-fu
Ruby
3
star
64

2ch

local image storage application for 2ch
JavaScript
3
star
65

rack_format_response

A Rack middleware for automatically formatting response body
Ruby
3
star
66

opts.cr

a wrapper for OptionParser to provide default values and handy args
Crystal
3
star
67

acts_with_comma

Rails plugin that accepts numeric value with comma in AR#setter and text_field
Ruby
3
star
68

var.cr

`Object.var` macro for Crystal
Crystal
3
star
69

merb_rjs

Merb plugin that enables you to use 'page' object in your controllers like RJS of Rails
3
star
70

redisniffer

Sniff redis packets and summarize count of commands
Crystal
3
star
71

genspec

A Rails utils that automatically generates a rspec file for the latest action written in a log file
3
star
72

dm-ys

a DataMapper extension that uses html table as its schema and data powerfully like YunkerStar
Ruby
3
star
73

twitter-ads.cr

Twitter Ads API SDK for Crystal
Crystal
2
star
74

crystal-init.sh

a simple wrapper for crystal init command
Shell
2
star
75

crc16.cr

crc16 for Crystal
Crystal
2
star
76

james-bond

James is a bond framework for web development
Ruby
2
star
77

yak-farm

A farm view for Yak
2
star
78

lmdb.cr

Lmdb client for Crystal
Crystal
2
star
79

scalerity

Scalerity = Scala + Celerity
Scala
2
star
80

record_dumper

ActiveRecord plugin for printing record value to various formats
Ruby
2
star
81

hosts_access

Rails/Merb plugin that controls host access like hosts.allow
Ruby
2
star
82

web_api

Basic classes for general Web API
Ruby
2
star
83

toml-config.cr

TOML::Config class for handy use of crystal-toml
Crystal
2
star
84

tokyocabinet.cr

TokyoCabinet client for Crystal
Crystal
2
star
85

clickhouse-table

A standalone ClickHouse table manager that provides partial data updates
Crystal
2
star
86

optionize

method arguments utils
2
star
87

cmds.cr

Yet another CLI Builder library for Crystal
Crystal
2
star
88

base32.cr

Base32 Encoding for Crockford's Base32
Crystal
2
star
89

edd

Error driven development plugin for Rails
2
star
90

wildcard

A ruby library to expand wildcard string like shell command line
2
star
91

active_record_view

Ruby
2
star
92

active_seven

ActiveRecord plugin for 7th normal form
Ruby
2
star
93

include_for

Ruby
2
star
94

sandboxed_methods

Avoid conflicting method and variable names between modules
Ruby
2
star
95

akka-watch-child

study: to know whether a parent actor will watch its child automatically or not.
Scala
2
star
96

neo4j

Neo4j manager that provides many commands such as load,dump,touch,inspect,list
2
star
97

migration2

Yet another migartion library for ActiveRecord
Ruby
2
star
98

habto

ActiveRecord plugin for habtm utils
Ruby
2
star
99

active-scaffold.cr

ActiveScaffold for Amber on Crystal
CSS
2
star
100

traildb.cr

TrailDB bindings for Crystal
Crystal
1
star