PHP:如何在redis中缓存大表?

PHP:如何在redis中缓存大表?,php,mysql,caching,redis,Php,Mysql,Caching,Redis,假设我有一个id->string的大(MySQL-)表(>10k行)。我可以把它们都放在一个数组中并缓存这个数组。但问题是:如何高效地缓存它 a)将其缓存为一个大项目。所以我会执行 $redis->set("array", $array); 很短很简单。但是我需要的每一个条目,我都得把整件东西取出来。绝对没有效率 b)缓存每个条目本身: foreach( $array as $id => $str ) $redis->set( "array:$id", $str );

假设我有一个id->string的大(MySQL-)表(>10k行)。我可以把它们都放在一个数组中并缓存这个数组。但问题是:如何高效地缓存它

a)将其缓存为一个大项目。所以我会执行

$redis->set("array", $array);
很短很简单。但是我需要的每一个条目,我都得把整件东西取出来。绝对没有效率

b)缓存每个条目本身

foreach( $array as $id => $str )
  $redis->set( "array:$id", $str );
使用这种方式,我将在Redis中拥有超过10k的条目。感觉不太好。如果我有10个这样的表,我将有10万个条目


那么你的建议是什么?如何缓存大数组?

第一个问题是:为什么需要缓存该数组

如果您总是需要整个阵列,那么:

$redis->set("array", $array);
如果您只需要一些特定的索引(第二种解决方案),那么为什么您要尝试缓存整个内容,而不是每次都在数据库中查询所需的id。 只获取所需数据总是更有效的

请记住,缓存可用性是使用读取(从缓存中有效读取的项)和未命中(从数据源读取的项然后添加到缓存中)之间的比率来估计的

如果缓存整个表(10k未命中),但仅按id查询少数元素(2de解决方案),则比率接近于零。 如果您每次都需要整个表,那么使用第一个解决方案(1miss)缓存它,因此您的比率更可能大于1

另外,请记住,redis是一个独立的服务器。对于每个对redis的请求,都会向该服务器发出请求(无论是否在本地主机上)。
因此,基本上redis的规则与mysql相同:一个大请求的执行速度比许多小请求的执行速度快。

缓存大数组只有在您计划始终作为一个整体检索它时才有帮助。然而,缓存失效将是一项非常“繁重”的操作,因为任何时候当您更改某些内容时,都必须使整个阵列失效并从数据库中重新读取它

redis中的10k根本不算多。你可以毫无问题地拥有数百万个条目


我会选择b)版本。单独缓存每个条目。更易于维护、更简单的应用程序代码和更小的应用程序内存占用,这在您想要扩展应用程序时变得越来越重要。

我不需要整个阵列。我一次只需要一个条目。然后,选择第二个解决方案。当您需要一个条目时,从缓存中获取它。如果它不在缓存中,则从数据库中获取它并将其存储在缓存中。但不要在应用程序启动后立即将整个表加载到缓存中,让它仅在需要时延迟加载到缓存中。但是,10万次“从表中选择字段,其中id=?”的负载比一次“从表中选择id,字段”的负载要重得多,并缓存这些。。。不是吗?延迟加载的目的是在给定的时间只加载您需要的内容。因此,如果10k Select更重,它们会在时间上分布(取决于应用程序的使用情况,分为几分钟甚至几小时)更多关于快速加载与延迟加载的信息:用例:我一次只需要一个条目。为什么需要在Redis中缓存整个数据库表,为什么不直接使用原始数据库表中的数据呢?1)id和字符串只是其中的两列。2) 数据库是高流量的,我想减少负载。3) 如果经常使用,这难道不是缓存的意思吗?4) Redis仅为内存,位于Web服务器的机器上,DB位于集群中自己的机器上;但是,如果数据库流量很大,那么请确保对其进行了适当的索引-外部缓存有助于存储运行时间较长的常规、相对静态查询的结果,但如果数据库访问速度不慢(取决于您的查询),但是一个简单的索引查询检索一条没有聚合/etc的记录不应该比redis访问慢。。。。。。即使您的redis物理上在同一台服务器上,它仍然像通过网络请求一样被请求,因此您唯一需要保存的是网络延迟;但是增加了缓存验证的开销,对未命中的回退,等等,就像你的答案一样-我会试试看!谢谢!