Redis: is Client safe for concurrent use?

Created on 11 Sep 2015  路  9Comments  路  Source: go-redis/redis

is Client safe for concurrent use? I'm using redis in a web app and I'm wondering if I should keep the client in a global variable or if I should Close / create a new one on each handler request.

Most helpful comment

The client is thread safe, but pipelines, multi blocks, etc are not.

All 9 comments

The client is thread safe, but pipelines, multi blocks, etc are not.

What @dim said. Multi, pipelines and PubSub are not thread-safe, because using them from multiple goroutines does not make much sense to me. But we can make them thread-safe if you find such use case.

Hopefully https://github.com/go-redis/redis/pull/167 will make situation clearer.

I have an app where .multi should be called from hundreds of goroutines in order to persist some work done by each worker. Is it good use-case to make .multi thread safe?

Not really, in my opinion. For me, the same rule applies here as for native
Go maps. The Go team could have made them thread safe but decided not to
add it would benefit only a small fraction of use cases.

I don't know the exact scenario, but I would suggest you should
batch/collect the results from your goroutines and then build a multi
statement from a single goroutine. Take e.g. a look at
https://github.com/facebookgo/muster for that purpose.

Well, maybe I am missing something. I don't wanna share multi tx between goroutines, each goroutine will create separate client.Multi().
I guess this code is ok then: https://github.com/sammy007/go-cryptonote-pool/blob/master/go-pool/storage/redis.go#L73
Please tell me if I am wrong.

From what I see it is okay, but you use Redis transactions (MULTI) without WATCH, which AFAIK is somewhat pointless (but I can be wrong :). When you don't need WATCH you can just use pipelines - https://godoc.org/gopkg.in/redis.v3#ex-Client-Pipelined. It will not be much faster though.

I don't wanna share multi tx between goroutines, each goroutine will create separate client.Multi().

Then you don't have to worry about thread-safety since each goroutine will have its own copy of Multi.

How about the following scenario: create a pipeline, pass it to multiple goroutines (which do some operations) and call Exec() a single time (after the goroutines have finished) from the function that created the pipeline. Is this still unsafe ?

Yes, currently it is unsafe. But I see a point and I am inclined to make pipeline/multi threadsafe just to avoid confusion it causes :)

Under high concurrency with single client, some request may fail.
After filter out the failed request, the response is OK.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

pmenglund picture pmenglund  路  4Comments

pranas picture pranas  路  8Comments

zhangruiskyline picture zhangruiskyline  路  7Comments

MaerF0x0 picture MaerF0x0  路  7Comments

patrickwhite256 picture patrickwhite256  路  7Comments