【问题标题】:Is it a good practice to cache Redis data in ngx.shared在 ngx.shared 中缓存 Redis 数据是一种好习惯吗
【发布时间】:2018-01-17 08:46:39
【问题描述】:

我在 nginx 中嵌入了一些 Lua 代码。在这段代码中,我从 Redis 缓存中获取了一些小数据。现在我想知道,使用ngx.shared 构造在 nginx 中缓存这些数据(在某种意义上已经缓存)是否是一个好习惯?这样做有什么好处和坏处吗?在伪代码中,我希望有类似的东西:

local cache = ngx.shared.cache
local cached_key = cache:get("cached_key")
if cached_key == nil then
    ... get data from Redis
    cache:set("cached_key", cached_key)
end

【问题讨论】:

  • 我认为这个问题很模糊。谷歌搜索“ngx.shared.cache”返回的结果实际上少于 10 个。你最好在适当的 ML 上问这个问题。
  • 我认为,搜索ngx.shared.cache没有意义,因为这种情况下的缓存是我自己的变量名。这个问题是相当概念性的——在现实世界的实践中,他们是否在 nginx 缓存中缓存 Redis(或 memcached)数据以提供更多性能。

标签: caching nginx lua


【解决方案1】:

如文档中所述,ngx.shared 是 nginx 服务器的所有工作人员之间共享的空间。

所有列出的操作都是原子的,所以如果你对ngx.shared 一个接一个地使用两个操作,你只需要关心race conditions。在这种情况下,应该使用ngx.semaphore 保护它们。

优点:

  • 使用 ngx.shared 可以更快地访问数据,因为您可以避免对 Redis 服务器的请求/响应循环。
  • 即使您需要ngx.semaphore,您也可以期望更快地访问数据(但我没有提供基准)。

缺点:

  • ngx.shared 缓存提供的数据不准确,因为您的本地缓存不反映当前 Redis 值。这并不总是一个关键点,因为在 worker 中使用的值与存储在 Redis 中的值之间总是存在差异。
  • ngx.shared 中存储的数据可能不一致,这一点更为重要。例如,它可以存储x=truey=false,而在Redis 中xy 始终具有相同的值。这取决于您如何更新本地缓存。
  • 您必须自己处理缓存,方法是在缓存中的值被发送到 Redis 时更新它们。这可以通过包装 redis 函数轻松完成。如果您在每次调用 redis.get 之后处理更新,则可能会出现错误,因为您(或某人)忘记它。
  • 您还必须处理读取:每当在您的ngx.cache 中找不到值时,您必须自动从 Redis 读取它。如果您在每次调用 cache.get 之后处理读取操作,预计会出现错误,因为您(或某人)忘记它。

对于最后两点,您可以轻松编写一个小型包装模块。

作为结论:

  • 如果您的服务器只运行一个实例,并带有一个或多个工作器,那么使用ngx.shared 会很有趣,因为您始终可以缓存始终保持最新的 Redis 数据。
  • 如果您的服务器运行多个实例并且必须始终保持最新的缓存,或者如果您可能遇到一致性问题,那么您应该避免使用ngx.shared 进行缓存。
  • 在所有情况下,如果您的数据可能很大,请确保在内存消耗过高之前提供一种清理方法。如果您无法提供清洁服务,则不应使用ngx.shared

另外,不要忘记将缓存值存储在一个local变量中,以避免get一次又一次地调用它,从而提高效率。

【讨论】:

  • 谢谢您,先生!这是非常有用的信息和帮助!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-08-17
  • 2020-09-10
  • 2015-12-14
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多