V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐学习书目
Learn Python the Hard Way
Python Sites
PyPI - Python Package Index
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 · 2020-06-29 20:18:58 +08:00 · 4114 次点击
    这是一个创建于 1394 天前的主题,其中的信息可能已经有所发展或是发生改变。

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

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

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

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

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

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