线程安全的Redis客户端

huangapple go评论95阅读模式
英文:

Threadsafe redis client

问题

我正在使用goredis,据我所见,当客户端连接到Redis服务器时,会有一个连接池。我不知道如何查询Redis服务器并确保以线程安全的方式进行查询。

目前我这样做:

我创建了一个全局指针clientclient *goredis.Redis
然后我这样做:

go func () {
    http.HandleFunc("/send_data/", trackHandler)
    http.HandleFunc("/init/", initHandler)
    http.ListenAndServe(":8000", nil)
} ()

现在我想在trackHandlerinitHandler中使用client,但我担心在执行查询时没有任何同步方式。这种方式可能会导致问题混乱。在golang中解决这个问题的规范方式是什么?

我还想知道在redis-py中是如何工作的。
我看到了这个线程

> 一般来说,我建议你要么:
>
> a. 创建一个全局的Redis客户端实例,并让你的代码使用它。
> b. 创建一个全局的连接池,并将其传递给代码中的各个Redis实例。
>
> 这两种方法都能实现相同的效果。都是线程安全的。

在第一种情况下是如何实现的呢?

英文:

I'm using goredis and as far as I can see - there is a connection pool when client connects to redis server. I don't know how to query redis server and to be sure that it is in a thread-safe way.

Currently I do this:

I am creating global pointer client: client *goredis.Redis
Then I do this:

go func () {
    http.HandleFunc("/send_data/", trackHandler)
    http.HandleFunc("/init/", initHandler)
    http.ListenAndServe(":8000", nil)
} ()

So now I want to use client in trackHandler and initHandler but I am concerned that there is no syncing in any way when executing queries. Is it possible to mess-up things in this way. What is the canonical way to solve this issue in golang?

Also I am wondering how this works in redis-py.
I've seen this thread:

> In general, I suggest you either:
>
> a. create a global redis client instance and have your code use that.
> b. create a global connection pool and pass that to various redis instances throughout your code.
>
> Both of these accomplish the same thing. Both are threadsafe.

How is it done in the first scenario?

答案1

得分: 2

客户端有一个线程安全的连接池,每当执行一个命令时,客户端会尝试从连接池中获取一个连接。因此,即使客户端没有锁,它仍然是线程安全的,所以使用全局客户端应该是没问题的。

在这里可以看到,Dial函数是如何创建一个新的连接池的:
https://github.com/xuyu/goredis/blob/master/redis.go#L432

这里是连接池本身的锁定示例:
https://github.com/xuyu/goredis/blob/master/redis.go#L287

关于redis-py - 如果你没有显式地使用连接池,它会创建自己的内部连接池,所以它是线程安全的,因为在底层连接是全局池化的。基本上是一样的。

英文:

The client has a connection pool which is thread safe, and whenever you execute a command, the client tries to get a connection from the pool. Thus even though the client has no lock, it's still thread safe, so you should be fine with a global client.

See here - how the Dial function creates a new connection pool:
https://github.com/xuyu/goredis/blob/master/redis.go#L432

And here for an example of locking in the connectino pool itself.
https://github.com/xuyu/goredis/blob/master/redis.go#L287

Re redis-py - It creates its own internal connection pool if you don't use one explicitly, so it's thread safe because under the hood the connections are pooled globally. Same thing basically.

huangapple
  • 本文由 发表于 2014年7月3日 19:41:30
  • 转载请务必保留本文链接:https://go.coder-hub.com/24552764.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定