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

本人在用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

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


 

此方法用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的大侠指正或建议.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值