论坛首页 Java企业应用论坛

Memcached大量数据缓存策略探讨

浏览 11771 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
   发表时间:2007-06-27  
使用Memcached。需求是这样的:系统需要把大量的关键常用数据(十万条以上,在不断增长中)放到缓存中,为提高程序执行效率。那么这些数据在缓存中的存储方式是怎样的时候,效率最高?站在目前的缓存工具角度来想,假设要缓存的数据为手机的订阅关系,可以有下面两种做法:
一,在缓存中建一个Cache,键为subsription,值则是一个大哈希表,哈希表存放所有的数据,以唯一的手机做Key,相关订阅信息做Value。
如此要查询一个手机的订阅数据,要先从Cached里拿到到key为subscription的缓存,这是个大哈希表,然后再从哈希表里按手机拿出订阅信息:
Map datas = memcached.get("subscription");
Subsciption s = datas.get(mobile);

这样的缺点就是查询客户端会从Memcached的Server拿到一个巨大的Map。不仅网络开销大,并且客户端也要开辟大块内存来存放这个临时的Map。
二,每一个订阅关系作为一个缓存实体放到Memcached中。那就意味着查询极为方便:
Subscription sub = memcached.get(mobile);

但是在Memcached里就会有几十万个缓存实体了,不知道是否会给查询带来速度上的影响。另一个不便的地方就是从缓存里拿不到订阅关系的总数(当然这个需求显得很鸡肋)。

下面是我自己的一些幻想。假如我按照做法一来存放数据。查询能这样就好了:
Subscription sub = memcached.get(“subscription#” + mobile);

不需要担心服务器端给客户端返回一个大Map,又占用客户端巨大的内存资源。所有的嵌套查找工作交给服务器去做,最后返回我想要的订阅关系即可。当然,我依然可以使用get("subscription")拿回一个大Map。

不过看起来我这样的想法应该是有点不实际。更多的是我想请教下大家,在大数量缓存的情况下,大家会使用什么样的缓存策略?
   发表时间:2007-06-27  
首先你肯定不能保存或返回所有的信息,除了你说的那些缺点, 用一个key,这样极不利于信息共享,

第二,你应该不需要担心cache怎么根据一个key得到一个相对应的内容,
不管它怎么实施,应该不会比map差,它至少可以用hash算法。
根据key快速存取内容对这种(key, value)cache来说极重要的,
具体的性能,你可以测试一下。

0 请登录后投票
   发表时间:2007-06-27  
我想是的。担心那几十万条数据如何存放是我过虑了。很明显我是应该使用第二种做法。
0 请登录后投票
   发表时间:2007-06-27  
采用第二种做法。
其实楼主说了一个cache的命中率的问题,在设计cache时命中率也是要考虑一下的,如果某些数据命中率非常高的,就应该单独做key来读取,程序也可以优化使得命中率高的最快get到。
0 请登录后投票
   发表时间:2007-06-27  
楼上所说的由命中率来决定是否用单独的Key来读取,看起来只能在设计阶段评估哪类的数据命中率较高。运行期中有办法可以让实际上命中率高的数据在缓存中存储的方式发生改变?我想即使可以,程序付出的代价也是相当大的。
0 请登录后投票
   发表时间:2007-06-27  
如果数据量很大的话 也可以对手机号进行分类

例如 按前三位 做多个缓存
133 130 131 135 138 139 158..... 其他
或者按奇偶分

这样也可以提高一些命中率
0 请登录后投票
   发表时间:2007-06-27  
风往北吹 写道
采用第二种做法。
其实楼主说了一个cache的命中率的问题,在设计cache时命中率也是要考虑一下的,如果某些数据命中率非常高的,就应该单独做key来读取,程序也可以优化使得命中率高的最快get到。


扯蛋,这跟命中率有什么关系?
命中率讲get能不能得到数据,反过来说就是考虑,应该缓存那些数据,提高空间的利用率。
lz讲的是怎样快速的get到结果, 你缓存的数据的多少,对cache的get的速度并没有多大的影响。

fins 写道
如果数据量很大的话 也可以对手机号进行分类

例如 按前三位 做多个缓存
133 130 131 135 138 139 158..... 其他
或者按奇偶分

这样也可以提高一些命中率


这样做,是吃包了撑着没事干。
更不明白跟命中率有和关系?
0 请登录后投票
   发表时间:2007-06-27  
谢谢Fins的建议。
不过像这样只是将一个大Map换成了几个相对小的Map。做法一所讲的负面影响还是一样存在。
0 请登录后投票
   发表时间:2007-06-27  
lihy70 写道
风往北吹 写道
采用第二种做法。
其实楼主说了一个cache的命中率的问题,在设计cache时命中率也是要考虑一下的,如果某些数据命中率非常高的,就应该单独做key来读取,程序也可以优化使得命中率高的最快get到。


扯蛋,这跟命中率有什么关系?
命中率讲get能不能得到数据,反过来说就是考虑,应该缓存那些数据,提高空间的利用率。
lz讲的是怎样快速的get到结果, 你缓存的数据的多少,对cache的get的速度并没有多大的影响。

fins 写道
如果数据量很大的话 也可以对手机号进行分类

例如 按前三位 做多个缓存
133 130 131 135 138 139 158..... 其他
或者按奇偶分

这样也可以提高一些命中率


这样做,是吃包了撑着没事干。
更不明白跟命中率有和关系?


我的意思是类似分治
从10万个对象中 挑出一个快, 还是 把10万个分类,然后从每类里取快呢
可能我确实是"吃包了撑着没事干",我只是对 "手机号码" 这个比较敏感
毕竟做了电信两年多了, 处理几千万的手机号相关的数据时, 这是一个很常规的方法.
不过也许确实 用在缓存里有些多于 毕竟缓存里的数据不会太多



风往北吹在扯淡, 我是吃饱了撑着没事干
那您的高见是????
0 请登录后投票
   发表时间:2007-06-27  
lz
"查询客户端会从Memcached的Server拿到一个巨大的Map。不仅网络开销大,并且客户端也要开辟大块内存来存放这个临时的Map"

这里的客户端是指什么???? 不是浏览器吧??

还有 我没明白这个和网络开销有什么关系
Memcached的Server端直接取得最终要查询的数据,然后传给客户端就可以了啊,没理解你的具体的场景
0 请登录后投票
论坛首页 Java企业应用版

跳转论坛:
Global site tag (gtag.js) - Google Analytics