Architecture: Database Client Design

 27th May 2022 at 2:29pm

数据库 client 库设计。

Redis blog 上有一篇文章 Multiplexing Explained(链接存档),描述了一个 client 库的主要职责:

  • Parsing and encoding RESP (Redis Serialization Protocol)
  • Making Redis commands idiomatic to your language
  • Managing the connection(s) to Redis

其中涉及连接管理这块,有这几种模式

  • Unmanaged
  • Pooled
  • Multiplexed

Unmanaged 意味着库提供的管理能力非常少,需要应用自行管理连接。比如 node_redis 库、Lua 的 Redis 库,库虽然会帮你建 TCP 连接(而不用你调用底层接口自己建),但是连接的建立和释放,基本上需要你手动管理。如果流量上来,你的程序可能不小心建了 10 万个连接把机器搞挂了。但必须认识到,并不一定是因为库的作者能力太弱才不帮你管理连接,有些可能是因为语言本身的模型限制(比如 JS 是事件驱动及单线程的)。

Pooled 表示库本身会维护一个连接池。这是最常见的模式。应用使用库发请求时,会在这个连接池中取一个连接来发送,发完后放回池子。如果池子里没有连接了,应用可能需要等待。

Multiplexed 表示库本身只使用 1 个连接,通过 pipelining 或者 multiplexing 来实现请求的并发(而不是单发单收)及节约资源。我理解 pipelining 与 multiplexing 不太相同(参考 Redis 的 pipelining 及 HTTP 2 的 multiplexing)。Pipelining 存在可能的问题是,如果请求 1 的回包太大,可能导致应用等待请求 2 的回包的时间,相较于 pooled 模式会更长。