您的位置:首页 > 其它

如何设计百万级以上规模项目的搜索功能

2019-03-20 13:30 41 查看
版权声明:本文为博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。 本文链接:https://blog.csdn.net/yangliuwei001/article/details/88686047

假想项目

项目名:***平台

项目规模:100万数据量

数据特征:每条信息有标题、作者、发布时间、唯一的识别码、正文

其中标题识别码是英文与数字的组合,正文假设500汉字。
 

一般项目的搜索功能

一般项目,这里特指数据量规模在1万以下的规模,简单的企业站、社区系统、博客系统,数据量不大,搜索功能直接用like查询就能满足使用需求,一般配置的服务器2核4G就能发挥很好的性能了。

 

百万级以上规模项目的搜索功能

但是项目规模达到百万级以上时,就不能用简单的like查询就行搜索了。like查询需要对数据表进行遍历,需要把表的内容加载至内存,这里简单计算下内存开销:

100万条数据,每条信息500字正文

每个汉字是2个字节,1024字节=1Kb,1024Kb=1Mb,1024Mb=1G

100万条数据全匹配产生的数据量大小是:1000000*500*2/1024/1024/1024≈1G,这里不考虑分页,1G数据的传输就会消消耗大量的带宽资源,更不好说CPU和内存消耗了

因此,百万级以上规模的搜索功能,必须要使用sphinx这类专门的全文索引工具

 

Like查询时,MySQL内部都做了什么

Like查询没有用到索引,需要对全表进行扫描,将所查到的每一行符合条件的数据放到结果集里面,然后返给客户端。

服务端并不需要保存一个完整的结果集,取数据和发数据流程如下:

  1. 获取一行,写到net_buffer中,它的内存的大小由参数net_buffer_length确定,默认16k;
  2. 重复获取行,直到net_buffer写满,调用网络接口发出去;
  3. 如果发送成功,清空net_buffer,然后继续取下一行,重复1、2过程;
  4. 如果发送函数返回EAGAIN 或者 WSAEWOULDBLOCK,此时表示“本地网络栈”(socket send buffer)写满了,进入等待(为什么会写满,因为没发出去)。直到网络栈重新可写,再继续发送。

由取、发数据流程可知:

  1. 一个查询在发送过程中,占用MySQL的内部内存最大就是net_buffer_length,它是有上限控制的,并不会肆意占用内存;
  2. socket send buffer (默认定义/proc/sys/net/core/wmem_default)也是有上限控制的,如果它被写满,就会暂停读数据的流程。

like查询有这以上2个瓶颈限制,导致查询速度缓慢,全表扫描会占用大量的CPU性能,匹配到的结果发送的过程中,又受到net_buffer和send_buffer的双重限制,这决定了like查询不适合处理10万以上数据量的表

实战经验分享

我们已有多个大数据量规模项目的实战经验,我们开发了一款专业的高性能开发框架,云豹框架,感兴趣的可以百度搜索了解下。

 

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