和zheng的聊天记录-关于搜索引擎(2)

zheng 说:
 
  搜索引擎-重新开始 说:
 
  搜索引擎-重新开始 说:
刚吃饱
zheng 说:
MSN 是不是不能 截图啊
  搜索引擎-重新开始 说:
不能,不过你可以捷了发给我,
  搜索引擎-重新开始 说:
什么咚咚啊
zheng 说:
没 问一下 呵~
zheng 说:
看你的 BLOG  好多都没接触的……
  搜索引擎-重新开始 说:
呵呵,不过msn才像是聊天的东西,qq还复杂
  搜索引擎-重新开始 说:
唉,好多东西都没有望上写,
zheng 发送:
 
  打开(Alt+P)
 
  您成功地从 zheng 处接收了 C:\Documents and Settings\Administrator\My Documents\我接收到的文件\Drawing4.jpg。
 
  搜索引擎-重新开始 说:
好的开始
zheng 说:
整体模型~
zheng 说:
不过是个单机的~ 哈
zheng 说:
没加入分发URL~ (分布式)
  搜索引擎-重新开始 说:
先别考虑分布式,太乱
  搜索引擎-重新开始 说:
url数据库管理是什么意思?
zheng 说:
自己写的那个 键树 数据结构相当于 一个 URL 数据库啊
  搜索引擎-重新开始 说:

zheng 说:
数据库管理就是提供操作接口 哈
  搜索引擎-重新开始 说:
呵呵,内存缓冲区怎么设置?
  搜索引擎-重新开始 说:
写io的线程和spider应该是是没有关系的
zheng 说:
写 IO 的线程必须和 页面分析的线程 是一个啊~
  搜索引擎-重新开始 说:
why
zheng 说:
因为他们是 信息耦合 哈~ 
都是对 页面数据的操作
zheng 说:
如果在分线程 就不太好了
  搜索引擎-重新开始 说:
不对吧,spider的任务只是从页面抓取html,先放到内存中,提取url。
  搜索引擎-重新开始 说:
然后缓存中的数据怎么保存就是io线程去考虑的事情了,
  搜索引擎-重新开始 说:
责任不同吧
zheng 说:
我也知道这个。如果这样的话,可能会让下载 和 URL 提取成为串行的~ (等下,我画给你看,我觉得这样会产生一个缺点)
  搜索引擎-重新开始 说:
不要一起发来,书写时间不要操过1分钟
zheng 说:
OK~
zheng 说:
ha
  搜索引擎-重新开始 说:

  搜索引擎-重新开始 说:
最好补充说明一下下载是什么意思?
zheng 说:
下载页面~
zheng 说:
下载 URL 对应的页面
  搜索引擎-重新开始 说:
漏了,职责划分的一下。下载,url提取,保存都是三种独立的任务
  搜索引擎-重新开始 说:
spider-parser-saver
zheng 发送:
 
  打开(Alt+P)
 
  您成功地从 zheng 处接收了 C:\Documents and Settings\Administrator\My Documents\我接收到的文件\Drawing4(1).jpg。
 
zheng 说:
恩 知道
zheng 说:
不过那个是每个子线程序 要完成的~
zheng 说:
如果再把各个子线程 页面数据 的处理合并到一个线程 那么 又得增加互斥操作…………
  搜索引擎-重新开始 说:
为什么要合并成一个线程?
zheng 说:
不是这个意思,我说的是 子线程所负责的事情
zheng 说:
有一个可能是这样
zheng 说:
你在看那图吧?
  搜索引擎-重新开始 说:

  搜索引擎-重新开始 说:
你说说有神么问题
zheng 说:
一个实现是:
zheng 说:
把左下角的两个流程
  搜索引擎-重新开始 说:
嗯?
zheng 说:
作为多个下载子线程共享的部分
zheng 说:
这样划分明确
zheng 说:
就是结构清晰
zheng 说:
但是 得增加互斥 的开销~
zheng 说:
就是把IO 部分完全脱离了~
  搜索引擎-重新开始 说:
左--
zheng 说:
就是让 页面缓冲区 在多个下载线程中共享
zheng 说:
不管哪个子线程下载了页面都往那里仍~
  搜索引擎-重新开始 说:
