数据库检查路径/ url 是否存在

Database to check whether a path/ url is present

我有一个应用程序,它可以有数千个 url。 假设 url 路径的形式为,

我想将这些路径存储在一个数据结构中,这样当一个请求到达一个不存在的路径时,我想尽早发现这一点并且 return 404 Not Found。 我可以想到两种方法,

  1. 存储在哈希集中并检查特定字符串是否存在。
  2. 存储在数据库中,因为我不想阻塞内存,因为可能有数百万个这样的 url。

对于方法 2,我在考虑是否可以使用像 Postgres 或 Mysql 这样的简单 RDBMS(因为我已经有使用它们的经验)或像 Redis 这样的 NoSql 数据库(虽然不确定)

使用 RDBMS,如果我将索引放在存储路径的列上,我会发现一个问题,因为当我尝试插入一个已经很大的 table 时,重新编制索引需要时间。 想知道其他人的想法,比如像 Redis 这样的 NoSql DB 在这里是否足够,或者任何其他更适合我的情况的建议。

方法 1 的缺点是您必须在服务器进程的每个实例中在内存中维护该哈希集的副本。

对于方法 2,您可以将 Redis 用作一种共享内存,并将 URL 存储在具有 O(1) 插入和 O(1) 成员检查时间复杂度的 Redis 集中。您将使用 [SADD][1] 和 [SISMEMBER][2] 命令。

让我们向 Redis 集添加一些 URL(添加到不存在的集会为您创建):

$ redis-cli
127.0.0.1:6379> sadd application_urls /app/something /app/somethingelse /api/v1/hello

(integer) 3

现在,让我们检查 URL 是否存在或应该是 404:

127.0.0.1:6379> sismember application_urls /app/something
(integer) 1
127.0.0.1:6379> sismember application_urls /app/whoops
(integer) 0

我们还可以使用 SMISMEMBER 命令在到 Redis 的单次网络往返中检查多个 URLs:

127.0.0.1:6379> smismember application_urls /app/something /app/whoops
1) (integer) 1
2) (integer) 0

1 的回复表示 URL 存在,0 表示不存在并且应该是 404。

这种方法将 100% 准确,代价是占用与在 Redis 中存储所有 URL 相关的内存(Redis 将整个数据集的副本存储在 RAM 中以提高速度)。如果数据集的大小在这里成为问题,您可以考虑使用 [RedisBloom 模块][3] 将集合替换为 Bloom 过滤器......而不是存储实际数据,Bloom 过滤器将权衡准确性 space 并存储数据的哈希值,这意味着当您检查成员资格时,您有时会得到误报。



  [1]: https://redis.io/commands/sadd
  [2]: https://redis.io/commands/sismember/
  [3]: https://redis.io/docs/stack/bloom/