dongtong848825
dongtong848825
2013-08-14 08:03

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

已采纳

Assume, that I have a big (MySQL-)table (>10k rows) with id -> string. I can put them all in an array and cache this array. But the question ist: How to cache it efficiently?

a) Cache it as one big item. So I will execute

$redis->set("array", $array);

Quite short and easy. But for every entry I need, I have to fetch the whole thing. Absolutely inefficient.

b) Cache every entry itself:

foreach( $array as $id => $str )
  $redis->set( "array:$id", $str );

Using this way, I will have >10k entries in Redis. That doesn't feel good. If I have 10 of these tables, i will have 100k entries....

So what's your proposal? How to cache a big array?

  • 点赞
  • 写回答
  • 关注问题
  • 收藏
  • 复制链接分享
  • 邀请回答

2条回答

  • duanjiyun7391 duanjiyun7391 8年前

    Caching the big array only makes helpful if you're planning to retrieve it always as a whole. However cache invalidation will be a very "heavy" operation as anytime when you change something you have to invalidate the whole array and reread it from the DB.

    10k in redis is not much at all. You can have millions of entries without problem.

    I would go with the b) version. Cache every entry individually. Easier to maintain, simpler application code and smaller memory footprint from application side which gets more and more important when you want to scale your application.

    点赞 评论 复制链接分享
  • dongqianzong4275 dongqianzong4275 8年前

    The first question is: why do you need to cache that array.

    If you allways need the whole array, then:

    $redis->set("array", $array);
    

    If you only need some specific indexes (2nd solution), then why are you trying to cache the whole thing instead of querying the database each time for the id you need. It is allways more efficient to get only needed data.

    Remember that a cache usefullness is estimmated using the ration between reads (items effectively read from the cache) and miss (items read from the datasource then added to the cache).

    If you are caching the whole table (10k miss), but querying only few elements by id (2de solution), then your ratio is near zero. If you need the whole table each time, then cache it using the first solution (1miss) and so your ratio is more likely to be > 1.

    Also, remember that redis is a separate server. For each request to redis, a request is made to this server (on localhost or not). So basicly it's the same rule for redis than for mysql: One big request will perform faster than many little requests.

    点赞 评论 复制链接分享