对我现在想把 页面抓取-url提取-io保存之间分离
  搜索引擎-重新开始 说:
想法一样
zheng 说:
这个有缺点………………
  搜索引擎-重新开始 说:
 ,你先说,我给你画个图
zheng 说:
zheng 说:
缺点就是:  如果某个线程在往缓冲区中写入页面数据时,其他的下载线程只有等待。…… 我们应该尽量减少互斥的使用,要不多线的效果会下降很多……
zheng 说:
而我认为 应该让每个子线程负责整个过程~
  搜索引擎-重新开始 说:
我现在也是一个想法,给你发过去
zheng 说:
OK
  搜索引擎-重新开始 发送:

  搜索引擎-重新开始 说:
画的太急,我一条一条给你说明
 
  传输“Snap1.jpg”完成。
 
  搜索引擎-重新开始 说:
Spider从url队列中获取一定数量的链接抓取网页,保存到PageBuffer中,
zheng 说:
知道~
zheng 说:
你的我明白
  搜索引擎-重新开始 说:
那么读写PageBuffer的互斥逻辑就比较麻烦了
zheng 说:
所以……
  搜索引擎-重新开始 说:
Parser专门负责提取链接,过滤链接,可以设定一组过滤逻辑,实现站内搜索
zheng 说:
我以前也这样分~
zheng 说:
把 parser  分出来……
  搜索引擎-重新开始 说:
然后
zheng 说:
等下 我回忆一下……
 
您发送了一个闪屏振动!
 
zheng 说:
 
zheng 说:
其实 就是让 parser 在 spiderController 里调用~
zheng 说:

  搜索引擎-重新开始 说:
不是,Parser自己负责监视Buffer
  搜索引擎-重新开始 说:
Writer也是
zheng 说:
就是说 是一个 parser 线程~ 一个 writer 线程
zheng 说:
监视 buffer ~
  搜索引擎-重新开始 说:
不是啊,writer和Parser各自独立的,不知道彼此是否存在的
zheng 说:
其实先别想那么细吧~
  搜索引擎-重新开始 说:
嗯?
zheng 说:
光从流程来说
zheng 说:
没~ OK  就一个 parser 线程~ 一个 writer 线程
也行~
  搜索引擎-重新开始 说:
当然可以
zheng 说:
问题就在于 pagebuffer 的互斥 上了~ 想个办法 把他搞了
  搜索引擎-重新开始 说:
那就要考虑一下PageBuffer的管理方法和互斥逻辑
zheng 说:
再加一层……
  搜索引擎-重新开始 说:
首先,PageBuffer大小是有限的,要考虑管理方法,
  搜索引擎-重新开始 说:
什么层?
zheng 说:
你的 pagebuffer 就相当于 管理器了~
zheng 说:
提供接口读取~
zheng 说:
我说的是那个位置~
  搜索引擎-重新开始 说:
对啊,对一块内存的管理,提供接口读取和写入,然后再接口里面做互斥是吧?
zheng 说:
恩~
zheng 说:
在他 和 spider 键再加一个
  搜索引擎-重新开始 说:
妙,小子厉害。互斥算法要好好想想,我对这里的实现就不是很熟了
zheng 说:
呵呵 郁闷 有其他开销的说……
zheng 说:
我刚才的想法是这样~ (比较一下)
  搜索引擎-重新开始 说:
好,其他开销是什么
zheng 说:
我是说我刚才想的 解决互斥问题的 新的开销
zheng 说:
我刚才的想法:
zheng 说:
在每个 spider 中再加一个 预buffer。
然后spider 子线程不用互斥的往 Pagebuffer 里写数据, 让pagebuffer_manager 开启监视线程序,监视各个spider 的数据,达到一定数据,就锁定
zheng 说:
取到自己的总的 pagebuffer 中
zheng 说:
缺点是 :
zheng 说:
预保存了一次……
  搜索引擎-重新开始 说:
pageBuffer和spider只有写入的关系,而且让pagebuffer_manager去监视spider,也很麻烦啊
zheng 说:
非常麻烦~
  搜索引擎-重新开始 说:
你比较过吗?抓网页的时间和写io的时间哪个比较长?
zheng 说:
但是你想一下现在的模型
  搜索引擎-重新开始 说:
对于同一个页面
  搜索引擎-重新开始 说:
