首先不废话,新版本搜索架构图
介绍下着里面几个东西:
commonindex:这个东西是我们自己写的一个工具包,这个工具包提供给需要进行索引的应用,封装了定时增量索引,全量索引,数据导出等功能。
search-admin为一个辅助web应用,实现了Solr配置集中管理,词典集中管理,数据缓冲的功能,并且提供一个入口导入JSON数据(没有用solr的DIH,不想让各个应用和solr耦合太多)。
FQueue是一个高性能的磁盘队列,通过这个队列,我们对应用实时发过来的数据进行缓冲处理,防止直接发送给solr失败,FQueue是国产的,是由去哪儿qunar网的孙立开发的,这次我们还发现了它的一个严重的bug并且提交了patch。
QueueReader就是一个定时任务,定时读取队列中的数据发送至Solr,不过做了些重试处理、失败处理等操作。
旧版本就不画图了,大概的介绍一下,旧版本采用的是solr早期的replication主从模式,一台机器作为主机,管理平台数据都发往这个机器,其他两个从机通过replication机器同步索引,并且提供给外部搜索调用,负载均衡采用2台nginx实现。这种缺点是没有主从自动切换,没有failover,主机down掉了的话,整个数据变成只读。并且需要一台机单独做索引,浪费资源,所有数据都需要在每个机器上单独存在一份,索引变化较大的时候同步会占用很大的带宽和资源。
旧版本存在问题是:
1、Solr配置是通过ssh方式拷贝至服务器的,并且是保存在数据库的,如果改动solrconfig.xml是不能被同步过去的,因为replication不能配置成同步solrconfig.xml,否则replication的master配置也同步过去了,所以改动了solrconfig.xml最终还是要手动上传至从机,而且没有做xml相关的有效性验证,上传后有可能配置出错就直接覆盖原来的配置了,而且也没有提示。
这种情况在SolrCloud可以很好的解决,首先配置验证的问题通过dom4j可以做一些大概的验证,确保是完整的XML,一些简单的schema或者config规则加了上传时判断,并且配置文件是保存在zookeeper进行集中管理的,只需要修改ZooKeeper里面的节点就能达到全局配置文件修改的目的。
2、词典管理这个功能在旧版本是比较鸡肋的,因为旧版本只是把词典保存在数据库,并且在修改后通过ssh同步至服务端,要想让词典生效,需要重载整个Core,我们的词典是根据业务类型来划分成几个固定词典的,所以不想让每个Core都加载单独的词典来节省内存,所以没有放到conf目录里面去,这样就不能通过replication同步了。
还是类似配置文件,新版本通过吧词典文件加载zookeeper中,并且通过一个solr插件进行变更监控和词典维护重载,只要修改了词典文件并上传到ZooKeeper,都可以自动的加载当前词典文件,并且不需要重载core即时生效,给业务变更带来很大的方便。
3、数据导入的问题,旧版本通过读取一个json文件,每行数据是一个docment,首先JSON文件这种文件方式是一种方便直接进行阅读的数据格式,但是一旦数据非常多,将会导致导出的数据文件非常巨大,导出速度和导入速度都受到了影响,所以根据solr的javabin类似的方式重新定义了一种数据导出格式,有的人可能会问为啥不生成压缩文件导出导入,其实这么大的文件数据,光压缩都会耗费很大的资源的,也会拖垮各项指标的,并且旧的导入方式为读取数据和发送Solr串行方式,新版本改用单个线程读取,多个线程发送,最大限度的发挥集群的作用。
新版本上线的时候配到了一个非常蛋疼的问题,很容易就出现了OOM的问题,后来跟踪发现是Solr分布式查询在队取得各个分片的数据进行合并的时候会new一个优先级队列,这个队列的初始化大小是client传过来的offset和count分页参数的一个和,我们的client中有个应用会一次性查出所有符合条件的数据,count传了个99999999的值,导致一请求就需要划分出2G多的堆内存,好恐怖。。。我们直接修复了这个bug,看是不是需要提交一个issue到solr得jira上去,不知道是不是有类似的issue了。打上了补丁并且让调用方做了分页处理后,目前系统运行良好,这一次升级估计能顶好久了。。。