An open API service indexing awesome lists of open source software.

https://github.com/realaravinth/redis-leaky-bucket

Redis module that implements leaky bucket algorithm
https://github.com/realaravinth/redis-leaky-bucket

counter leaky-bucket redis redis-cluster redis-module rust

Last synced: 10 days ago
JSON representation

Redis module that implements leaky bucket algorithm

Awesome Lists containing this project

README

        


Redis Leaky Bucket




Redis module that implements
leaky bucket algorithm

[![CI Linux)](https://github.com/realaravinth/redis-leaky-bucket/actions/workflows/linux.yml/badge.svg)](https://github.com/realaravinth/redis-leaky-bucket/actions/workflows/linux.yml)
[![AGPL License](https://img.shields.io/badge/license-AGPL-blue.svg?style=flat-square)](http://www.gnu.org/licenses/agpl-3.0)
[![dependency status](https://deps.rs/repo/github/realaravinth/redis-leaky-bucket/status.svg)](https://deps.rs/repo/github/realaravinth/redis-leaky-bucket)

**NOTE:** This repository was moved from
[mCaptcha/cache](https://github.com/mCaptcha/cache) to here.

## Features

- [x] Timers for individual count
- [x] Clustering
- [x] Persistence through RDB
- [ ] Persistence through AOF

## Motivation

[mCaptcha](https://github.com/mCaptcha/mCaptcha) uses a [leaky-
bucket](https://en.wikipedia.org/wiki/Leaky_bucket)-enabled counter to
keep track of traffic/challenge requests.

- At `t=0`(where `t` is time), if someone is visiting an mCaptcha-protected website, the
counter for that website will be initialized and set to 1.

- It should also automatically decrement(by 1) after a certain period, say
`t=cooldown`. I call this cool down period and is constant for a
website.

- If at `t=x`(where `x
```

## Get counter value

```redis
LBUCKET.GET
```

## Benchmark

**NOTE:** These benchmarks are for reference only. Do not depend upon
them too much. When in doubt, please craft and run benchmarks that are
better suited to your workload.

To run benchmarks locally, launch Redis server with module loaded and:

```bash
$ ./scripts/bench.sh
```

- platform: `Intel core i7-9750h`

```bash
running set and get without pipelining
SET: 125046.89 requests per second, p50=0.199 msec
GET: 124502.00 requests per second, p50=0.199 msec

mCaptcha cache without piplining
MCAPTCHA_CACHE.COUNT mycounter 45: 124828.37 requests per second, p50=0.215 msec

running set and get with pipelining
SET: 1353179.88 requests per second, p50=0.487 msec
GET: 1633987.00 requests per second, p50=0.383 msec

mCaptcha cache with piplining
MCAPTCHA_CACHE.COUNT mycounter 45: 385653.69 requests per second, p50=1.959 msec
```

## Hacks

I couldn't find any ways to persist timers to disk(`RDB`/`AOF`). So I'm
using a dummy record(`lbucket:timer:*` see [Gotchas](#gotchas)) which
will expire after an arbitrary time(see `BUCKET_EXPIRY_OFFSET` in
[`lib.rs`](./src/lib.rs)). When that expiry occurs, I derive the key of
the bucket from the values that are passed to expiration event handlers
and perform clean up of both the bucket and counters registered with the
bucket.

Ideally, I should be able to persist timers but I couldn't find ways to
do that.