首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >基于分数的PHP内存缓存

基于分数的PHP内存缓存
EN

Stack Overflow用户
提问于 2015-07-30 16:33:42
回答 2查看 497关注 0票数 4

我正在尝试基于分数的PHP内存缓存,但我对性能(如何计数分数和删除低分数记录)有问题。

目标

我有大约一千万张唱片。我只想在内存中缓存最频繁的记录的0.1%,而不是在磁盘上。

我想设置10,000个缓存插槽(0.1%),我只想保持在这些插槽中最频繁的。

尝试/问题

我尝试了基于文件的缓存,它非常慢。

我尝试了MySQL和PostgreSQL,但是由于计算分数和删除低分数记录,它的性能成本过高。

我试过基于时间的缓存,例如。xcache,但是由于我的项目中有太多的数据,所以写的太多了。此外,删除最低分记录和列出所有缓存槽也有问题,因为它是"key->value“。

我找到了Redis,但似乎没有任何分数或类似的东西。

我的问题:

基于分数的缓存应该使用什么缓存方法?

请注意,所有这些帖子都是相似的,但不包含任何可用的答案:

Fastest PHP memory cache/hashtable

In-memory cache with LRU expiration

In-memory cache architecture/technology?

Need a php caching recommendation

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2015-07-31 10:40:31

听起来,LRU缓存应该能满足您的需要。您可以像配置LRU缓存一样配置Redis。也许它能很好地处理你的情况。以下是redis docs的一些参考资料:http://redis.io/topics/lru-cache

要快速总结一下,您可以使用“allkeys”驱逐策略,并将"maxmemory“设置为您想要的东西。一旦达到内存限制,redis将释放最近使用最少的项,并将内存使用情况保持在"maxmemory“之下。

另一种选择是使用"memcached",它是内存中的键值存储,默认情况下被配置为LRU缓存。

如果您真的想自己跟踪分数,并且已经有了某种类型的项目评分机制,您可以使用Redis,您可以将SortedSet和Hash放在一起来对缓存项进行排序。

散列将保持缓存的数据,而SortedSet将保持项的排序。

您需要这些SortedSet命令:

  • 您可以使用"ZADD“添加和更改项目分数。
  • 您也可以使用"ZINCRBY“来更改项目分数。
  • 您可以使用"ZCARD“命令来获取排序集的总数。
  • 您可以使用ZRANGE获取得分最低的项目。
  • 您可以使用ZREM删除项目。

每次插入后,您必须手动检查SortedSet的计数,并限制缓存中的项目数。总的来说,算法应该是这样的:

缓存插入:

代码语言:javascript
复制
HSET "cacheKey" "itemName" "itemValue"
ZADD "rankingKey" "itemScore" "itemName"
count = ZCARD "rankingKey"
if (count > limit)
    lowestRankedItem = ZRANGE "rankingKey" 0 0
    ZREM "rankingKey" lowestRankedItem
    HDEL "cacheKey" lowestRankedItem

查找将是:

代码语言:javascript
复制
itemValue = HGET "cacheKey" "itemName"
票数 1
EN

Stack Overflow用户

发布于 2015-07-31 14:59:51

纯LRU并不是很好,因为它缓存了所有的新键,我只需要缓存0.1%的数据(高分),所以不会有太多无用的写入。

当然,我将按照下一个版本的建议实现Redis方法,因为应该更快。所以,只有当你没有红宝石的时候才使用这个,如果你不能决定任何其他的得分,只需要计算每一段时间的点击数,或者只是想保持简单。

但我目前最好的尝试是使用key=>value memcached,只是现在进行测试,而且看起来既快速又稳定。在我以错误的方式思考之前。

当需要缓存新项时,我们检查缓存中是否存在得分(cache用于键包含int),如果是且小于我们的限制,则增加分数,如果是和高于限制,则获取内容并保存到缓存中。如果缓存中包含的不是数字,那就是我们的内容(高分)。如果key的缓存根本不存在,我们将int 1作为得分保存到非常短的TTL缓存中,并且我们只是获得内容而没有任何缓存(低分数)。

代码语言:javascript
复制
<?php

$minhits = 10; // Min 10 hits for one key
$minhitstime = 60 // Max 60 seconds between hits
$cachettl = 3600; // Cache for 3600 seconds  

$key = "article1";

$mem = new Memcached();
$mem->addServer('localhost', 11211);

$content = $mem->get($key);

if(!$content OR (is_int($content) AND $content<$minhits)){
    $content = getArticleContent(); // Your own function
}

if(is_int($c)){
    if($c>=$minhits){
        $mem->set($key, $content, $cachettl);
    } else {
        $mem->set($key, ($c+1), $minhitstime);
    }
} elseif($c) {
    $content = $c;
} else {
    $mem->set($key, 1, $minhitstime);
}

echo $content;

?>

此外,请不要尝试缓存纯int值;)如果是,您必须编辑代码。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/31729359

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档