A light-weight Redis client for Crystal.
MiniRedis is a light-weight low-level alternative to existing Redis client implementations.
In comparison with crystal-redis, MiniRedis has lesser memory consumption, built-in logging and first-class support for raw bytes. It also doesn't need to be updated with every Redis release.
On the other hand, MiniRedis doesn't have commands API (i.e. instead of
redis.ping you should write
redis.send("PING")). However, such a low-level interface terminates the dependency on the third-party client maintainer (i.e. me), which makes it a perfect fit to use within a shard.
You can always find the actual Redis commands API at https://redis.io/commands.
Benchmarks code can be found at https://github.com/vladfaust/mini_redis-benchmarks. These are recent results of comparison MiniRedis with crystal-redis.
> env REDIS_URL=redis://localhost:6379/1 crystal src/send.cr --release mini_redis 13.4k ( 74.62µs) (± 2.50%) 32 B/op fastest crystal-redis 13.36k ( 74.83µs) (± 2.97%) 144 B/op 1.00× slower
mini_redis is more memory-efficient.
Pipeline mode benchmarks
1 million pipelined
sends, average from 30 times repeats:
> env REDIS_URL=redis://localhost:6379/1 crystal src/pipeline.cr --release mini_redis 914.569ms 1.093M ops/s crystal-redis 908.182ms 1.101M ops/s
mini_redis has almost the same speed as
- Add the dependency to your
dependencies: mini_redis: github: vladfaust/mini_redis version: ~> 0.2.0
This shard follows Semantic Versioning v2.0.0, so check releases and change the
version accordingly. Note that until Crystal is officially released, this shard would be in beta state (
0.*.*), with every minor release considered breaking. For example,
0.2.0 is breaking and
0.1.1 is not.
require "mini_redis" redis = MiniRedis.new # MiniRedis responses wrap `Int64 | String | Bytes | Nil | Array(Value)` values, # which map to `Integer`, `Simple String`, `Bulk String`, `Nil` and `Array` Redis values # SET command returns `Simple String`, which is `String` in Crystal pp redis.send("SET", "foo", bar").raw.as(String) # => "OK" # GET command returns `Bulk String`, which is `Bytes` in Crystal bytes = redis.send("GET", "foo").raw.as(Bytes) pp String.new(bytes) # => "bar" # Bytes command payloads are also supported redis.send("set", "foo".to_slice, "bar".to_slice)
response = redis.pipeline do |pipe| # WARNING: Accessing the `.send` return value # within the pipe block would crash the program! pipe.send("SET", "foo", "bar") end pp typeof(response) # => [MiniRedis::Value(@raw="OK")]
response = redis.transaction do |tx| pp tx.send("SET", "foo", "bar").raw.as(String) # => "QUEUED" end pp typeof(response) # => MiniRedis::Value(@raw=[MiniRedis::Value(@raw="OK")])
pool = MiniRedis::Pool.new response = pool.get do |redis| # Redis is MiniRedis instance, can do anything redis.send("PING") end # Return value equals to the block's pp response.raw.as(String) # => "PONG" conn = pool.get pp conn.send("PING").raw.as(String) # => "PONG" pool.release(conn) # Do not forget to put it back!
env REDIS_URL=redis://localhost:6379 crystal spec and you're good to go.
- Fork it (https://github.com/vladfaust/mini_redis/fork)
- Create your feature branch (
git checkout -b my-new-feature)
- Commit your changes (
git commit -am 'feat: new feature') using angular-style commits
- Push to the branch (
git push origin my-new-feature)
- Create a new Pull Request
- Vlad Faust - creator and maintainer