# Radix Radix is a full-featured [Redis][redis] client for Go. See the reference links below for documentation and general usage examples. **[v3 Documentation](https://pkg.go.dev/github.com/mediocregopher/radix/v3#section-documentation)** **[v4 Documentation](https://pkg.go.dev/github.com/mediocregopher/radix/v4#section-documentation)** **[Discussion/Support Chat](https://matrix.to/#/#radix:waffle.farm)** Please open an issue, or start a discussion in the chat, before opening a pull request! ## Features * Standard print-like API which supports **all current and future redis commands**. * Connection pool which uses **connection sharing** to minimize system calls. * Full support for [Sentinel][sentinel] and [Cluster][cluster]. * Helpers for [EVAL][eval], [SCAN][scan], [Streams][stream], and [Pipelining][pipelining]. * Support for [pubsub][pubsub], as well as persistent pubsub wherein if a connection is lost a new one transparently replaces it. * API design allows for custom implementations of nearly anything. ## Versions There are two major versions of radix being supported: * v3 is the more mature version, but lacks the polished API of v4. v3 is only accepting bug fixes at this point. * v4 has feature parity with v3 and more! The biggest selling points are: * More polished API. * Full [RESP3][resp3] support. * Support for [context.Context][context] on all blocking operations. * Connection sharing (called "implicit pipelining" in v3) now works with Pipeline and EvalScript. View the [CHANGELOG][v4changelog] for more details. [v4changelog]: https://github.com/mediocregopher/radix/blob/v4/CHANGELOG.md ## Installation and Usage Radix always aims to support the most recent two versions of go, and is likely to support others prior to those two. [Module][module]-aware mode: go get github.com/mediocregopher/radix/v3 // import github.com/mediocregopher/radix/v3 go get github.com/mediocregopher/radix/v4 // import github.com/mediocregopher/radix/v4 ## Testing # requires a redis server running on 127.0.0.1:6379 go test github.com/mediocregopher/radix/v3 go test github.com/mediocregopher/radix/v4 ## Benchmarks Benchmarks were run in as close to a "real" environment as possible. Two GCE instances were booted up, one hosting the redis server with 2vCPUs, the other running the benchmarks (found in the `bench` directory) with 16vCPUs. The benchmarks test a variety of situations against many different redis drivers, and the results are very large. You can view them [here][bench results]. Below are some highlights (I've tried to be fair here): For a typical workload, which is lots of concurrent commands with relatively small amounts of data, radix outperforms all tested drivers except [redispipe][redispipe]: ``` BenchmarkDrivers/parallel/no_pipeline/small_kv/radixv4-64 17815254 2917 ns/op 199 B/op 6 allocs/op BenchmarkDrivers/parallel/no_pipeline/small_kv/radixv3-64 16688293 3120 ns/op 109 B/op 4 allocs/op BenchmarkDrivers/parallel/no_pipeline/small_kv/redigo-64 3504063 15092 ns/op 168 B/op 9 allocs/op BenchmarkDrivers/parallel/no_pipeline/small_kv/redispipe_pause150us-64 31668576 1680 ns/op 217 B/op 11 allocs/op BenchmarkDrivers/parallel/no_pipeline/small_kv/redispipe_pause0-64 31149280 1685 ns/op 218 B/op 11 allocs/op BenchmarkDrivers/parallel/no_pipeline/small_kv/go-redis-64 3768988 14409 ns/op 411 B/op 13 allocs/op ``` The story is similar for pipelining commands concurrently (radixv3 doesn't do as well here, because it doesn't support connection sharing for pipeline commands): ``` BenchmarkDrivers/parallel/pipeline/small_kv/radixv4-64 24720337 2245 ns/op 508 B/op 13 allocs/op BenchmarkDrivers/parallel/pipeline/small_kv/radixv3-64 6921868 7757 ns/op 165 B/op 7 allocs/op BenchmarkDrivers/parallel/pipeline/small_kv/redigo-64 6738849 8080 ns/op 170 B/op 9 allocs/op BenchmarkDrivers/parallel/pipeline/small_kv/redispipe_pause150us-64 44479539 1148 ns/op 316 B/op 12 allocs/op BenchmarkDrivers/parallel/pipeline/small_kv/redispipe_pause0-64 45290868 1126 ns/op 315 B/op 12 allocs/op BenchmarkDrivers/parallel/pipeline/small_kv/go-redis-64 6740984 7903 ns/op 475 B/op 15 allocs/op ``` For larger amounts of data being transferred the differences become less noticeable, but both radix versions come out on top: ``` BenchmarkDrivers/parallel/no_pipeline/large_kv/radixv4-64 2395707 22766 ns/op 12553 B/op 4 allocs/op BenchmarkDrivers/parallel/no_pipeline/large_kv/radixv3-64 3150398 17087 ns/op 12745 B/op 4 allocs/op BenchmarkDrivers/parallel/no_pipeline/large_kv/redigo-64 1593054 34038 ns/op 24742 B/op 9 allocs/op BenchmarkDrivers/parallel/no_pipeline/large_kv/redispipe_pause150us-64 2105118 25085 ns/op 16962 B/op 11 allocs/op BenchmarkDrivers/parallel/no_pipeline/large_kv/redispipe_pause0-64 2354427 24280 ns/op 17295 B/op 11 allocs/op BenchmarkDrivers/parallel/no_pipeline/large_kv/go-redis-64 1519354 35745 ns/op 14033 B/op 14 allocs/op ``` All results above show the high-concurrency results (`-cpu 64`). Concurrencies of 16 and 32 are also included in the results, but didn't show anything different. For serial workloads, which involve a single connection performing commands one after the other, radix is either as fast or within a couple % of the other drivers tested. This use-case is much less common, and so when tradeoffs have been made between parallel and serial performance radix has general leaned towards parallel. Serial non-pipelined: ``` BenchmarkDrivers/serial/no_pipeline/small_kv/radixv4-16 346915 161493 ns/op 67 B/op 4 allocs/op BenchmarkDrivers/serial/no_pipeline/small_kv/radixv3-16 428313 138011 ns/op 67 B/op 4 allocs/op BenchmarkDrivers/serial/no_pipeline/small_kv/redigo-16 416103 134438 ns/op 134 B/op 8 allocs/op BenchmarkDrivers/serial/no_pipeline/small_kv/redispipe_pause150us-16 86734 635637 ns/op 217 B/op 11 allocs/op BenchmarkDrivers/serial/no_pipeline/small_kv/redispipe_pause0-16 340320 158732 ns/op 216 B/op 11 allocs/op BenchmarkDrivers/serial/no_pipeline/small_kv/go-redis-16 429703 138854 ns/op 408 B/op 13 allocs/op ``` Serial pipelined: ``` BenchmarkDrivers/serial/pipeline/small_kv/radixv4-16 624417 82336 ns/op 83 B/op 5 allocs/op BenchmarkDrivers/serial/pipeline/small_kv/radixv3-16 784947 68540 ns/op 163 B/op 7 allocs/op BenchmarkDrivers/serial/pipeline/small_kv/redigo-16 770983 69976 ns/op 134 B/op 8 allocs/op BenchmarkDrivers/serial/pipeline/small_kv/redispipe_pause150us-16 175623 320512 ns/op 312 B/op 12 allocs/op BenchmarkDrivers/serial/pipeline/small_kv/redispipe_pause0-16 642673 82225 ns/op 312 B/op 12 allocs/op BenchmarkDrivers/serial/pipeline/small_kv/go-redis-16 787364 72240 ns/op 472 B/op 15 allocs/op ``` Serial large values: ``` BenchmarkDrivers/serial/no_pipeline/large_kv/radixv4-16 253586 217600 ns/op 12521 B/op 4 allocs/op BenchmarkDrivers/serial/no_pipeline/large_kv/radixv3-16 317356 179608 ns/op 12717 B/op 4 allocs/op BenchmarkDrivers/serial/no_pipeline/large_kv/redigo-16 244226 231179 ns/op 24704 B/op 8 allocs/op BenchmarkDrivers/serial/no_pipeline/large_kv/redispipe_pause150us-16 80174 674066 ns/op 13780 B/op 11 allocs/op BenchmarkDrivers/serial/no_pipeline/large_kv/redispipe_pause0-16 251810 209890 ns/op 13778 B/op 11 allocs/op BenchmarkDrivers/serial/no_pipeline/large_kv/go-redis-16 236379 225677 ns/op 13976 B/op 14 allocs/op ``` [bench results]: https://github.com/mediocregopher/radix/blob/v4/bench/bench_results.txt ## Copyright and licensing Unless otherwise noted, the source files are distributed under the *MIT License* found in the LICENSE.txt file. [redis]: http://redis.io [eval]: https://redis.io/commands/eval [scan]: https://redis.io/commands/scan [stream]: https://redis.io/topics/streams-intro [pipelining]: https://redis.io/topics/pipelining [pubsub]: https://redis.io/topics/pubsub [sentinel]: http://redis.io/topics/sentinel [cluster]: http://redis.io/topics/cluster-spec [module]: https://github.com/golang/go/wiki/Modules [redispipe]: https://github.com/joomcode/redispipe [context]: https://pkg.go.dev/context [resp3]: https://github.com/antirez/RESP3/blob/master/spec.md