automattic/sliding-window-counter

滑动窗口计数器

0.3 2023-06-21 08:44 UTC

This package is auto-updated.

Last update: 2024-09-18 10:13:44 UTC


README

composer install automattic/sliding-window-counter

这是关于什么的?

我们需要一种方法来拥有任意短暂的时间序列。例如,为了解决消息垃圾邮件问题,我们想知道来自特定IP地址范围的用户发送的统计上可疑消息的数量是否超过了之前观察到的数量。

我们可以使用由日志或数据库条目构建的时间序列来解决这个问题。这需要首先有一个日志或数据库,更不用说计算每个请求所需的统计数据可能会很昂贵。我们可以使用缓存来支持计算,但为什么不一开始就使用内存缓存呢?这正是我们在这里追求的。

首先,我们需要解决问题的输入端。为此,我们将时间分成相等的块,并记录落在匹配时间段内的事件。我们还需要在缓存键中包含观测期间和窗口大小,以确保我们不会意外地重复使用来自另一个时间序列的数字。这很简单。

稍微复杂一些的是将一切组合起来。让我们就以下术语达成一致

  • 帧是窗口长度的时间段。
  • **材料帧**是与缓存中存储的数据相匹配的帧,直到最后一秒。
  • **逻辑帧**是与当前时间对齐的窗口长度帧,但不一定与缓存数据对齐。

如果当前时间与材料帧边界对齐,那么一切都很直接。拿出缓存中的内容,魔术般地出现!

Logical Frames Aligned

但如果逻辑帧和材料帧没有对齐(最后一个材料帧的结束可能在二十秒前,而逻辑帧始终是现在),我们就需要进行一些外推。

Logical Frames Not Aligned

并且存在许多边缘情况:例如,如果我们没有指定异常检测的开始时间,我们将丢弃所有前置空值。但对于相对罕见的事件,可能有必要保留每个空帧,因此有一个选项可以指定开始时间。

API

以下是使用方法

// Configure a counter to work in hourly buckets, for the last 24 hours
// and using the Memcached adapter.
$counter = new \Automattic\SlidingWindowCounter\SlidingWindowCounter(
    'my-counters',
    3600,
    3600 * 24,
    new \Automattic\SlidingWindowCounter\Cache\MemcachedAdapter($memcached)
);

// Increment the counter when a certain event happens.
$counter->increment($_SERVER['REMOTE_ADDR']);

并在某个稍后时间点

// Try to detect an anomaly.
$anomaly_result = $counter->detectAnomaly($_SERVER['REMOTE_ADDR']);
if ($anomaly_result->isAnomaly()) {
    // Inspect the result using the toArray() method.
    $anomaly_result->toArray();

    // Or individual accessors.
    $anomaly_result->getMean();
    $anomaly_result->getStandardDeviation();
    // ...
}

// And explore the historic variance...
$variance = $counter->getHistoricVariance($_SERVER['REMOTE_ADDR']);
// ...using various accessors.
$variance->getCount();
$variance->getMean();
$variance->getStandardDeviation();

还有一个用于Memcached支持的WP_Object_Cache的便利适配器

$counter = new \Automattic\SlidingWindowCounter\SlidingWindowCounter(
    'my-counters',
    3600,
    3600 * 24,
    new \Automattic\SlidingWindowCounter\Cache\WPCacheAdapter($wp_object_cache)
);