首页   注册   登录
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐学习书目
Learn Python the Hard Way
Python 学习手册
Python Cookbook
Python 基础教程
Python Sites
PyPI - Python Package Index
http://www.simple-is-better.com/
http://diveintopython.org/toc/index.html
Pocoo
值得关注的项目
PyPy
Celery
Jinja2
Read the Docs
gevent
pyenv
virtualenv
Stackless Python
Beautiful Soup
结巴中文分词
Green Unicorn
Sentry
Shovel
Pyflakes
pytest
Python 编程
pep8 Checker
Styles
PEP 8
Google Python Style Guide
Code Style from The Hitchhiker's Guide
Te11UA
V2EX  ›  Python

请问静态资源取走后删除怎么做性能最高,代码最简洁呢

  •  
  •   Te11UA · 11 天前 · 2498 次点击

    首先说一下是 Python 技术栈,现在需求是有大量的文件不断生成在一个目录下(文件几 k 到几百 k 不等,同期数量约 20W ),想做一个服务,使得其它服务来请求的时候能快速地取走该文件,并在取走后删除。

    当然,最简单的做法就是 Tornado/Flask 直接写个接口,然后 os.remove 就行,想问下大伙儿还有什么高效率的方法来实现吗?

    第 1 条附言  ·  11 天前
    统一回复一下各位大佬:
    其实当前不存在有性能瓶颈,我只是想问下有没有更加快速、更加清晰的做法而已,感谢各位的认真讨论~
    38 条回复    2020-06-30 17:47:40 +08:00
    gwy15
        1
    gwy15   11 天前
    zero-copy (sendfile)?
    ipwx
        2
    ipwx   11 天前
    redis
    optional
        3
    optional   11 天前
    这样性能并不高啊,包括生成大量文件与删除。
    删除是强需求吗,是一定只能取一次,还是过一段时间取不到就好?
    chenqh
        4
    chenqh   11 天前
    流程没懂
    Te11UA
        5
    Te11UA   11 天前
    @optional 删除是强需求,但不要求立即删。正是性能不高才想问问呢
    @gwy15 学习了,我试试~
    @ipwx 不太清楚怎么做会好点儿,能再具体说说不?
    Te11UA
        6
    Te11UA   11 天前
    @chenqh 提供一个接口,让其它的服务来取该目录下的文件,取完文件后删除。删除不要求即时
    optional
        7
    optional   11 天前
    @Te11UA 不要求立即删除,就放不同文件夹,比如每个小时一个文件夹,然后定时半小时删除之前的文件夹就好了。
    Te11UA
        8
    Te11UA   11 天前 via Android
    @optional 不可以,未取走的不能被删除:(
    jugelizi
        9
    jugelizi   11 天前 via iPhone
    效率?嫌删除动作慢?改成异步任务呗
    vevlins
        10
    vevlins   11 天前
    不删除直接覆盖写?瞎说一下
    netnr
        11
    netnr   11 天前
    重命名文件夹,mv folder folder.del
    再删除 *.del 文件夹
    makdon
        12
    makdon   11 天前
    要不换成 SSD ?如果是自己的物理服务器,可以搞 nvme 的,或者组个 raid,应该会更快
    等等首先现在你的瓶颈在哪里...是定位到了线程池里面大部分线程都在等 os.remove 吗(个人感觉应该是读文件的成本远远高于删文件吧)
    如果不是的话...不要提前优化

    我想到的这些:
    1. 如果业务上面可以实现的话,在请求到的时候再生成文件,不落硬盘直接发送
    2. 按照文件名之类的唯一键,hash 到多台服务器上面处理
    3. 只能单机的话,可以调研一下有没有适合这个场景的文件系统...
    billlee
        13
    billlee   11 天前
    别想太多,才 20 万文件而已,只要你不去遍历目录,现代文件系统处理起来不会有问题
    realpg
        14
    realpg   11 天前
    想要高性能,直接写个简单的文件系统。
    计算机科班专业的大佬应该都会,如果上学时候做过相关的作业,估计两三天就能解决这个问题。
    发生一次读取内容之后直接标记这个文件的区域释放。
    realpg
        15
    realpg   11 天前
    而且 20 万这个级别,一个文件不超过 1MB,这种存储的 IOPS 只要高一点,连瓶颈都不会发生啊……
    文件系统只要是个稍微现代点的文件系统即可。
    不知道你那边用的啥服务器,基础架构层优化一下就完事了。

    如果基础架构层没法优化,还想绕开删除慢这个坑,那就用完的改名,加前缀,然后当系统 io 不密集时进行限定写负载的删除
    Vegetable
        16
    Vegetable   11 天前
    文件需要鉴权?一定要 python 来处理文件?有点蛇。其实直接 remove 并没有什么性能问题,同步 web 框架控制好流程就行,性能瓶颈不在删除这里。异步的话可以用 redis 之类的把取走的文件标记一下,定时删除就好了。
    gstqc
        17
    gstqc   11 天前 via Android
    nginx 提供静态访问,瓶颈就是网络带宽
    访问记录输出日志,Python 定时读取日志批量删除
    SlipStupig
        18
    SlipStupig   11 天前
    Redis 直接使用队列就好了啊。。
    hurrytospring
        19
    hurrytospring   11 天前
    不要求立即删的话搞个表标记一下删除就行了。。真正删除的时候再搞个定时任务拉表批量删掉完事
    jedihy
        20
    jedihy   11 天前 via iPhone
    @gwy15 zerocopy 可以删除?
    jedihy
        21
    jedihy   11 天前 via iPhone
    19 楼的方案应该是最简单高效的了。
    em70
        22
    em70   11 天前
    瓶颈到底在哪里? 最简单方法先实现跑起来再谈优化啊
    GTim
        23
    GTim   11 天前
    一种不知道可不可行的方案是使用 nginx-lua 中的 `log_by_lua` 在这个脚本文件里删除,我没试验过,不知道可不可行
    dbolo123
        24
    dbolo123   11 天前 via Android
    直接 nginx 返回,每天跑个脚本分析是 access log,删掉文件就好?
    yaleyu
        25
    yaleyu   11 天前
    @hurrytospring 赞同这个方案,空闲时候比如半夜再删除
    enjoyCoding
        26
    enjoyCoding   11 天前
    两个服务 一个取 取完了通知另一个删除
    删除放一个标志位或者存到一个数组里面 一个一个删除
    说到底还是异步
    encro
        27
    encro   11 天前
    写都没问题,删还会成问题了?所以为什么不取的时候同时删除呢?

    或者取的时候写入队列,通过 crontab 或者 supervisord 脚本任何时候想删就删。
    lychs1998
        28
    lychs1998   11 天前
    既然这样读写删除性能差,那么为什么要生成文件呢……看上去就是消息队列一样的功能……
    xjmroot
        29
    xjmroot   11 天前
    如果是用 Nginx 做代理,访问文件时会有 Nginx 日志,将日志入到 kafka
    写个 kafka 消费者消费 Nginx 日志删除文件
    Te11UA
        30
    Te11UA   11 天前
    @SlipStupig @lychs1998 因为内存少昂,你的意思是将文件内容缓存到消息队列是吗 ?
    @realpg @billlee 的确不是什么大问题,性能也可以接受,我只是想问下还有什么方式可以去做~当然,这也可能是我过早优化了
    crclz
        31
    crclz   11 天前
    20w 个文件还是直接用数据库好了,让生产者把文件放数据库里面。传统的关系型数据库都行。
    Huelse
        32
    Huelse   10 天前
    既然时先取后删,建议还是延时删除吧,还可以避开访问高峰
    SlipStupig
        33
    SlipStupig   10 天前
    @Te11UA 是的啊,队列不是在不停消费嘛,不会占用太多,如果怕占用大,可以压缩后再存
    VictorJing94
        34
    VictorJing94   10 天前
    取走后给文件加标识?定期统一处理?
    est
        35
    est   10 天前
    高效的方法是建立个删除队列。用一个后台进程慢慢删。
    009694
        36
    009694   10 天前
    celery 异步删除
    SjwNo1
        37
    SjwNo1   10 天前
    消息队列或者 19 楼的做法都行
    no1xsyzy
        38
    no1xsyzy   10 天前
    一致性的要求?是否完整地取走才能被删?取一半对方 RST 了怎么办?取一半 Python 线程 / 进程挂了怎么办?
    是否要确认对方确实完全收到?是否要求对方无误地收到?
    关于   ·   FAQ   ·   API   ·   我们的愿景   ·   广告投放   ·   感谢   ·   实用小工具   ·   2443 人在线   最高记录 5168   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 22ms · UTC 01:44 · PVG 09:44 · LAX 18:44 · JFK 21:44
    ♥ Do have faith in what you're doing.