一、需求来源一个并发量大、数据量适中的业务线,需要实现一个“标题检索”功能:(1)量并发量大,每秒20万次(2)数据量适中,200w左右数据(3)是否需要分词:是(4)数据是否实时更新:否2.常见的潜在解决方案及其优缺点(1)数据库搜索法具体方法:将题名数据存储在数据库中,使用like进行搜索。优点:方案简单缺点:无法实现分词,无法承载并发量:无法支撑并发量(3)使用开源方案将索引外化具体方法:构建开源外置索引方案比如lucene,solr,ES等优点:性能比上面两个好缺点:并发量可能有风险,系统比较重对于简单的业务搭建这样的系统成本比较高.3、58龙哥的建议问题一:龙哥,同城首届58编程大赛题目好像是“过滤黄反词”。你是冠军。那时候是用DAT来实现的吗?龙哥:是的画外音:什么是DAT?流行度:DAT是doublearraytrie的缩写,是trie树的变种优化数据结构。它可以在保证trie树检索效率的同时大大减少内存的使用,常被用来解决检索和信息过滤等问题。(详情请百度“DAT”)Q2:以上业务场景是否可以使用DAT来实现?龙哥:DAT更新数据比较麻烦,不能自增。问题三:是否可以直接使用trie树?龙哥:trie树占内存多画外音:什么是trie树?通俗点:trie树,又称词搜索树,是一种树结构,是hash树的变种。一个典型的应用是用于统计,保存大量的字符串(但不限于字符串),因此常被搜索引擎系统用于文本词频统计。其优点是:利用字符串的公共前缀减少查询时间,尽量减少不必要的字符串比较,查询效率高于哈希树。(来源:百度百科)比如:上面的trie树可以表示{and,as,at,cn,com}等五个标题的集合。问题4:如果要支持分词,需要合并多个分词遍历trie树对吧?龙哥:对,每次分词遍历一次trie树,就可以得到doc_id的列表,将多次分词得到的列表合并,就是最后的结果。问题5:龙哥,请问有没有更好更轻量级的方案?龙哥:有了trie树,数据会膨胀到文档数*标题长度这么多。标题越长,文档越多,内存占用越大。有解决办法,占用内存很小,和标题长短无关,很帅。Q6:有没有相关的文章,推荐一篇?龙哥:网上可能查不到。我简单说一下。核心思想是“内存哈希+ID列表”。:将查询词切分,对词进行哈希处理,直接查询哈希表,得到doc_id的列表,然后合并多个词=====示例=====例如:doc1:我爱北京doc2:我爱到家doc3:到家美首先切分标题:doc1:我爱北京->我,爱,北京doc2:我爱到家->我,爱,到家doc3:到家美->到家,美好对分词进行hash,生成hash+IDlist:hash(me)->{doc1,doc2}hash(love)->{doc1,doc2}hash(北京)->{doc1}hash(home)->{doc2,doc3}hash(good)->{doc3}这样就完成了所有标题的初始化,你会发现数据量的多少与标题的长度无关。用户输入“我爱”,分词后变成{我,爱},在内存中查找每个分词的hashhash(me)->{doc1,doc2}hash(love)->{doc1,doc2}再合并,最终的查找结果为doc1+doc2。=====ExampleEND=====Q7:这种方法有什么优点?龙哥:内存存储操作可以满足很多并发,延迟也很低,内存占用也不大。实现起来非常简单快捷Q8:有什么不足之处?它与传统搜索有何不同?龙哥:这是一个快速过渡的方案,因为索引本身还没有实现,固化的title数据还需要存入数据库。如果不实现高可用,数据恢复会很慢。当然,实现高可用也很容易,只需要创建两个相同的哈希索引即可。另外,水平切分没有做,但是当数据量非常非常大的时候,还是需要改进水平切分。