应该是抓网页的时间比较长吧
zheng 说:
如果10个线程都抓完了页面,并多要写入到 pagebuffer 中,
zheng 说:
那就只能一个等一个 等一个 ……
  搜索引擎-重新开始 说:
你比较过吗?抓网页的时间和写io的时间哪个比较长?

  搜索引擎-重新开始 说:
对于同一个页面

zheng 说:
应该是抓的时间长
  搜索引擎-重新开始 说:
好,我也是这样想的,那么writer基本上就是在等spider
zheng 说:
那也不能说明什么问题……
zheng 说:
我不是说这个……
zheng 说:
我说的是 spider  和 pagebuffer 的写入导致频繁等待……
zheng 说:
虽然每次等待的时间很小,但是等待的次数会非常多
  搜索引擎-重新开始 说:
好好,先把这个问题解决了。
zheng 说:
如果上面的问题解决了 那下面的 writer  没有问题……
  搜索引擎-重新开始 说:
以前是怎么做的
  搜索引擎-重新开始 说:
对于抓取回来的页面的处理
zheng 说:
以前是这样 ( spider pagebuffer )
  搜索引擎-重新开始 说:
那就不需要同步了
  搜索引擎-重新开始 说:
互斥
zheng 说:
组合成一个子线程(其实我刚才一直说子下载线程 并不是说,该线程只负责下载)
  搜索引擎-重新开始 说:
url提取呢?
zheng 说:
不过那样模型 感觉肯定不如这个清晰~
zheng 说:
 这是以前模型( spider -> pagebuffer -> url_parser )

  搜索引擎-重新开始 说:
pagebuffer对于每个线程是独占的吗?
zheng 说:
这样 url_parser  占用了 spider 的时间(同步)
zheng 说:
分别拥有各自的
zheng 说:
所以我的改进方法是~
zheng 说:
其实 也就是你那个图~ 晕……
zheng 说:
只不过 是把左边的 都放到子线程里
zheng 说:
再在子线程里 增加 各个监视线程……
zheng 说:
如果 第2层线程 个数 为 10 那么总共可能创建的线程个数 大致为
zheng 说:
20 + 10
  搜索引擎-重新开始 说:
不明白,第二层线程?
zheng 说:
就是从 controller 创建的线程个数
zheng 说:
详细的说是这样:
  搜索引擎-重新开始 说:
ft,好,说得清楚写
zheng 说:
假设 controller 创建了 10 个线程,其中某一个为 Ti
  搜索引擎-重新开始 说:
come one
zheng 说:
 Ti 中首先从 url_list 中读取URL
然后下载,把下载的页面数据保存到此线程对应的 pagebuffer 中,同时 Ti 又创建了两个子
zheng 说:
线程序 writer_thread and parser_thread 用于监视 pagebuffer
zheng 说:
这样 下载页面 和 parser and writer 就异步了
zheng 说:
这是 Ti 其他同理 (每个Ti有2个孙子(嘿嘿)线程 因此总共)
zheng 说:
创建的就是 10+10*2 个
  搜索引擎-重新开始 说:
知道你的意思
zheng 说:
哈 应该不算多吧~
  搜索引擎-重新开始 说:
不过模型你给我整个改了
zheng 说:
你觉得最多创建多少个线程?
zheng 说:
会导致系统 KO
  搜索引擎-重新开始 说:
小波说他以前都是1000个线程的,
  搜索引擎-重新开始 说:
统计一下吧:因为writer操作时间比spider的操作时间要短
zheng 说:
那就无所谓了 对吧 通过增加线程~ 来解决问题
  搜索引擎-重新开始 说:
而parser的时间应该是最短的
zheng 说:
反正他们已经异步了啊~ 
zheng 说:
短是一回事~
zheng 说:
如果同步的话
zheng 说:
在下载完后 还要 parser  writer 虽然短
zheng 说:
但是 这样的操作会用 NNNNN 次
  搜索引擎-重新开始 说:
所以线程的数量理想应该是:spider最多,writer次之,parser最少。这样创建的线程数量就可以尽量少。这是理想化的
zheng 说:
不是啊 ~ 我是2层的线程 把 (spider,writer ,parsre )都完成啊~ 换句话说 
zheng 说:
每个2层的线层 都必须有一个 writer/parsre moniter thread
zheng 说:
要不 又回到一开始那个 要考虑 互斥的 问题了
  搜索引擎-重新开始 说:
了解,但是,可能出现这样的情况吗, window的线程调度如果出现这样的情况呢: spider第二次获取到页面数据时,writer还没开始写
  搜索引擎-重新开始 说:
第一次的页面数据
zheng 说:
……
zheng 说:
那个是缓冲 pagebuffer
  搜索引擎-重新开始 说:
又要同步了
zheng 说:

zheng 说:
对啊~ 但是我这个是缓冲,就是说下载后可以放到 buffer 中,达到某个级别后,writer 监视到,锁定,才写……
zheng 说:
这里的操作和你发给我的那个 writer -> pagebuffer 的关系是一样的 
  搜索引擎-重新开始 说:
嗯,等等,我整理一下
zheng 说:
他解决的问题是下载的页面不用频繁的互斥才能写入 pagebuffer (你发给我的,就会产生这个问题,多个spider 往一个 buffer 写)
  搜索引擎-重新开始 说:
我想到办法了~~~~
  搜索引擎-重新开始 说:
等等。
  搜索引擎-重新开始 说:
这样的,我们可以参考操作系统申请临界资源的办法
  搜索引擎-重新开始 说:
比如说我们的pagebuffer分层10个缓冲块
  搜索引擎-重新开始 说:
现在有5个spider线程,3个writer线层,2个parser线程。
  搜索引擎-重新开始 说:
先等我写完,你先别打断
  搜索引擎-重新开始 说:
现在有一个spider要开始工作,那么他先到pagebuffer申请缓冲块,如果有可用的缓冲块,那么该缓冲块标记为已经分配,然后这个spider开始抓取网页,并且把内容保存到申请的缓冲块中,同时缓冲块的bWritten和bParsed设为false,
  搜索引擎-重新开始 说:
然后把缓冲块放回PageBuffer
  搜索引擎-重新开始 说:
然后分配标记置为未分配。可用缓冲块的定义是:标记为尚未分配,且bWritten和bParsed都为true
  搜索引擎-重新开始 说:
但是,
zheng 说:
写完留到 QQ 上 我回去了, 关门。 川要回去!  你再想一下 我刚才说的那个……!!  让 pagebuffer 分层,或者让每个2层线层维护一个 pagebuffer~。 再说了 pagebuffer 现在可不象标记一下那么简单。他是要保存页面数据,如果分层,那么就要考虑如何控制BUFFER 的大小,以及没层的大小,相当于又要进行随机会文件读取管理了…… 并且还要相斥(你分层了难道不是对同一BUFFER 读写吗?)
zheng 说:
 
zheng 说:
明天再说 ~ continue!
  搜索引擎-重新开始 说:
好,如果没有可用的缓冲块,那么该Spider被转移到PageBuffer的等待队列,仅当发现
zheng 说:
yeah
  搜索引擎-重新开始 说:
好玩
 
  无法将以下消息发送给所有接收者:
好玩



聊得正high,azheng要回去了,真是重色轻友....

总结一下我最后的想法:

可以参考操作系统申请临界资源的办法。比如说我们的pagebuffer分层10个缓冲块,现在有5个spider线程,3个writer线层,2个parser线程。

现在有一个spider要开始工作,那么他先到pagebuffer申请缓冲块,
(1)如果有可用的缓冲块(可用缓冲块的定义是:标记为尚未分配,且bWritten和bParsed都为true),那么该缓冲块标记为已经分配,然后这个spider开始抓取网页,并且把内容保存到申请的缓冲块中,同时缓冲块的bWritten和bParsed设为false,然后Spider把缓冲块放回PageBuffer,然后缓冲块分配标记置为未分配。
(2)如果没有可用的缓冲块,那么该Spider被转移到PageBuffer的等待队列,当PageBuffer监视线程发现PageBuffer中存在可用的缓冲块时,取出等待队列中的第一个Spider,分配缓冲块,然后Spider开始工作,情况如(1)中描述。(不学习minix的notify all了)

parser和writer线程监视PageBuffer中的待parse和write的缓冲块,操作后至相应的标志为为真。

这样,同步和互斥的问题就好处理多了。

 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值