2

我们有以下系统:
用户数量:~500k
项目数量:~100k

UserSimilarity userSimilarity = new TanimotoCoefficientSimilarity(dataModel);       
UserNeighborhood neighborhood = new NearestNUserNeighborhood(neighborHoodSize,userSimilarity, dataModel);
GenericBooleanPrefUserBasedRecommender recommender = new GenericBooleanPrefUserBasedRecommender(dataModel, neighborhood ,userSimilarity);

使用上述推荐器,对于 400 个邻域大小,我们获得了平均 600 毫秒的响应时间。

我们尝试使其小于 100 毫秒(在线引擎),我们确实通过使用自定义TopItems.getTopUsers()TopItems.getTopItems()多线程(等于核心数)函数实现了这一点。函数 TopUsers() 花费的平均时间
:~ 30-40 ms
TopItems():~ 50-60 ms

但是,当我们尝试发出许多并发请求(甚至达到 25 个)时,响应时间会飙升至几秒。

我们可以为每个用户预先计算类似邻域的东西,但 TopItems() 仍然是并发请求的明显瓶颈。

您会建议任何方法来改善多线程并发请求的响应时间吗?

后备选项是将预先计算的建议存储在一些 NoSql DB 中。这将不会很昂贵,因为我们会定期进行预计算,即使对于不那么活跃的用户也是如此。我们可能会比不那么活跃的用户更频繁地挑选活跃用户并预先计算推荐。

有什么想法吗?

4

1 回答 1

1

是的,多线程不会增加系统的整体吞吐量。这意味着您可以通过承载更多线程来更快地响应一个请求。但是当并发请求的数量等于您的核心数量时,它或多或少会回到您开始的地方;事实上,线程的开销可能会使其变慢。

当然,您可以随时尝试添加更多机器并维护此服务的 N 个实例。

这可能与您在基于邻域的模型上所做的一样好。item-neighborhood 版本有更多的杠杆:您可以控制所考虑的项目数量的抽样。这可以提供帮助。

除此之外,您可能需要查看为更好地扩展而构建的模型。我个人更喜欢这种基于矩阵分解的技术。

于 2013-07-11T16:16:43.137 回答