美文网首页程序员的星期天
聊一聊Python ExpiringDict

聊一聊Python ExpiringDict

作者: 逆小苍 | 来源:发表于2020-08-15 11:41 被阅读0次

    缘起

    最近工作中,涉及到接口优化,无奈时间紧,要优化的地方很多,无法每个接口都详尽梳理其业务逻辑;由于业务场景对数据的实时性要求不高,且无个性化参数,即每个用户请求返回结果都一样;如此,就可以想办法短时间内缓存逻辑处理的结果,这样接下来的时间内,后续的请求就很快得到响应;若想实现缓存,自然想到redis,如果数据量很大,redis确实不错,无非是多了一次交互,相对于之前的每次都要复杂逻辑处理,确实快了很多;但如果数据量比较少,是否可以把结果放到内存里呢,设置一个过期时间;这样就少了一次redis的交互,时间更短;于是查阅资料,发现了一个三方库 expiringdict

    始惊

    expiringdict实现了一个有序字典类,支持设置过期时间max_age_seconds,以及字典大小max_len;适用于缓存目的的自动过期值字典;支持python 2python 3,其源码仅仅250行,通俗易懂,值得一看;

    安装方式
    • 命令行安装:
    pip install expiringdict
    
    • 源码安装:
    git clone https://github.com/mailgun/expiringdict.git
    cd expiringdict
    python setup.py install
    
    • 简单使用:
    >> from expiringdict import ExpiringDict
    >> test_dict =ExpiringDict(max_len=10, max_age_seconds=100)
    >> test_dict[1]="a"; test_dict[2]="b"; test_dict[3]="c"
    >> test_dict
    Out: ExpiringDict([(1, 'a'), (2, 'b'), (3, 'c')])
    
    >>  test_dict.ttl(1)
    Out: 41.763437032699585
    
    >> test_dict.items_with_timestamp()
    Out:  [(1, ('a', 1597461000.321023)),
           (2, ('b', 1597461000.321065)),
           (3, ('c', 1597461000.321101))]
    
    

    次醉

    ExpiringDict该类继承了OrderedDict,数据的存储为:key : (value, timestamp) 其过期机制的实现,属于消极过期机制,即当一个key到期后,该类并不会主动清理掉,而是等到下一次这个key被访问到的时候,检查其过期与否,如果其过期,就清理掉。

    常用方法

    pop(self, key, default=None)
    获取指定key对应的value,并将其从字段中移除

    ttl(self, key)
    返回指定key剩余过期时间,单位s,如果key过期或不存在,返回 None

    get(self, key, default=None, with_age=False)
    返回key对应的value, key不存在返回默认值,with_age为true时返回一个元组,第一个值为value,第二个值为该key已经存在的时间

    items_with_timestamp(self)
    返回字典(key, value, timestamp)三元组列表的副本

    终迷

    了解其用法后,只需在handler类中初始化一个过期字典,缓存接口返回结果即可

    ...
    from expiringdict import ExpiringDict
    
    @route("/api/test/info")
    class InfoHandler(RequestHandler):
        cache = ExpiringDict(max_len=10, max_age_seconds=60)
    
        def get(self):
            if 'info' in self.cache:
                return self.cache['info']
            result = self.get_info_result() # 原有获取result逻辑
            self.cache['info'] = result
            return result
    

    如此,就可以在不修改大量代码的情况下,短时间内迅速提高接口性能

    相关文章

      网友评论

        本文标题:聊一聊Python ExpiringDict

        本文链接:https://www.haomeiwen.com/subject/vxtadktx.html