Zoie
时间:2011-05-03 来源:mandela
--------------------------------------
Unsolved Problems
1. 实时模式下类RealtimeIndexDataLoader里面消化函数consume调用RAMLuceneIndexDataLoader
写内存索引这个逻辑块和刷磁盘两个逻辑块-[a. RAM-A关闭写,开RAM-B来写 | b. 将RAM-A合并到磁盘]
是互斥同步的,其实应该consume和逻辑块a写索引切换同步就可以了,源码里面是和a&b同步的
这样的效果是些索引必须要等到合并完成
--------------------------------------
Zoie Logic
1. 在逻辑上来看zoie系统每一个DOC必须有个字段UID,在批量提交DOC时会先把UID取出来,处理逻辑是
a. 如当前RAM-A的IndexWriter没关则关闭,为打开RAM-A非只读模式IndexReader让出writer.lock
b. 以非只读模式打开RAM-A -> IndexReader,同时获取RAM-A上和提交UID重复的那些,这些UID都是经过
其底层的ZoieSegementReader过滤了的,然后用MAPPER将UID转变成DOCID,用IndexReader
deleteDocument提交删除这些DOC,然后关闭IndexReader。[对于RAM-A没有标记删除一说,它都是直接
写到索引里面]
c. IndexWriter打开RAM-A,提交新增的DOC,再commit
d. 拿批量提交的UID去标记磁盘索引和RAM-B,如果它存在的话,从a-d这些步骤里用户线程来拿READER
由于RAM-A没有做refresh则拿到的READER和步骤a之前拿到的是一样的,磁盘索引和RAM-B虽然标记删除
部分过期DOCID,由于没有commit故拿READER.setDeleteDocs时这些标记是不可见的
e. 进行RAM-A的refresh操作,在进行磁盘索引和RAM-B标记删除的commit操作,这些操作和SearchIndexManager
里获取READER是互斥同步的,即获取READER只能在这个原子操作之前或者之后,在进行这个操作之后
拿READER,则RAM-A里新提交的DOC则可见了,磁盘索引和RAM-B里面包含新提交DOC过期的则被过滤掉了
保证数据的一致性
2. zoie的层次消费
a. 经过ZoieSystem提交的EVENT都缓冲起来,其会起一个线程来到缓冲区去取EVENT给下层消费
这样下层的消费数据限制住了上层提交EVENT的速度
b. 由ZoieSystem转发过来的EVENT经过RealtimeIndexDataLoader层时会给RAM-A去写索引,同时在
RealtimeIndexDataLoader也会起一个周期刷磁盘的线程,这个线程和ZoieSystem层的那个线程在某段
逻辑处必须同步,因为在进行RAM-INDEX切换时会关闭当前可写RAM,而ZoieSystem层线程是往当前
可写RAM写索引,故这两块逻辑需要同步。刷磁盘的线程在进行完RAM切换后则需要将当前只读RAM合并
到磁盘上
c. FLUSH到磁盘前后Searcher的READER视角变化
[1]. 当需要刷磁盘时会先NEW一个新的内存索引管理器RAM-B,然后关闭当前RAM-A的IndexWriter,构建新的
Mem,让新建的RAM-B作为可写的暴露出去,RAM-A做为只读的暴露,再这个操作前用户线程来拿READER
只会拿到磁盘的READER和RAM-A的READER,在这个操作后可以拿到RAM-B的READER[这时还没有数据],在
这个切割过程中是不能进行DOC写入的
[2]. 切换完成后DOC写进RAM-B,可能过期的UID都标记到RAM-A和磁盘的READER上,保持数据的一致性上面
提到过;切换完成后会进行索引合并的操作
[3]. 索引合并时细节
1. 关闭磁盘索引的IndexWriter,如果打开了的话
2. 当前磁盘保持的过期UID-_delDocs经MAPPER到DOCID
3. 以非只读模式获取磁盘索引的IndexReader,经deleteDocument提交过期的DOCID,再关闭这个IndexReader
4. 磁盘管理器的_delDocs清空,在IndexWriter打开磁盘索引,合并RAM-A的索引目录
5. 在1-4步骤期间用户线程来获取READER得到的结果和步骤1之前获取的是一样,RAM-A都没refresh,更值得
注意的是磁盘的READER不是通过磁盘索引管理器来拿的,而是在Mem实例化时从磁盘管理器拿到READER后
就一直是这个,即使这时候磁盘索引管理器refresh了,其提供的READER可返回RAM-A的DOC,但是Mem持有
的磁盘索引READER是没有变的
过期DOCID的过滤是在READER层做的,在索引管理层保持一份的目的就在于此
6. 磁盘索引管理器refresh获取到新的INDEX-READER,再拿RAM-A持有的过期UID标记下这个新的磁盘索引READER
因为RAM-A的DOC都写到磁盘去了,需要过滤掉这些过期的 -> mark -> commit
7. RAM-A资源的释放 - 通过磁盘索引管理器获取到最新的磁盘索引READER,构造新的Mem[RAM-B, null, RAM-B,
null, 新的磁盘索引READER],切换Mem。在做这个切换前后用户线程来拿READER变化很大,在切换前拿三个READER
RAM-A RAM-A[DOCS] & RAM-A[DELETE-UID]
RAM-B RAM-B[DOCS]
DISK-O DISK-O[DOCS] & DISK-O[DELETE-UID]
----------------
RAM-B RAM-B[DOCS]
DISK-O DISK-O[DOCS-DELETE-UID] | RAM-A[DOCS] & RAM-A[DELETE-UID] -> DISK-N[DOCS] & RAM-A[DELETE-UID]
--------------------------------------