您的位置:首页 > 其它

分布式微博爬虫运行中出现的问题及解决方法(持续更新)

2015-12-19 22:58 876 查看
9.2016/3/31 对mongodb进行模糊查询是效率低的解决办法

当对mongodb使用正则表达式查询时,普通的正序和倒序索引已经无效,因为待搜索的pattern不是从字符串开头开始的。好在mongodb提供了文档索引的功能,官方文档参见这里,至于python的实现,可以这么写

collec.create_index([('dealed_text.left_content',pymongo.TEXT)])


这行代码的意思就是对域为dealed_text.left_content的项建立文档索引。经过测试,建立文档索引以后,模糊查询的时间从10分钟以上下降到5秒钟,可以说是效果显著

8. 2016/3/19 对MySQL和MongoDB进行批量更新。

对于mysql和mongo,如果只是批量插入的话都可以非常简单的实现。而如果是要进行批量修改的话,就要费一番周折,尤其是mysql。

对于MySQL,需要借助case语句。简单的说,就是

update TableName set ColName case KEY
when KEY1 then VALUE1
when KEY2 then VALUE2
...
when KEYN then VALUEN
end
where KEY in (KEY1,KEY2,...,KEYN)


其中TableName指表名,ColName指列名,KEY表示case语句的依据值,而value则是指不同需要修改的不同Key对应的值。

值得注意的是,如果 where KEY in (KEY1,KEY2,…,KEYN) 括号中的KEY值范围比 CASE-END语句中KEY范围要大,那么多出来的KEY值对应的VALUE会被设为空。这点要谨记。

打个比方,如果

update TABLE set COL case KEY
when 1 then 2
when 3 then 4
when 5 then 6
end
where KEY in (1,3,5,6)


那么在执行的时候,KEY=1,3,5的地方COL值会被更改为2,4,6,但是KEY=6的地方COL值被改为空。

MongoDB批量操作方法。

mongodb相对来讲要简单一些,需要使用bulk_write功能(pymongo)具体参考这里

7. 2016/3/12 数据量增大导致存储困难,查询及其困难以及由此导致的服务器不稳定的问题

爬取用户微博的部分完成以后,数据开始大量增加,平均每天新增30~40G内容。几天下来,就有上百G了。

由于一开始是把所有数据放在一张表里,从而导致读取和插入速度非常的慢,由此也导致服务器频繁宕机。

为了解决这个问题,主要有如下措施:

1.将数据分表。一般来讲,历史数据的使用频率是不太高的,所以,首先可以将这些数据按照时间来分表。我这边是按照月份来分表的,每个月的数据放在一张表里。这样一来的话,微博从09年10月到现在大概78个月,预计总的数据量大概在2.5T~3T,那么平均每张表的容量大概在30G左右。相对于现在180G一张表的容量来讲,算是很不错了

2.使用MongDB的数据分片功能。通过数据分片,可以将一个collection中的内容分散到多个文件夹中。指定要分类所依据的键值后,mongo就会自动安排分类了。我打算按照用户id来分类。这样,上面2个措施就成功的将数据分成了2个维度,分别是时间和用户。如果分成10个片的话,大概一个片的容量是3G左右。这样就很可观了。

MongoDB分片指南

3.使用Nginx来进行反向代理,分流数据服务器的请求,提高数据服务器的响应速度

NGINX的使用方法

6. 2016/2/29 传输较大数据时导致服务器堵塞的问题

在获取用户微博的阶段,发现服务器(tornado)在运行一定时间以后,客户端会连接不上服务器。虽然目前还不知道具体原因是什么,但是在去掉回传数据的功能以后,服务器就能稳定运行了。

所以,我估计爬虫出问题的原因是,客户端在获取到目标用户的微博以后,在把数据传输回主机的过程中,由于数据量太大,会造成服务器堵塞,从而使得服务器瘫痪的情况。目前的情况是一条微博大概3K大小,那么如果一个用户有1W条微博,那么就需要传输30M的数据。如果有3W条微博,就需要传输90M数据。很有可能是在将这么大的数据一次性传输给服务器的过程中导致服务器瘫痪

那么,对应的可能的解决方法,主要有两个,一是使用云存储,将数据存入云主机,二是将数据分成小段,分开传输,最后再由服务器拼接起来。

——————3.9更新—————-

问题已解决。解决方案是,将整个数据打散,拆分成许多小的http包,分批多次传送给服务器。服务器接收完所有包以后,再组装起来,放入数据库。此外,将写入数据库的操作放到一个单独的线程中去,不再在收到客户端的请求之后由服务器来完成,从而加快了服务器的响应速度

