在SNS网站中,“好友的相册”、“好友的日志”、“好友常去的小组”,这样的功能到处都是,如果处理不当,对整个系统的压力都会非同小可。
这里介绍一种利用sphinx的搜索天性,倒排索引群中的人,然后把好友的XX功能化解为或关系的搜索,下面是是一些记录。关于sphinx的安装,详细见54chen之前的一些手记:http://www.54chen.com/tag/sphinx
第一步,制造随机数据
这里为方便理解,作一个假设的场景,要索引的字段缩减到2个字段,字段1是目标id,表示相册id\日志id\小组id等等,字段2是一个text,里面以逗号隔开记录了所有的和这个目标id有关系的人的id号,大致如下所示:
id members
1 1,2,3,4,5,6
这样一个表,标识了id为1的一个目标,都有什么用户和他有关。比如可以表示:id为1的群都有12345这五个人加过;id为1的相册都有12345这五个人看过;id为1的相册都有12345这五个人回复过,等等。
下面代码片段所做之事,是将10万条记录插入到表中,表的members的记录在五千条内随机,里的人id从1到50000随机产生,这样,基本能够模拟一个中型应用的水平了。
$db = new DLConnection();
$sql = "INSERT INTO `forum`.`forum_info` (`id` ,`members`)VALUES";
$dot = "";
for ($i=0;$i<100000;$i++)
{ $dot2 = "";
$sql2 = "";
for ($j=0;$j$x = rand(1,50000);
$sql2 .= $dot2.$x;
$dot2 = ",";
}
$sql .= $dot."('$i', '$sql2')";
$dot = ",";
if ($i%1000==0) {
$db->Execute($sql);
$sql = "INSERT INTO `forum`.`forum_info` (`id` ,`members`)VALUES";
$dot = "";
}
}
第二步,压力测试搜索性能
代码太长不帖了,使用java开启100个线程100个连接到sphinx,sphinx建立索引后,只起一个节点。
搜索的时候,关键的几点:
1. int mode = SphinxClient.SPH_MATCH_BOOLEAN; 使用布尔方式查询
2.随机产生1到1000个用户id,id为1到50000之间的随机一个,多个之间用|(或)连接
结论
sphinx的搜索性能还是基本满意,在压力测试的时候看后台的query log可以发现,绝大多数的查询在100ms左右,当然,因为随机的原因,也会出现一些3秒5秒的查询,但这是个案,在普通用户中出现的可能性不大。
此方案的适用性正在进一步优化中。
原创文章如转载,请注明:转载自五四陈科学院[http://www.54chen.com]
捐赠说明