0

我在应用程序中使用 redigo,我想知道我的服务应该如何与 Redis 交互。

维基百科对线程安全有这样的说法:

线程安全是适用于多线程代码的计算机编程概念。线程安全代码仅以确保所有线程正常运行并满足其设计规范而没有意外交互的方式操作共享数据结构。

我对此的解释是,如果一个数据结构需要被多个客户端访问(在当今的微服务世界中,数百、数千甚至数百万)线程安全是我们确保正确保存状态的方式系统无论何时何地访问数据。这意味着解决访问优先级(哪个客户端首先到达那里),确保锁定突变(一次只有一个客户端可以写入)同时促进并发性(如果没有更改,许多客户端可以读取数据)。

从我收集到的信息来看,一个 redigo 客户端可以被多个“goroutines”(或线程)同时使用。这让我相信像我熟悉的 Java 中的单例实现就足够了。

我看到了示例,例如,herehere,其中 Redis 连接(pools)只是在main方法中创建并传递给各种 redigo 函数。这似乎不是完成工作的最可靠方法,尽管它们似乎确实遵循单例模式。(可以理解的是,第二篇文章实际上只是一个快速的 n'dirty API。)

我会这样做:

  1. 在返回 redigo的main函数调用中。initpool

  2. 创建接受 apool作为参数的处理函数(控制器)(一种“脏”依赖注入)。

这将(我认为)确保只pool创建一个。

pool或者,每次我想访问数据存储时,是否有任何理由无法创建(客户端)?pool如果客户端在事务完成后被杀死,那么每次处理程序收到请求时启动一个新的有什么问题吗?

4

1 回答 1

3

正确答案已经在评论中提供,尽管我仍然想加我的 5 美分。

您的问题混淆了两个概念 - 并发和资源池

并发代码确保多个执行流程使用共享内存在同一个应用程序中安全地工作。在我们的示例中,我们有来自用户的多个 http 请求和并发执行的这些请求的处理程序代码。数据库连接是该流程的一部分,并且是请求执行所必需的。

并发代码应该能够使用数据库连接并在必要时打开/关闭连接。

虽然,并发与定义在任何给定时间应打开多少连接以及应如何重用/共享这些连接的规则无关:

  • 有人可以为每个请求创建数据库连接,并且该代码是并发的。
  • 有人可以使用一些共享的数据库连接,并且只要多个请求不相互干扰,该代码就是并发的。内存锁通常可以实现什么。

另一方面,连接池是一种提供有效方式来处理数据库连接的模式。为什么管理连接生命周期很重要:

  1. 打开连接很昂贵
  2. 在不使用数据库的情况下保持连接的成本很高,只能保持有限数量的打开连接。

使用连接池,您可以控制:

  1. 有多少连接始终打开 - 预热慢速资源
  2. 最大打开连接数 - 防止打开太多连接
  3. 连接超时 - 连接重用和释放未使用资源之间的平衡

维护每个请求的连接或连接池不允许有效的连接重用。每个请求都会因连接打开开销而减慢,流量高峰会导致打开太多连接等。

通常应用程序在所有请求之间共享一个连接池。

有时,开发人员会为不同类型的连接创建多个池。例如,一个用于事务操作的池和一个用于报告的池。

于 2018-11-12T19:40:31.303 回答