• 在Google App Engine中使用hash和marshal持久化模块,快速判断数据库条目是否已经存在


    由于要取消linode但是ror的监控程序就不能用了,于是想用gae写一个,毕竟本地电脑太不靠谱了,还要一直开着,


    http://blog.csdn.net/egg90/archive/2010/08/16/5816453.aspx


    本人在用GAE写爬虫的时候,遇到判断重复URL来防止重复抓取的问题,但是由于GAE数据库的限制(db.ListProperty每个记录不能 保存超过5000个元素),经测试发现直接筛选数据库中的属性来判断是否有重复链接 会耗费大量CPU时间(甚至有时候会花费0.3秒来判断是否已经抓过某个网页),而利用建立哈希表来解决也没有多少改善.

    经分析,根本问题在于hash颗粒度太小,读取数据库时使用GQL难免会比 (url in list)这样的python内置语句慢.经过查阅相关资料,用memcache可以解决.因为memcache是保存在内存中的,所以它的效率很高,且 不随请求完毕而消亡.但是memcache有1M大小的限制,而且它并不是永久持久化的.可能因为服务器原因而丢失老数据.

    有另一种解决方案就是把hash_list存到一个包装好的raw数据包中,put到数据库,下次使用再展开...于是我找到了marshal模块.它有将python所有内置数据类型和数据结构打包的功能.

    注:另外一个python持久化的模块叫pickle 还有其C的底层实现:cPickle,与marshal模块不同的是,它可以记录自定义模块的数据.且展开时要导入原来的模块,若导入失败会引发一个异常.

    利用python的marshal内置模块构建dump

    1. import marshal  
    2. from google.appengine.ext import db  
    3. # 新建模型  
    4. class Dump(db.Model):  
    5.     dump_str = db.BlobProperty()  
    6. #把dump存入list  
    7. hash_list = []  
    8. for url in urls:  
    9.     hash_list.append(hash(url))  
    10. dump_str = marshal.dumps(hash_list)  
    11. Dump( dump_str = dump_str ).put()  

    以下是判断是否存在url记录的方法:


    1. url = "http://xxx.xxx.xxx/xx"  
    2. dump = Dump.all().get()  
    3. exist = False  
    4. if dump:  
    5.     try:  
    6.         hash_list = marshal.loads(dump.dump_str)  
    7.     except:  
    8.         break        # load error  
    9.     if hash(url) in hash_list:  
    10.         exist = True  
     

    此方法用time测试 每个in 判断的操作需要时间小于0.001s

    hash的list空间占用还是很小的,以每个数据记录为2M,每个hash数位64位(8字节)整形,打包不浪费空间,这样计算的话,能记录2*1024^3 /8 = 268435456 条hash数据

    等空间不够时,还可以用zlib压缩一下,经过测试可以变成大小的1/3到1/4 ,证明marshal打包后 压缩空间还是蛮大的 毕竟全部是hash数组成的list 

    再多的数据便要有更多的Dump项来实现了.

    但是这个方法也不是很高效,因为每次还要抓一下数据库或者这个包,希望懂GAE的大侠指正或建议.

  • 相关阅读:
    常用Linux 服务器命令--各种性能指标命令
    jenkins离线插件安装--笨方法
    Jmeter压力测试简单教程(包括服务器状态监控)
    【JMeter】JMeter使用plugins插件进行服务器性能监控
    Linux查看服务器配置常用
    Linux下内存查看命令
    【linux命令】lscpu、etc/cpuinfo详解
    Jmeter用于接口测试中【接口耦合关联的实现】
    jmeter教程--简单的做压力测试
    将字母拆分
  • 原文地址:https://www.cnblogs.com/lexus/p/2061114.html
Copyright © 2020-2023  润新知