Type-safe Redis client for Golang
Go to file
Jason Parrott 7fa8fdf3e7
Cleanup sentinel pubsub on close
Currently, the pubsub connection is aggressively disconnected when we close the upstream client which causes it to log something like:

redis: 2018/11/09 09:10:07 pubsub.go:151: redis: discarding bad PubSub connection: read tcp 127.0.0.1:61025->127.0.0.1:26378: use of closed network connection

This change simply cleans up the connection on close.  

We create new redis servers and connections for each set of independent tests and the logs were getting spammy.
2018-11-09 09:32:22 -05:00
internal Add releaseConnStrict 2018-10-14 11:27:34 +03:00
testdata Added backoff retry 2017-05-26 14:33:34 +03:00
.gitignore Use go standard path for test data 2016-03-12 10:25:59 +00:00
.travis.yml travis: test on Go 1.11 2018-09-07 11:46:34 +03:00
CHANGELOG.md Process pipeline commands concurrently 2018-09-11 13:30:51 +03:00
LICENSE Fix license. 2016-09-12 12:00:28 +00:00
Makefile Fix build on 32bit arch 2018-03-07 12:41:11 +02:00
README.md Code highlighting for example codes 2018-07-20 17:47:53 +09:00
bench_test.go Bench bigget values 2018-08-15 09:10:53 +03:00
cluster.go Add releaseConnStrict 2018-10-14 11:27:34 +03:00
cluster_commands.go Add Cluster.DBSize 2017-09-11 09:19:30 +03:00
cluster_test.go remove snake case use 2018-10-11 12:58:31 +02:00
command.go Implement BZPop{Min,Max} 2018-11-02 18:07:01 +01:00
command_test.go Add FlushDBAsync and FlushAllAsync 2017-06-17 12:53:16 +03:00
commands.go Change ZWithKey 2018-11-03 12:07:25 +02:00
commands_test.go Change ZWithKey 2018-11-03 12:07:25 +02:00
doc.go doc: fix outdated reference. 2014-10-07 09:27:55 +03:00
example_instrumentation_test.go Replace client with redisdb in examples 2018-08-12 11:45:35 +03:00
example_test.go use more idiomatic for loop in ExamplePubSub 2018-10-03 16:36:21 -07:00
export_test.go Rework ReceiveMessage 2018-07-23 17:10:58 +03:00
internal_test.go Add missing options to UniversalOptions 2018-08-15 08:44:06 +03:00
iterator.go Remove Scanner in favor of ScanCmd. 2017-01-03 12:44:06 +02:00
iterator_test.go Add FlushDBAsync and FlushAllAsync 2017-06-17 12:53:16 +03:00
main_test.go Optimize reading big values 2018-08-16 14:01:03 +03:00
options.go Add test for read timeout option (#877) 2018-10-05 09:46:29 +03:00
options_test.go Add test for read timeout option (#877) 2018-10-05 09:46:29 +03:00
pipeline.go Add more docs for Tx 2018-07-12 15:57:03 +03:00
pipeline_test.go Add FlushDBAsync and FlushAllAsync 2017-06-17 12:53:16 +03:00
pool_test.go Add MaxConnAge 2018-08-12 10:25:16 +03:00
pubsub.go Fix nil ping error 2018-10-09 10:52:30 +03:00
pubsub_test.go Add MaxConnAge 2018-08-12 10:25:16 +03:00
race_test.go Add more race tests 2018-05-17 14:55:00 +03:00
redis.go Add releaseConnStrict 2018-10-14 11:27:34 +03:00
redis_test.go Cleanup pool 2018-05-29 17:29:47 +03:00
result.go Optimize reading big values 2018-08-16 14:01:03 +03:00
ring.go Add releaseConnStrict 2018-10-14 11:27:34 +03:00
ring_test.go Rework ReceiveMessage 2018-07-23 17:10:58 +03:00
script.go Script: Fix `Exists` to use hash instead of source (#726) 2018-03-05 11:03:03 +02:00
sentinel.go Cleanup sentinel pubsub on close 2018-11-09 09:32:22 -05:00
sentinel_test.go Resent client pool when sentinel switches master 2017-06-29 16:53:49 +03:00
tx.go Add more docs for Tx 2018-07-12 15:57:03 +03:00
tx_test.go Cleanup pool 2018-05-29 17:29:47 +03:00
universal.go Add missing options to UniversalOptions 2018-08-15 08:44:06 +03:00
universal_test.go Update import 2017-02-20 14:13:02 +00:00

README.md

Redis client for Golang

Build Status GoDoc Airbrake

Supports:

API docs: https://godoc.org/github.com/go-redis/redis. Examples: https://godoc.org/github.com/go-redis/redis#pkg-examples.

Installation

Install:

go get -u github.com/go-redis/redis

Import:

import "github.com/go-redis/redis"

Quickstart

func ExampleNewClient() {
	client := redis.NewClient(&redis.Options{
		Addr:     "localhost:6379",
		Password: "", // no password set
		DB:       0,  // use default DB
	})

	pong, err := client.Ping().Result()
	fmt.Println(pong, err)
	// Output: PONG <nil>
}

func ExampleClient() {
	err := client.Set("key", "value", 0).Err()
	if err != nil {
		panic(err)
	}

	val, err := client.Get("key").Result()
	if err != nil {
		panic(err)
	}
	fmt.Println("key", val)

	val2, err := client.Get("key2").Result()
	if err == redis.Nil {
		fmt.Println("key2 does not exist")
	} else if err != nil {
		panic(err)
	} else {
		fmt.Println("key2", val2)
	}
	// Output: key value
	// key2 does not exist
}

Howto

Please go through examples to get an idea how to use this package.

Look and feel

Some corner cases:

// SET key value EX 10 NX
set, err := client.SetNX("key", "value", 10*time.Second).Result()

// SORT list LIMIT 0 2 ASC
vals, err := client.Sort("list", redis.Sort{Offset: 0, Count: 2, Order: "ASC"}).Result()

// ZRANGEBYSCORE zset -inf +inf WITHSCORES LIMIT 0 2
vals, err := client.ZRangeByScoreWithScores("zset", redis.ZRangeBy{
	Min: "-inf",
	Max: "+inf",
	Offset: 0,
	Count: 2,
}).Result()

// ZINTERSTORE out 2 zset1 zset2 WEIGHTS 2 3 AGGREGATE SUM
vals, err := client.ZInterStore("out", redis.ZStore{Weights: []int64{2, 3}}, "zset1", "zset2").Result()

// EVAL "return {KEYS[1],ARGV[1]}" 1 "key" "hello"
vals, err := client.Eval("return {KEYS[1],ARGV[1]}", []string{"key"}, "hello").Result()

Benchmark

go-redis vs redigo:

BenchmarkSetGoRedis10Conns64Bytes-4 	  200000	      7621 ns/op	     210 B/op	       6 allocs/op
BenchmarkSetGoRedis100Conns64Bytes-4	  200000	      7554 ns/op	     210 B/op	       6 allocs/op
BenchmarkSetGoRedis10Conns1KB-4     	  200000	      7697 ns/op	     210 B/op	       6 allocs/op
BenchmarkSetGoRedis100Conns1KB-4    	  200000	      7688 ns/op	     210 B/op	       6 allocs/op
BenchmarkSetGoRedis10Conns10KB-4    	  200000	      9214 ns/op	     210 B/op	       6 allocs/op
BenchmarkSetGoRedis100Conns10KB-4   	  200000	      9181 ns/op	     210 B/op	       6 allocs/op
BenchmarkSetGoRedis10Conns1MB-4     	    2000	    583242 ns/op	    2337 B/op	       6 allocs/op
BenchmarkSetGoRedis100Conns1MB-4    	    2000	    583089 ns/op	    2338 B/op	       6 allocs/op
BenchmarkSetRedigo10Conns64Bytes-4  	  200000	      7576 ns/op	     208 B/op	       7 allocs/op
BenchmarkSetRedigo100Conns64Bytes-4 	  200000	      7782 ns/op	     208 B/op	       7 allocs/op
BenchmarkSetRedigo10Conns1KB-4      	  200000	      7958 ns/op	     208 B/op	       7 allocs/op
BenchmarkSetRedigo100Conns1KB-4     	  200000	      7725 ns/op	     208 B/op	       7 allocs/op
BenchmarkSetRedigo10Conns10KB-4     	  100000	     18442 ns/op	     208 B/op	       7 allocs/op
BenchmarkSetRedigo100Conns10KB-4    	  100000	     18818 ns/op	     208 B/op	       7 allocs/op
BenchmarkSetRedigo10Conns1MB-4      	    2000	    668829 ns/op	     226 B/op	       7 allocs/op
BenchmarkSetRedigo100Conns1MB-4     	    2000	    679542 ns/op	     226 B/op	       7 allocs/op

Redis Cluster:

BenchmarkRedisPing-4                	  200000	      6983 ns/op	     116 B/op	       4 allocs/op
BenchmarkRedisClusterPing-4         	  100000	     11535 ns/op	     117 B/op	       4 allocs/op

See also