5.2016/1/16 MySQL写入速度慢的问题

之前为了结局磁盘读写的瓶颈问题,使用redis作为缓存。然而随着数据的增多,渐渐地单纯的写入操作也越来越慢。现在的表中大概2500W行左右的数据,但是每次存储都会占用大量的时间,以至于影响到了服务器的响应速度。为了解决这个问题,我修改了一些参数,扩大了数据库的缓存,显著加快了写入速度。

主要修改了

innodb_buffer_pool_size ,

innodb_log_file_size ,

innodb_log_buffer_size ,

innodb_flush_log_at_trx_commit 这几个参数,具体见这里

4. 2015/12/21 redis经常奔溃的问题

看报错信息好像是持久化的时候出错。由于我并不需要redis中的数据持久化,只是想作为缓存,因此我选择关闭持久化。

关闭redis持久化的方法:

修改redis配置文件,redis.conf 第115行左右。

1.注释掉原来的持久化规则

#save 900 1
#save 300 10
#save 60 10000


2.设置为空

save ""


然后重启redis服务

——————12.23更新—————-

之前选择的关闭持久化好像并没有什么卵用,依旧有时候会奔溃。看来问题不是出在持久化上面。再仔细看了看报错信息,大致意思好像是数据过大,以至于win系统的内存中无法提供相对于的连续空间heap来存放。由于这里redis是用来存放bloomfilter的数组的,因此我推测可能是因为数组过长导致的。之前的长度是 2^25 bit ,我改成2^15 bit 。由于目前数据量不大,这一修改对错误率没什么影响。到现在为止,已经运行了大概20小时。后续如何还有待观察,不过比起之前的6~7小时崩溃一次已改进不少

—————–12.29更新—————–

缩短了数组长度之后还是会报错。后来发现一个奇怪的现象,我的内存是8G*2,但是在使用内存超过8G的时候redis在写入的时候必定会崩溃,具体原因不明。不过我依照这篇文章在运行时关闭持久化以后,可以顺利运行

即在redis-cli中,输入config set save “”即可

3. 2015/12/17 待爬取列表行数太多查询变慢

每次获取任务都需要从待爬取列表中获取信息,但是当行数较多的时候会导致查询速率变慢

解决方案:

大致想了想,我能想到的主要有以下几种方案:

1.在redis里面设立缓存,批量从mysql读取数据,然后分发给各个客户端

2.将数据存入多个表里面

3.将待爬取的用户按照粉丝数从大到小排序,当行数过多的时候去除掉粉丝数较少的一些用户

4.为经常要查询的列设立索引

目前用的是第三种方案

2. 2015/12/15 已爬数据的查重问题

详细描述:

对于获取到的页面,需要判断出页面中的链接是否已经查询过。如果是,则不必再次爬取。如果不是,则加入待爬取列表。那么相应出现的一个问题就是,如果对于每个链接都要去mysql查询是否存在,会占用磁盘大量读取性能。甚至于可能会影响到其他功能的正常使用。

解决方案:

考虑到这些大部分都是查询功能,因此可以把查询功能放在内存解决。也就是说,不需要再到磁盘去查询,这样就能把磁盘的性能解放出来。如此一来,就需要一个内存数据库,把放在数据内存中。我这里选用的是redis 。

当数据量比较小时,可以把所有数据都放入内存中。好处是可以保存所有的信息,坏处则是不能存储太大的数据,对于超过内存大小的数据就无能为力了。那么此时就需要BloomFilter,通过多个hash函数,能够将字符串映射到不同的位上面。当有新的待查询字符串到来时,只需要查询相关bit位上的值,就能够判断该字符串之前是否出现过。这样就解决了大量数据的查询问题。但是相应的缺点则是,有一定的可能会出错,且只能查询,不能从内存数据库中还原出完整的原始信息

相关资料:redis官网 相关指令 BloomFiler介绍

我的具体解决过程

1. 2015/12/12 宿舍建站的相关问题

在宿舍的电脑上跑服务端程序的时候,发现从外网无法连接到该服务器;而如果换个位置,即阿里云上跑服务端程序,则可以从宿舍连上。查询了一下发现是DNS问题,由于自己宿舍里面用的是电信的校园网,再加上用的路由器是特制的,掩码是255.255.255.255,导致外网无法连接上宿舍内的程序。

对应的解决方案则是,需要一个DDNS(动态域名服务)。 我这用的是花生壳(感觉好贵,然而也没什么其他好办法)安装好之后,开通域名映射功能即可。要注意的是花生壳不太稳定,有时候断网以后需要重新映射一下
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: