【发布时间】:2018-11-12 15:01:50
【问题描述】:
我在一个应用程序中使用 redigo,我想知道我的服务应该如何与 Redis 交互。
维基百科对线程安全有这样的说法:
线程安全是适用于多线程代码的计算机编程概念。线程安全代码仅以确保所有线程正常运行并满足其设计规范而没有意外交互的方式操作共享数据结构。
我对此的解释是,如果一个数据结构需要被多个客户端访问(在当今的微服务世界中,有数百、数千甚至数百万),线程安全是我们确保状态正常的方式无论哪个客户端以及何时访问数据,都可以正确保存在系统中。这意味着解决访问优先级(哪个客户端首先到达那里),确保锁定突变(一次只有一个客户端可以写入)同时促进并发性(如果没有更改,许多客户端可以读取数据)。
据我所知,一个 redigo 客户端可以被多个“goroutines”(或线程)同时使用。这让我相信像我熟悉的 Java 中的单例实现就足够了。
我看到了一些例子,例如 here 和 here,其中 Redis 连接 (pools) 只是在 main 方法中创建并传递给各种 redigo 函数。这似乎不是完成工作的最可靠方法,尽管它们似乎确实遵循单例模式。 (可以理解,第二篇文章实际上只是一个快速的 n'dirty API。)
我会这样做:
在
main函数调用中init返回一个redigopool。创建接受
pool作为参数的处理函数(控制器)(一种“脏”的依赖注入)。
这将(我认为)确保只创建一个 pool。
或者,我每次想访问数据存储时都不能创建pool(客户端)有什么原因吗?如果客户端在事务完成后被杀死,那么每次处理程序收到请求时启动新的pool 是否有任何问题?
【问题讨论】:
-
确实效率低下。连接池的全部意义在于重用连接并避免建立新连接所涉及的开销。 en.wikipedia.org/wiki/Connection_pool
-
酷。所以单例访问是要走的路。
-
Redigo 的pool documentation 描述了如何在 Web 应用程序中使用池。您应该创建一个池并共享它。
-
另见Redigo's documentation on allowed concurrency。 Redigo 没有问题中提到的“客户端”类型。 Redigo 确实有一个线程安全池和一个部分不安全的连接。