distlimiter

Distributed Limiter based on Redis


Install
pip install distlimiter==0.1.1

Documentation

DistLimiter 分布式限流器

distlimiter是一个分布式限流器,基于Redis

特性

  • 分布式,基于redis
  • 支持平滑限流,说好100qps则就是0.01秒执行一次
  • 基于redis的lua引擎,超过每秒10w次throttle请求会极大影响redis的常规性能

安装

pip install distlimiter

使用方法

import time
import random
import threading
from statistics import mean, stdev
from distlimiter import throttle

starttimes = []


@throttle('add0',
          rate_per_second=100,
          method='smooth',
          redis_url='redis://localhost')
def add(a: int, b: int) -> int:
    starttimes.append(time.time())
    time.sleep(random.random() / 5)
    return a + b


tasks = []
for _ in range(11):
    t = threading.Thread(target=add, args=(1, 2), daemon=True)
    t.start()
    tasks.append(t)

for t in tasks:
    t.join()

intervals = [
    starttimes[i] - starttimes[i - 1] for i in range(1, len(starttimes))
]
print(intervals)
print(mean(intervals), stdev(intervals))
# [0.009971857070922852, 0.012664794921875, 0.007295131683349609, 0.01067209243774414, 0.009412765502929688, 0.013530254364013672, 0.0070078372955322266, 0.01360011100769043, 0.005474090576171875, 0.01084280014038086]
# 0.010047173500061036 0.002804029576649581

Why?

分布式部署分布式任务的时候,比如用celery时,经常会发生任务限流不准的情况。

这是因为celery使用的限流方式比较不稳定,会产生大量的波峰波谷,有时对服务器造成了不必要的压力。

所以需要一个稳定平滑的,支持分布式系统的限流器。

实现原理

现有的限流算法大部分基于两种模式:令牌桶或者漏桶。无论哪种方式,运用在分布式环境下,都需要有个单独进程不断发放令牌,然后各个任务执行者去抢令牌。

这个模式依赖一个令牌产生器,从来又不够优雅,又不够scalable

distlimiter使用另一种方式,直接把限流管理放在redis里面,用lua脚本来执行。由于lua脚本执行的高效率和原子性,很好地保证了限流调度的有效性,配合throttle装饰器即可直接实现精确限流。