这个想法由来已久,由于全文索引本身的缓存设计,使得其io操作要小于数据库对于频繁读取的操作全文索引绝对有可能在性能上超越数据库(至少能轻松秒杀mysql,mysql那超低的io性能如果不改那肯定是要被sqlserver给灭掉的,只是时间问题)但当你深入这个问题的时候就会有很多问题出现,我最初的需求是利用这个记录搜索关键字进而得到关键字hot排名。问题出现了:
1 IndexerWriter有个特性如果不close始终有部分内容会写不入索引,也就是它的缓冲机制,这是非常致命的,由于在实际应用中,这种写入是多线程的,当你在需要的时候close下以获得更新的时候,那么很可能使得某个写入线程出错,这是非常糟糕的,虽然我们不要求lucene达到acid的水准,但是经常报错是非常有问题的。
2 接着1的问题,同样在reader端需要频繁读入新内容,这可能会造成很大的性能问题,虽然在2.3中已经有了reopen方法,但我尝试过效率绝对没有官方宣称的如此高效,源代码我也看过的确不是那么高效的在我已经优化过的环境里,并没有获得很巨大的优势。
那么现在来看看解决的方法:
首先可以考虑是否使用ram作为临时存储地,不管如何,在ram上close和reopen都要比fs要高速得多,当然这个代价就是无法很大,虽然现在我的生产环境已经是16g内存的机器×2但我依然无法保证能够无限满足需求,有一天满了怎么办?到时候哭都来不及。
第二,考虑在fs上使用多索引,然后merge到主索引的方法,这样我可以利用线程限制极大保证fs上不会在close状态下被写入,close方法上有一个参数 是否等待merge完成,只要在线程模式下,是可以保证得到期望结果的,偶尔io不行的时候也就是偶尔出错一次不会产生太多问题。
好了,上述的方法还没有得到验证,尤其是线程模式下环境是很复杂的,而lucene又要求严格的线程安全,因此大量的实验室少不了的。
其实在我的理想中希望做一套lucene的服务,能够完全兼容于jdbc,这样可以实现服务的从db到全文的0切换,毕竟在like下lucene的效率之高使得数据库系统完全被秒杀。当然进而还有很多问题,比如表和表的关系,在lucene中怎么对应,这是后话,待我想想再来说,先去试验多线程安全模式下的写入。
1 IndexerWriter有个特性如果不close始终有部分内容会写不入索引,也就是它的缓冲机制,这是非常致命的,由于在实际应用中,这种写入是多线程的,当你在需要的时候close下以获得更新的时候,那么很可能使得某个写入线程出错,这是非常糟糕的,虽然我们不要求lucene达到acid的水准,但是经常报错是非常有问题的。
2 接着1的问题,同样在reader端需要频繁读入新内容,这可能会造成很大的性能问题,虽然在2.3中已经有了reopen方法,但我尝试过效率绝对没有官方宣称的如此高效,源代码我也看过的确不是那么高效的在我已经优化过的环境里,并没有获得很巨大的优势。
那么现在来看看解决的方法:
首先可以考虑是否使用ram作为临时存储地,不管如何,在ram上close和reopen都要比fs要高速得多,当然这个代价就是无法很大,虽然现在我的生产环境已经是16g内存的机器×2但我依然无法保证能够无限满足需求,有一天满了怎么办?到时候哭都来不及。
第二,考虑在fs上使用多索引,然后merge到主索引的方法,这样我可以利用线程限制极大保证fs上不会在close状态下被写入,close方法上有一个参数 是否等待merge完成,只要在线程模式下,是可以保证得到期望结果的,偶尔io不行的时候也就是偶尔出错一次不会产生太多问题。
好了,上述的方法还没有得到验证,尤其是线程模式下环境是很复杂的,而lucene又要求严格的线程安全,因此大量的实验室少不了的。
其实在我的理想中希望做一套lucene的服务,能够完全兼容于jdbc,这样可以实现服务的从db到全文的0切换,毕竟在like下lucene的效率之高使得数据库系统完全被秒杀。当然进而还有很多问题,比如表和表的关系,在lucene中怎么对应,这是后话,待我想想再来说,先去试验多线程安全模式下的写入。