当不使用denoâ!
#网络开发人员 #node #devops #deno

我一直很喜欢Deno个人项目!开发人员的体验非常出色,Deno Deploy使快速,轻松地部署它变得容易。

虽然其按需设计效率高且非常适合许多用例,但由于其为每个请求创建新实例的性质,因此在某些情况下的性能很差。不幸的是,当我为我一直从事的项目构建缓存层时,我遇到了其中之一。在本文中,我将解决这些问题,并解释我避免使用的替代路线。

问题:redis超负荷ð¯

数据库读取既昂贵又慢。有一个multitude of other reasons为什么缓存至关重要,但是对于我正在处理的项目,我正在使用supabase,他们的免费层仅支持有限的带宽。为了避免任何限制限制的限制,我在其前面添加了一个Redis层,以减少直接击中数据库的查询数量。

方便地,Deno有一个deno-redis(实验)插件,我用来在项目中添加一个简单的缓存层:

import { connect } from "https://deno.land/x/redis/mod.ts";

const redis = await connect({ hostname, port });

let cachedResult = await redis.get(query);
let result = cachedResult;

if (!cachedResult) {
  result = db.get(query);
  await redis.set(query, result);
}

return result;

有了这个,完整的请求生命周期如下:

Request lifecycle

这很好!但是,在足够的请求开始涌入后,会抱怨有太多的连接,不允许新的连接(redis.connect导致:ERR max number of clients reached)。当然,我还使用他们的免费级别,一次限制了30个客户。但是,由于hosted integrations通常在连接数量上有硬上限,因此此问题也会出现。

为什么会发生这种情况?这是由于DeNo的基本方面:每次提出请求时,都会创建全新的上下文,在这种情况下,必须建立与Redis的新联系。为了形象化这一点,这是当n用户每个人提出请求时发生的情况:

Problem with n requests

为了解决这个问题,我们需要一种方法来减少连接的数量并将其保持在极限之下,但是当我们看到这样做的性能好处。

一个持续的连接ð°°

尽管任何传统的服务器环境都可以启用此功能,但我使用了Node,因为它接近Deno且易于使用。有了几行代码,在开始时创建单个客户端的express服务器将启用任何传入的请求以重复使用相同的连接。添加一些简单的路由来检测请求参数并使用REDIS返回的内容响应,然后允许DENO中的缓存请求与GET请求交换到此服务器。

这被称为reverse proxy,在任何网络堆栈中都是常见的。有了这个,请求生命周期现在看起来像这样:

Reverse proxy added

有了这个地方,由于连接的数量,不仅没有错误,而且性能会大大改善,持续时间降低了50%以上:

基准 时间(AVG) (min - 最大) p75 p99
deno-> redis 65.06 ms/iter (792 ns - 114.68 ms) 111.41 MS 114.68 MS
deno->节点 - > redis 34.79 ms/iter (28.4 msâ€41.7 ms) 36.53 MS 41.7 m

但是有一个转折! -

我的主要目的是确定重新误差的解决方案,但我认为为什么不测试持续的postgres连接的行为是否相似。令我惊讶的是,结果相反!

令人困惑的是,当对上述相同的基准测试(deno vs deno + deNo +节点层)时,就会有一个令人惊讶的结果:deno的表现优于〜2x!因此,尽管为每个请求重新创建supabase客户端,但DENO仍然胜过节点:

基准 时间(AVG) (min - 最大) p75 p99
deno-> Postgres 42.98 ms/iter (916 NSâ€89.29 ms) 79.8 ms 89.29 MS
deno->节点 - > Postgres 88.24 ms/iter (667 ns - 205.44 ms) 160.8 ms 205.44 MS

这是由于deno's中不存在的@supabase/supabase-js实施中的限制,还是只是DENO的表现更好,我不完全确定。据我所知,连接到单个Supabase实例的客户端数量没有限制。但是基于这些数字,我将保留节点以查询redis和deno查询邮政。

感谢您的阅读!


如果您想自己尝试这些基准,这是运行这些基准测试的源:

GitHub logo brycedorn / deno-node-redis-postgres-benchmarks

根据DENO与DENO和节点的组合对Redis和Postgres性能进行基准测试。

Deno vs Node Redis/Postgres benchmarking

As part of a dev.to article.

结果

在Apple M1 Max 64GB Ventura上运行的结果来自阿姆斯特丹。

使用节点? 基准 时间(AVG) (min - 最大) p75 p99
deno-> redis 65.06 ms/iter (792 ns - 114.68 ms) 111.41 MS 114.68 MS
deno-> Postgres 42.98 ms/iter (916 NSâ€89.29 ms) 79.8 ms 89.29 MS
deno->节点 - > redis 34.79 ms/iter (28.4 msâ€41.7 ms) 36.53 MS 41.7 m
deno->节点 - > Postgres 88.24 ms/iter (667 ns - 205.44 ms) 160.8 ms 205.44 MS

在本地运行

先决条件

  • deno> = v1.30.2。
  • v8> = v10.9.194.5。
  • ts> = v4.9.4。
  • node> = v16.15.0。
  • redis实例,我正在使用Redis Enterprise Cloud(有免费层)。
  • Postgres实例,我正在使用supabase(有免费层)
    • 此示例使用hex作为查找键,但这是