V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
V2EX 提问指南
kkfnui
V2EX  ›  问与答

Python 缓存库, LRU, max, timeout

  •  
  •   kkfnui · 2017-12-14 09:59:17 +08:00 · 3124 次点击
    这是一个创建于 2527 天前的主题,其中的信息可能已经有所发展或是发生改变。

    服务性能出现瓶颈,有些逻辑需要多次进行 reids 访问。 虽然每次 redis 访问时间较短,但是总体下来网络开销还是吃不消。

    现在明确的解决方案是使用 进程内的缓存 来解决。调研了几个现有的 缓存 库,都不太满足需求。

    1. repoze/repoze.lru,看文档应该是不支持 timeout
    2. jlhutch/pylru,也是不支持 timeout
    3. stucchio/Python-LRU-cache, 支持 timeout, 但是实践发现装饰器不能用在成员函数上

    不知道 python 中是否有个缓存组件能够同时支持:

    1. 对类成员函数使用装饰器
    2. LRU (提升内存使用效率
    3. max (防止内存使用过多)
    4. timeout 设置(缓存涉及黑名单,必须要定时从 redis 内重新加载)

    如果没有,就只能自己在基于上面的几个缓存组件修改。

    16 条回复    2018-11-13 11:41:00 +08:00
    kkfnui
        1
    kkfnui  
    OP
       2017-12-14 10:01:42 +08:00
    需要功能是和 java guava 库中的 LoadingCache 一样的
    cabing
        2
    cabing  
       2017-12-14 10:07:28 +08:00   ❤️ 1
    搭个本机的缓存应该就符合你的要求了吧?
    比如本机的 redis。或者用 leveldb 在本机重复造个轮子。
    kkfnui
        3
    kkfnui  
    OP
       2017-12-14 10:12:12 +08:00
    @cabing 现在访问的 redis 就是本机的 redis
    cabing
        4
    cabing  
       2017-12-14 10:27:08 +08:00
    性能瓶颈是网络 io ?
    如果磁盘 io 低的话,可以使用基于文件的 nosql。

    1 如果时间不着急可以自己造轮子啊

    2 如果比较急
    或者看看能不能找个共享内存的库,你的四点基于轮子去做.
    cabing
        5
    cabing  
       2017-12-14 10:28:08 +08:00   ❤️ 1
    抱歉啊,实在是不是特别了解 python。只能提供一点点思路,希望能帮到你哦~
    kkfnui
        6
    kkfnui  
    OP
       2017-12-14 10:35:51 +08:00
    @cabing 多谢。

    业务逻辑决定了要多次访问 redis。
    redis 现在内存量级对应我们的硬件来说是比较大的,慢查询也会出现十几毫秒的情况。

    现在是短平快的解决思路
    billion
        7
    billion  
       2017-12-14 10:38:44 +08:00   ❤️ 1
    你的这个网络开销,是从 redis 传数据回来的时间,还是 redis 读取的时间?如果是前者,使用异步模型可解。
    cabing
        8
    cabing  
       2017-12-14 10:42:12 +08:00   ❤️ 1
    @kkfnui
    思路一 如果只是内存问题的话,建议看看走磁盘的 nosql。做成一个服务,通过 socket 调用,自己封装下就行

    思路二 python 开源库,找一个比较原始的能够实现多进程共享内存的组件,其他的业务逻辑可以自己封装。

    思路三 用 c 重复造个轮子。短平快你是不用考虑了~
    mooncakejs
        9
    mooncakejs  
       2017-12-14 10:42:16 +08:00   ❤️ 1
    也找不到合适的,最后自己写了一个,发现其实代码没多少行。
    VYSE
        10
    VYSE  
       2017-12-14 10:47:12 +08:00   ❤️ 1
    自己用 PYLRU 改过,选其他一些不成熟实现遇到过坑,比如某用 C 实现 LRU 说自己很快然后 crash 一堆
    Kilerd
        11
    Kilerd  
       2017-12-14 12:01:13 +08:00   ❤️ 1
    from functools import lru_cache
    kkfnui
        12
    kkfnui  
    OP
       2017-12-14 13:17:47 +08:00
    @billion
    异步模型成本更高

    1. 需要修改现在业务逻辑,时间成本高
    2. 复杂度、心智负担都会提高

    不是万不得已,一般的业务逻辑还是不要采用异步模型
    kkfnui
        13
    kkfnui  
    OP
       2017-12-14 13:18:26 +08:00
    @Kilerd 这个不支持 timeout 吧
    kkfnui
        14
    kkfnui  
    OP
       2017-12-14 13:18:48 +08:00
    @mooncakejs 恩,还是自己写了一个。
    Kilerd
        15
    Kilerd  
       2017-12-14 13:59:06 +08:00
    @kkfnui 那就自己实现一个咯。

    异步处理起来实在是太舒服了,前提是架构合理的情况下。
    Buffer2Disk
        16
    Buffer2Disk  
       2018-11-13 11:41:00 +08:00
    @kkfnui
    最近也在研究这一块,可以讨论讨论,网上找了一个支持 timeout 的 lru_cache , 是基于 python 官方的 orderedDict 实现的,
    测试后发现,orderedDict 貌似有内存泄漏的问题 ---> https://stackoverflow.com/a/46935255/2379891
    不知道你后来是怎么解决的?
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1046 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 33ms · UTC 22:10 · PVG 06:10 · LAX 14:10 · JFK 17:10
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.