请负责任地使用 Redis

2025-06-10

请负责任地使用 Redis

Redis 的核心在于速度。但 Redis 速度快并不意味着它在你向其发出请求时不会占用时间和资源。如果这些请求的发送方式不当,就会累积起来,影响应用程序的性能。以下是 Kenna 是如何从痛苦的经历中吸取这一教训的。

隐藏在众目睽睽之下

Kenna数据库中最大的表格之一是漏洞。我们目前拥有近 40 亿个漏洞。漏洞是指攻击者可以利用的弱点,从而未经授权访问计算机系统。简而言之,漏洞是公司遭受黑客攻击的途径。

我们首先将所有这些漏洞存储在 MySQL 中,这是我们的数据来源。之后,我们将漏洞数据索引到Elasticsearch中。

当我们将所有这些漏洞索引到 Elasticsearch 中时,我们必须向 Redis 发出请求才能知道将它们存放在哪里。在 Elasticsearch 中,漏洞是按客户端组织的。为了确定漏洞的归属,我们必须向 Redis 发出 GET 请求来获取该漏洞的索引名称。

在准备漏洞索引时,我们会收集所有漏洞哈希值。然后,在将它们发送到 Elasticsearch 之前,我们要做的最后一件事是发出 Redis GET 请求,根据每个漏洞的客户端检索其索引名称。

indexing_hashes = vulnerability_hashes.map do |hash|
   {
      :_index => Redis.get("elasticsearch_index_#{hash[:client_id]}")
      :_type => hash[:doc_type],
      :_id => hash[:id],
      :data => hash[:data]
   }
end
Enter fullscreen mode Exit fullscreen mode

这些漏洞哈希值按客户端分组,因此 GET 请求

Redis.get("elasticsearch_index_#{hash[:client_id]}")
Enter fullscreen mode Exit fullscreen mode

经常会一遍又一遍地返回相同的信息。所有这些简单的 GET 请求都快得惊人,大约需要一毫秒就能完成。

(pry)> index_name = Redis.get("elasticsearch_index_#{client_id}")
DEBUG -- : [Redis] command=GET args="elasticsearch_index_1234"
DEBUG -- : [Redis] call_time=1.07 ms
Enter fullscreen mode Exit fullscreen mode

但是,无论您的外部请求有多快,如果您发出大量请求,都会花费很长时间。由于我们发出了大量简单的 GET 请求,它们占据了我们索引作业大约65%的运行时间。您可以在下表中看到这个统计数据,它在图表中用棕色表示。

消除大量此类请求的解决方案是使用本地 Ruby 缓存!我们最终使用 Ruby 哈希来缓存每个客户端的 Elasticsearch 索引名称。

client_indexes = Hash.new do |h, client_id| 
   h[client_id] = Redis.get("elasticsearch_index_#{client_id}")
end

Enter fullscreen mode Exit fullscreen mode

然后,当循环遍历所有漏洞哈希并将其发送到 Elasticsearch 时,我们只需引用此客户端索引哈希,而不是针对每个漏洞访问 Redis。

indexing_hashes = vuln_hashes.map do |hash|
   {
      :_index => client_indexes[hash[:client_id]]
      :_type => hash[:doc_type],
      :_id => hash[:id],
      :data => hash[:data]
   }
end
Enter fullscreen mode Exit fullscreen mode

这意味着我们只需要对每个客户端攻击一次 Redis,而不是对每个漏洞攻击一次。

回报

假设我们有 3 批漏洞需要编入索引。

对于这三个批次,无论每个批次中有多少个漏洞,我们只需要向 Redis 发出总共 3 个请求。这些批次通常每个包含 1000 个漏洞,因此这项更改将我们对 Redis 的访问次数减少了 1000 倍,从而使作业速度提高了 65%。

虽然 Redis 很快,但使用本地缓存总是更快!简单来说,从本地缓存获取信息就像从芝加哥市中心开车去奥黑尔机场取一样。

要从 Redis 获取相同的信息,就像从芝加哥乘飞机一路飞到波士顿一样。

Redis 速度非常快,以至于当你与它交互时,很容易忘记你实际上是在向外部发出请求。这些外部请求会累积起来,影响应用程序的性能。不要将 Redis 视为理所当然。确保你向它发出的每个请求都是绝对必要的。

如果您对使用 Ruby 防止数据库命中的其他方法感兴趣,请查看我在RubyConf 上发表的“Cache Is King”演讲,该演讲启发了本文的灵感。

鏂囩珷鏉ユ簮锛�https://dev.to/molly/please-redis-responsively--3gn
PREV
Elasticsearch 扩展第 2 部分:如何加速搜索分组数据过滤器是朋友将 ID 存储为关键字不要让您的用户拖慢您的速度回顾:加快大规模搜索速度提前规划
NEXT
跟上 Codeashians 的步伐