开发者学堂课程【Lucene知识精讲与实战(下):Lucene优化(解决大量磁盘IO问题)】学习笔记,与课程紧密联系,让用户快速学习知识。
课程地址:https://developer.aliyun.com/learning/course/701/detail/12353
Lucene优化(解决大量磁盘IO问题)
一、解决大量磁盘IO问题
1、lucene 优化属于 lucene 中高级的优化概念,lucene 在创建索引时速度快还是慢,搜索时速度快还是慢,从两部分思考问题,利用磁盘 io 问题解决索引和查询速度。从代码层面可以控制磁盘 io,从硬件入手也可以控制,假如是机械硬盘,分转速大小,400转,7200转,12000转,服务器用的都是12000的机械硬盘,读的速度在500多兆每秒,写的速度在200多兆每秒,如果写入的量,读取的量,远远超过磁盘读和写的性能,速度更慢,可以把机械硬盘全部换成固态硬盘,速度会变快。通过代码层面进行优化。
2、解决大量磁盘
(1)config.setMaxBufferedDocs(100000); 控制写入一个 segment 前内存中保存的 document 的数目,设置较大的数目可以加快建索引速度。通过设置 Buffer 内存中的缓存区大小,优化索引的速度。内存的速度比硬盘速度快,如果往磁盘中写入一个文档,速度很慢,在 lucene 高级存储时讲到过,lucene 中有段,段中存的是索引和文档,设置 Buffer 内存的缓存大小,如果可以达到很大的量,达到上限会批量的把文档写入,不是有一个文档就用磁盘写一个,批量写比一个一个写速度快。通过设置 Buffer 缓存区的大小达到一定量之后,再往磁盘中写文档,数据可以减少磁盘 io,加快速率。如果设置过大,会比较消耗内存。数值指的是存放文档的速度,十万个文档会动用磁盘,每十万个文档往磁盘中写入一次。不优化情况下创建索引会花多长时间。不测试从数据库取数据,因为涉及到从数据库中读数据的快慢程度,跟创建索引没关系。
数值越大索引速度越快,但是会消耗更多的内存。
测试创建索引速度优化
@Throws Exception
@Test
public void createIndexTest2() throws Exception {
从创建分词器到在索引库中写数据,获取当前时间毫秒数start。
long start System. currentT imeMillis();
释放完资源后,再获取当前时间毫秒数。
long end = System. currentTimeMillis();
打印消耗的时间,结束时间减起始时间,
System . out . println(" ====
消耗的时间为:
======"+(end-start)+ "ms");
来到索引库,把已有的数据清除掉。
执行,在没有优化的情况下,1000ms为1s,7.725s,7725ms。
/**
*没有优化 小100万条数据,创建索引需要7725ms。
*/
//设置在内存中多少个文档向磁盘中批量写入一次数据
config.setMaxBufferedDocs(100000);
清除数据。
测试,十万条写一次数据,操作十次磁盘,6688ms,6s多。
再进行优化。
config.setMaxBufferedDocs(500000);
清除数据。
写两次,7106ms。操作磁盘的时间不是特别平均,优化完之后会变快。
//如果设置的数字过大,会过多消耗内存,但是会提升写入磁盘的速度
电脑用的是固态,.mto 接口最新的固态硬盘,由于硬盘速度的原因,所以感觉不出来有明显的差别,如果换成机械硬盘,越是机械硬盘慢的,使用这种优化方法,创建索引时效果越明显。
(2)indexWriter.forceMerge (文档数量);设置N个文档合并为一个段。
段是索引库中的物理文件,就是 segments_1。
没有设置数量,在 lucene 中有默认值,每一个版本默认值都不一样。
一千个文档合并成一个段文件,数值越大索引速度越快,搜索速度越慢;十个文档合并成一个段文件,值越小索引速度越慢,搜索速度越快。
网上没有确定的数值,官方也没有确定的数值,根据机器的配置不同,内存大小不同,磁盘速度不同,逐步设置,建议在线上服务器每一个机器设置的值都应该不一样,在服务器上先设置一千个文档,合并成一个段,五万个文档,十万个文档一点一点往上加,最后通过测试找出适合服务器的参数,配置即可。
文档数量设置为100个合并成一个段。
//设置多少给文档合并成一个段文件,数值越大索引速度越快,搜索速度越慢;值越小索引速度越慢,搜索速度越快
indexwriter . forceMerge(100);
把索引库中已经创建好的索引删除。
没有优化前需要7725ms,执行,需要7579ms。
indexwriter . forceMerge(1000000);
删除数据。
重新创建索引,运行。6895ms。
更高的值意味着索引期间更低的段合并开销,但同时也意味着更慢的搜索速度,因为此时的索引通常会包含更多的段。如果该值设置的过高,能获得更高的索引性能。但若在最后进行索引优化,那么较低的值会带来更快的搜索速度,因为在索引操作期间程序会利用并发机制完成段合并操作。故建议对程序分别进行高低多种值的测试,利用计算机的实际性能来告诉你最优值。