采纳答案成功!
向帮助你的同学说点啥吧!感谢那些助人为乐的人
老师您好, 课程很好, 已经学完了, 回过来做去重有点疑惑. 我理解的去重的本质是是找个容器visitedUrls把访问过的url存起来, 下一个url去看一下这容器里有没有. 那05:30说的worker去调去重, 会不会有多个goroutine并发访问容器visitedUrls? 09:14时说, 把map换成redis, 在多个goroutine中访问, 好像也会有同步的问题? 还有, 05:57说并发版的爬虫各自调自己的去重服务是什么意思, 可以有很多个去重服务?
谢谢同学的支持。
如果让每个worker去调用去重,的确需要处理并发的问题。需要加锁来保护。
把map换成redis的话是不需要处理同步问题的。redis当然能够支持并发访问。只是对于同一个key的值并发访问,我们可能需要在redis层面做一下保护,但是我们去重服务一般会把url或是url的hash作为key,值无关紧要,不存在对同一个key的值并发访问的问题。
还有各自去调去重服务,不一定是多个,一般一个去重服务就够了,所有的worker都可以去调它。
谢谢老师回答, 对于redis不需要处理同步问题还是有点不理解?在goroutine中 { //1.查下redis是否爬取过, 我用redis的set存放 if redis.Do("sismember", "zhenai", reqeust.Url) == 0{ //2.没爬去过, 先写入到redis中 redis.Do("sadd", "zhenai", request.Url) //rpc调用处理 } } 在第2步没写入成功前, 不是也有可能其他goroutine写入同样的url吗? redis层面做保护, 具体怎么做呢?我要先查到了url有没有处理过, 没有再将url添加到redis中, 这两步的原子性怎么保证呢? 麻烦老师指点下!
比较自然的做法是key是url,value是bool,并且只要插入的记录,value都是true。所有的记录插入都是原子性的,就保证了并发安全。 如果我们要考虑namespace,比如zhenai, xcar,最简单的方法就是在key上加上前缀,key=zhenai_http://www.zhenai/..., value=true 如果要使用set也不是不可以,其实只需要用sadd一个命令就行。文档在https://redis.io/commands/sadd 文档里说,sadd会返回到底成功添加了几个元素。所以sadd==1,就说明不存在。可以看一下文档最后的例子
登录后可查看更多问答,登录/注册
语法+分布式爬虫实战 为转型工程师量身打造
3.7k 14
712 1
2.0k 1
1.1k 12