分布式索引的架构和更新问题
osborn
2013-05-03
大约5000万数据量的项目,需要经常更新,每天会增加1万左右的数据,要求尽量实时。
我现在的做法是分成3个索引,一个大索引存储全部内容,一个月更新一次。一个中索引储存1个月的内容,每天更新一次。还有一个小索引存储2~3天的内容,每15分钟更新一次。每次更新都会留旧索引的备份。 这么做的原因是,项目的数据底层和服务器都不太好,用的mysql,生成索引的时候可能会因为负载或数据库同步等问题导致索引出毛病,我要能快速把索引切换回相对旧一点的版本。 但我更新索引的方式很粗暴,说来可能比较吓人,我是直接生成新索引,做完后把旧索引改个名字备份,然后把新索引MV过去,再重新打开以下reader……一直没用过增量索引。 而做分布式的方法是把索引用rsync拷贝到所有的云端服务器,并让云端服务器分别重新打开reader。 我现在想试试做增量索引,现在有几个问题。 1是怎样更新旧数据,比方说更新索引的时候,我按照数据表的更新时间读数据,其中有些数据索引里已经有了,只是需要把数据更新一下。lucene更新的方式是删了旧的再加新的,那么是不是说我在做索引的时候每加一条数据都要先看一下数据是不是已存在?这样做好像很慢,有没有什么比较好的策略? 2是索引有没有必要做读写分离?如果更新一个正在线上使用的索引,更新完了刷新一下reader,会比我原来的方式更好吗? 另外,关于分布式索引,各位都是怎样做的,如果让多个搜索服务器挂载同一个NFS上的索引,会有IO瓶颈么? |
|
rrong_m
2013-05-10
看看这个吧。
elasticsearch.org |
|
冰糖葫芦
2013-05-12
就问题1来说,我们的做法是版本号,如version字段,这样你在首次做索引的时候只要记录下本次索引的所有数据里的最大version,这样下次增量索引的时候只要做version大于上次做索引记录的最大version即可,而不用每次都去数据库里判断是否存在
|
|
lvwenwen
2013-05-14
elasticsearch.org
|
|
caizi12
2013-05-24
冰糖葫芦 写道 就问题1来说,我们的做法是版本号,如version字段,这样你在首次做索引的时候只要记录下本次索引的所有数据里的最大version,这样下次增量索引的时候只要做version大于上次做索引记录的最大version即可,而不用每次都去数据库里判断是否存在
具体怎么弄呢,没想太明白。 例如luence版本是1,数据库里面的数据也是1,然后某条数据更新了version变成2? 其它数据version还是1吧,有条数据更新了两次version是3,怎么知道那个是最大版本呢?还有记录删除呢? 我之前做的都是数据更改完后,直接更新索引,表中数据量比较小只有10w左右。 大数据也不知道有啥好方法,加一个临时表不知道怎么样,加上主键和更改标识,一条数据只存一个状态,数据如果有改动则在临时表加条数据,定时去这个表查数据然后更新索引,如果考虑到并发到的话,再加个时间段什么的。 |
|
冰糖葫芦
2013-05-31
1、例如lucene版本是2,那么对与luence来说只要把数据库中大于2的数据的索引更新就OK了;那么对于版本为1的那条数据来说,是没有变化的,不需要重新建索引。
2、对于删除,一般做法是标记删除而不是真正的物理删除,这样,其实做删除操作和更新操作就是一个原理,只不过对于lucene来说,数据库中标记为删除且版本号大于2的则从索引中移除就可以了。 3、对于最大版本,一般oracle做法是用sequence,其他数据库如mysql的话可以专门建一张version表来维护版本号 4、当然了,在每次更新过索引且成功后需要把lucene的版本号更新为max version 其实,看看一些持久化框架如hibernate采用的也是类似的机制,要不然想楼主说的加临时表,一方面性能问题,再一方面,使用数据库本身的机制如sequence的话并发就已经得到控制了 |