来个 PHP shell 自动执行的思路 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
colordog
V2EX    PHP

来个 PHP shell 自动执行的思路

  •  
  •   colordog 2017-05-30 22:08:19 +08:00 4464 次点击
    这是一个创建于 3060 天前的主题,其中的信息可能已经有所发展或是发生改变。

    场景是这样的,有一个商城,预估用户数为 10w+,客户要求每月 1 日,计算每个用户上个月的消费总额和消费笔数,然后根据这 2 个数值,自动给用户升降级,同时需要写入升降级记录以便用户查询;

    问题,写一个 php 程序,如果一次 foreach 出来 10w 个数据,再循环查询、插入,效率感觉很低,服务器基本要垮掉,而浏览器我记得可以一次处理一部分,然后跳转再执行下一部分,跟分页似的,可是用 shell 行么?不行吧,使用 sleep 让 php 等待不知道是不是可以希望大家给个思路。

    26 条回复    2017-07-06 13:53:23 +08:00
    shmilyin
        1
    shmilyin  
       2017-05-30 22:13:42 +08:00 via iPhone
    php cli
    cnlongxi
        2
    cnlongxi  
       2017-05-30 22:21:29 +08:00 via iPhone
    PHP 一次执行 100 条,没计算完就用 PHP 执行 exec 继续
    shoaly
        3
    shoaly  
       2017-05-30 22:26:18 +08:00
    放到 crond 里面去执行: 执行思路:
    1 每次取 100 个用户, 计算积分, 并且缓存该积分, 然后记录本次计算的时间戳
    2 注意取的时候要 where 出 当前时间减去上一次更新时间>阈值的数据

    基于上面 2 个点, 就可以无限去运行 crond 了, 既不会重复计算, 也不会因为某一次计算量太大而卡住, 即便是卡住了, 也可以"断点续传"的接着上次 bug 掉的地方继续处理
    colordog
        4
    colordog  
    OP
       2017-05-30 22:32:00 +08:00
    @shmilyin 以前稍微弄过一点,不太熟悉,还是不太了解一次性处理大量数据的方法。
    colordog
        5
    colordog  
    OP
       2017-05-30 22:32:17 +08:00
    @cnlongxi 这个方法好像可以诶,谢谢
    colordog
        6
    colordog  
    OP
       2017-05-30 22:32:31 +08:00
    @shoaly 看着好复杂的样子,不过看起来貌似可以
    sagaxu
        7
    sagaxu  
       2017-05-30 22:35:59 +08:00
    10 万是很小的量,放心 foreach 吧
    rekulas
        8
    rekulas  
       2017-05-30 22:38:22 +08:00
    10w+的数据量 PHP 的性能完全能胜任,如果慢很可能是卡在数据库相关操作上,检查你的语句即可
    hiboshi
        9
    hiboshi  
       2017-05-30 22:45:02 +08:00
    既然是写脚本不需要考虑浏览器,超时。直接 php-cli 即可。
    hiboshi
        10
    hiboshi  
       2017-05-30 22:45:26 +08:00
    @hiboshi > php run.php
    doctorlai
        11
    doctorlai  
       2017-05-30 23:00:43 +08:00
    每次从数据库里取 1000 条,执行,结束。
    加入 crontab 每几分钟执行一次
    coolyujiyu
        12
    coolyujiyu  
       2017-05-30 23:02:49 +08:00
    任务分片、多线程处理。
    dangyuluo
        13
    dangyuluo  
       2017-05-30 23:04:26 +08:00
    同时从数据库内取 10000 条,然后处理完成后,组成一条长 MySQL update 语句,这样执行很快。
    Fishdrowned
        14
    Fishdrowned  
       2017-05-30 23:34:14 +08:00 via Android
    我来说三个点
    1、如果你要遍历所有用户,你可以写成两层循环,外层 while(读 1000 条),内层 foreach (刚才读到的 1000 条);
    2、在 sql 里就可以筛选掉大部分记录。升级比较容易处理,降级再加一个条件,因为最低级别是不会再降级的,所以不用处理最低级的用户;
    3、每月 1 号执行配置一下 crontab 就可以了,具体怎么配置,搜索一下。
    cxbig
        15
    cxbig  
       2017-05-31 07:26:39 +08:00 via Android
    用户总有自增 ID 的吧?怕读多了锁表或吃太多内存,每次取 100 个来计算不就好了? SQL 不是有 LIMIT 分页么。
    azh7138m
        16
    azh7138m  
       2017-05-31 07:56:03 +08:00 via Android
    @Fishdrowned 最低级用户可以升级的吧
    zhs227
        17
    zhs227  
       2017-05-31 08:26:46 +08:00
    如果数据不会因为后续的更新而导致 sql 变化,可以把要执行的 sql 都统一生成到一个文件里,前后加上事务执行开始和结束。然后使用 mysqladmin 导进去。
    Fishdrowned
        18
    Fishdrowned  
       2017-05-31 08:57:19 +08:00 via Android
    @azh7138m 升级和降级是分开处理的
    klgd
        19
    klgd  
       2017-05-31 08:57:28 +08:00
    没有消费的用户也要处理吗? 如果不处理的话,就反过来,先查出上月消费数据,根据这些数据来处理用户升降级,这样要处理的数据会少很多(每月不可能 10W 用户都有消费的)
    sarices
        20
    sarices  
       2017-05-31 09:07:11 +08:00
    分开取出或者一次性取出,10W 不多,但是看你取出会不会有慢查询了,然后放到队列跑
    harborM
        21
    harborM  
       2017-05-31 09:42:04 +08:00
    想必计算用户的上月总额和笔数不会在每月一日执行,每月一日前的工作是取出已经叠加的聚合数值执行升降级工作,那么可以用一条语句直接 update,担心性能的话可以用 crontab + limit 分段工作;
    gouchaoer
        22
    gouchaoer  
       2017-05-31 17:01:45 +08:00
    php-cli 部署很麻烦的,10w 的数据量就用 php-fpm 就 ok 了,至于怕 cron 超时的话超过一定时间之后可以自己触发新的 php 请求。。。。
    mengdodo
        23
    mengdodo  
       2017-05-31 17:37:49 +08:00
    phpredis
    mingyun
        24
    mingyun  
       2017-05-31 22:11:13 +08:00
    cli 每次取 1000 获取最后一个 id 然后第二次从 这个 id 开始,依次循环
    baoguok
        25
    baoguok  
       2017-06-02 11:55:29 +08:00
    php xx.php

    用多线程处理,10 万,也就几分钟的事情
    zhengwenk
        26
    zhengwenk  
       2017-07-06 13:53:23 +08:00
    才 10w 用户 你开一个 php 脚本 放后台跑,一伙都跑完了吧
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     1493 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 26ms UTC 16:40 PVG 00:40 LAX 09:40 JFK 12:40
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86