python dict key expire_Python dict 设置键值过期时间

问题背景

使用滑动窗口解决接口限流问题时需要统计连续时间内的请求数,可以用 Redis 对请求的信息设置过期时间,进而统计滑动窗口内的请求数,对阈值范围内的请求提供服务。但目前服务规模较小,且不需要 Redis 的大部分功能,不必要引入对 Redis 资源的依赖,因此基于 Python 字典实现 Redis TTL 功能

功能实现

学习 Redis 的实现,将 EXPIRE 提供的 key 的生命时间转化为 key 应过期时的 Unix Timestamp。在查询时检查 key 的过期时间,必要时进行清除操作

功能函数

1、 expire(key, ttl, now=None) 对指定的键设置生命时间,now是相对的起始时间 Unix Timestamp,默认是当前

2、 ttl(key, now=None) 返回剩余的生命时间

3、 setex(key, value, ttl) 赋值同时设置生命时间

4、 支持 dict 其他操作,例如 len(dict), dict[key], dict[key] = value, iter(dict), del dict[key]

用法

实现方向

主要考虑了下面几个实现方法:

1、 学习 collections.DefaultDict 等,继承 dict 并重写部分类方法,出于性能优化的原因,dict 中部分方法并不是直接调用魔法方法实现,例如 update(), setdefault() 并不是直接调用 __setitem__进行存储,所以如果使用 dict 还需要重写 update() 等函数。DefaultDict 直接继承 dict 是因为它只增加了 __missing__的处理,并不影响核心功能

2、 继承抽象类 MutableMapping,实现必要的魔法方法(__init__, __len__, __iter__, __setitem__, __delitem__, __getitem__),通过 duck typing 实现字典功能

3、 继承封装了 MutableMapping 的 UserDict 类,数据通过 UserDict 的 data 对象存储

实现过程

实际采用了第3中方法: 继承 UserDict,并在 UserDict 的 data 对象中存储 (过期时间 timestamp, value) 的元组

1、 expire 实现::将 data 中的值设置为 (过期时间 timestamp, value),过期时间通过当前时间+生命时间计算得出

2、 ttl 实现:返回指定 key 剩余的生命时间,已过期的返回 -2 并将其删除,没有设置过期时间的返回 -1

3、 setex 实现:

4、 iter 实现:遍历所有数据,使用生成器返回没有过期的值

5、 对象存取:存储 key, value 时默认将过期时间设置为 None,读取时先检查过期时间,如果没有过期会正常返回 value,否则会触发 KeyError

完整代码

最后还加上了并发控制

参考

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值