V2EX = way to explore
V2EX 是一个关于分享和探索的地方
Sign Up Now
For Existing Member  Sign In
DAOCLOUD
推荐学习书目
Python Cookbook
Using Google App Engine
推荐下载
Latest Google App Engine SDK
其他兼容技术
AppScale
darasion

讨论:关于批量清理数据。

  •  
  •   darasion · Dec 19, 2010 · 4547 views
    This topic created in 5620 days ago, the information mentioned may be changed or developed.
    经常遇到这样的事情:
    有很多很多实体,有些实体保存的内容是有效的,有些是无效的。
    现在要将那些无效的实体清理掉。

    我暂时考虑到如下几点:
    1、要判断一个实体是否有效,需要一番计算。
    2、从 datastore 获取实体不能超过一定数量,太多了也会造成麻烦。
    3、考虑到实体有很多,不可能在一次请求中完成有效性判断,会超时。


    所以,要把取实体的工作和判断实体有效性的工作都分成很多次进行。

    ==设想:
    实现的时候,利用 taskqueue 这个东西。

    把任务分成两个 Handler ,一个 FetchHandler 用于从 datastore 取得实体;另一个 CleanUpHandler 于判断每个实体的有效性并完成清理。

    运行的时候,首先调用 FetchHandler ,取得从 datastore 里边取得一定数量的实体,并获得当前 query 的游标(cursor),然后将每个实体 key 作为参数通过 CleanUpHandler 加入 taskqueue ,最后将 cursor 作为参数通过 FetchHandler 加入 taskqueue 。

    这样,通过先加入 taskqueue 的每个 CleanUpHandler 将每个 key 所代表的实体清理完成后,又通过后加入 taskqueue 的 FetchHandler 根据之前提供的 cursor 取得新一批实体并加入 taskqueue,然后再用新的 cursor 作为参数将 FetchHandler 加入 taskqueue。 这样周而复始,直至 cursor 为空。


    ==实测:
    我用 Twitdao 测试了几次,感觉还能用。

    Twitdao 目前大概保存了400多个 access tokens。
    每个 access token 必须通过 urlfetch 调用 twitter api 的 account/verify_credentials 方法根据返回的状态判断有效性。而众所周知 urlfetch 效率是非常低的。

    实际运行发现,FetchHandler 每次取得大约 60 个实体左右的时候,后台 log 有时会出现叹号,说这个请求需要一点优化;FetchHandler 每次取得大约 40-50 个实体的时候,后台 log 的叹号会减少或消失。

    所有 400 多个实体清理完成大约需要几十秒左右(没测,只是后台观察taskqueue的变化),一眨眼就没了,很快。


    ==缺点:
    1、taskqueue 限量很少(好像是10万次调用),如果实体很多很多,太容易超限了。我只测试了几次就用掉了1%。
    2、跟所有递归迭代的东西一样,必须注意那个退出的条件,稍不注意肯定就会无限自我调用而耗尽资源。
    3、CleanUpHandler 只负责清理一个实体,任务有些太轻了,看来需要考虑一次请求清理若干实体才好。
    4、。。。
    5、...
    8 replies    1970-01-01 08:00:00 +08:00
    julia
        1
    julia  
       Dec 19, 2010
    学习
    jeeson
        2
    jeeson  
       Dec 19, 2010
    加上时间戳,最后的验证/使用时间,多少时间内的不需要再次验证,这样可以减少验证数量

    否则,如果你的数据够多,短时间内突发访问,对方(twitter)的服务器要遭殃。万一对方来不及5秒-10秒内响应(URLFetch timeout),你的队列会堵塞、重试

    就token数据而言,需要专门验证有效性吗?我觉得使用时发现无效做标志或者清除就好。也可能我没明白
    darasion
        3
    darasion  
    OP
       Dec 19, 2010
    @jeeson 如果使用时验证,响应可能会很慢。

    urlfetch 相对别的服务特别慢。比访问datastore数据似乎要慢很多。所以我认为使用时应尽量减少使用时访问 twitter api 的次数。

    另外全世界访问 twitter api 的应用那么多,一定不会在乎我这一个小小的应用,如果真的因为我造成twitter服务器遭殃,那我就太荣幸了。呵呵。

    再说,任务队列是可以通过 queue.yaml 调整执行频度的,GAE限制死了,不必担心什么太多突发请求。每次入队的任务数量也可以通过 FetchHandler 来调整每次取出实体的数量来限制,这样队列中总能保持有限数量的任务而不会冒漾。

    触发批量清理过程,可以设置cron来找个没人访问的时候进行,或者自己手动也可以。
    jeeson
        4
    jeeson  
       Dec 19, 2010
    @darasion 我不确定是否理解你的意思

    如果是OAuth,除非用户取消了授权,否则会一直有效。而如果无效,访问的时候,会得到一个401 Unauthorized的错误,把这个token做无效标识就好

    URLFetch 是远程请求,当然很慢 :)
    darasion
        5
    darasion  
    OP
       Dec 19, 2010
    @jeeson 光是判断 401 不行。

    因为如果一个用户 protect 了它自己的推。而持有 token 的用户并没有通过这个用户的验证,那么这个这个持有token的用户用他的 token 访问 statuses/user_timeline 的时候仍然会返回 401 。即便这token是有效的。

    所以并不是只有当 token 无效时返回才返回 401 。
    jorakura
        6
    jorakura  
       Dec 20, 2010
    > 1、taskqueue 限量很少(好像是10万次调用),如果实体很多很多,太容易超限了。我只测试了几次就用掉了1%。

    我这边显示:20,000,000
    darasion
        7
    darasion  
    OP
       Dec 20, 2010
    @jorakura 您那是:Billing Enabled Quota ,我说的是Free Quota
    Livid
        8
    Livid  
    MOD
    PRO
       Dec 21, 2010
    MapReduce。

    V2EX 用来清理数据的办法,源代码里有。
    About   ·   Help   ·   Advertise   ·   Blog   ·   API   ·   FAQ   ·   Solana   ·   2971 Online   Highest 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 45ms · UTC 06:33 · PVG 14:33 · LAX 23:33 · JFK 02:33
    ♥ Do have faith in what you're doing.