论坛首页 Java企业应用论坛

MemCached Cache Java Client封装优化历程

浏览 41510 次
该帖已经被评为良好帖
作者 正文
   发表时间:2008-09-29  
我上次的场景是这样的,我测试的时候放入的对象为100k,然后会放到第二个slab上,算了一下大概10000个左右就可以满一页,然后测试了一下,当超过一页,那么的确slab后面的页数是2,同时其他每一个在初始化时候就设置的slab一个没有少,当然我不知道时间长了Memcached是否会回收这些空间。
还有就是放入进去的内容,在删除的时候真的仅仅只是标示一下,具体什么时候回收应该是要不够的时候才会使用,不过也没看过C的代码,只是看过有一个人对C代码的部分分析。用我那个keyset的方法是的却可以取得那些已经被删除的内容。
看来还有很多东西要仔细看看^_^,多谢Robbin指点
0 请登录后投票
   发表时间:2008-09-29  
cenwenchu 写道
我上次的场景是这样的,我测试的时候放入的对象为100k,然后会放到第二个slab上,算了一下大概10000个左右就可以满一页,然后测试了一下,当超过一页,那么的确slab后面的页数是2,同时其他每一个在初始化时候就设置的slab一个没有少,当然我不知道时间长了Memcached是否会回收这些空间。
还有就是放入进去的内容,在删除的时候真的仅仅只是标示一下,具体什么时候回收应该是要不够的时候才会使用,不过也没看过C的代码,只是看过有一个人对C代码的部分分析。用我那个keyset的方法是的却可以取得那些已经被删除的内容。
看来还有很多东西要仔细看看^_^,多谢Robbin指点


不客气。也许和版本也有关系吧,我用的memcached是1.2.5版本的。我也比较关心memcached的行为,希望可以把它用好。
0 请登录后投票
   发表时间:2008-09-29  
robbin 写道
sdh5724 写道
 
   这个你有经验么, 我好久没有去维护这些东西了, 现在我的每个CACHE 进程大约使用了4-5G内存。 我没有设置特别的参数。 看来我要好好改善下了。


一个memcached使用4-5G内存,还不如启动4-5个进程,每个进程1GB这样更能够有效利用内存。



我前面说过, 我大约用了20个机器, 如果说使用一个机器那么多的进程, 会导致我的配置非常的冗长。 这个也导致连接数量的虚高。 我的生产环境压力非常大, 每天每台机器要提供200W以上的PV,大约有80台机器, 都且这个访问有30%是在早上9:00-11:00产生。 如果memcached使用1G的管理模式, 可能导致我的每个memcache机器达到4000-8000个连接。 这么多的连接, 无论对于客户端或者服务端, 都是非常的不利的。 在一个有规模的环境中, 我必须考虑这些问题带来的严重性。  如果您想讨论细节问题, 你可以加我的MSN SDH5724@163.COM .
说实话, 内存利用效率对我来说, 这东西太便宜了, 并不是最重要的.  大内存使用我唯一的担心是内存抖动, 不过, 好像我没有观察到过, 毕竟我没有开启SWAP的使用.  现在我的配置的7G的内存分配给memcached, 1g给OS使用.  使用了大约4-5G. 命中效基本在96%左右, 24小时的数据有效时间. 我没有测过真的7G内存到达会对OS产生什么影响. 希望别出问题. 哈:)
0 请登录后投票
   发表时间:2008-09-29  
启动一个memcached,占大内存,和启动好几个memcached,他们的连接数量应该是一样的吧。这个并发连接数只和client端的并发访问请求有关,和memcached怎么部署应该是无关的。
0 请登录后投票
   发表时间:2008-09-30  
robbin 写道
启动一个memcached,占大内存,和启动好几个memcached,他们的连接数量应该是一样的吧。这个并发连接数只和client端的并发访问请求有关,和memcached怎么部署应该是无关的。

可能还不完全一样,我的理解是这样的:

一台mc的情况:假设我们有10个java client,每个client的连接池有20个连接,那么这台mc一共有10 * 20 = 200个连接

假设我们的mc上升到5台,10个java client,每个client的连接池有20个连接,那么5台mc一共有10 * 20 * 5 =1000个连接

随着mc数量的上升,连接数也在成倍的增加,而且一旦有很多很多的client的时候,连接数更是大的惊人。所以一般情况下我们会在应用程序上使用lb,比如说不同id段的文章放在不同的mc中(只是举例),这样就不会让所有的client都连到一组mc上了,虽然总连接数没有变,但是连接到某个mc的连接数确下来了。

------------------------------------

关于删除的问题,应该是这样的,删除的时候给这个记录作一个标识,然后每个元素还有一个引用计数器,一旦这个引用计数器为0,那么就可以证明这个数据确实可以删除了,如果引用计数器不为0,那么虽然删掉,但是还有请求在使用这个数据,所以是不能立即删掉了,否则正在使用这个内存的指针就指不到数据了。

而LRU,我之前也写了一篇文章来分析它的特点,再补充一点,过期的数据会被移动到slab中双向列表的队头,那么一旦空间不够,mc会遍历队头的50个元素,把过期的那个位置的元素丢弃,放上新的元素。


---------------------------------------
搂主这个东西其实我之前也很想做(之前对现在最流行的那个client的性能真的很失望),但是由于很多原因都停下来了,不过有一点我不敢恭维,就是这个client是local+remote的方式,因为互联网的需求是很奇怪的,很多时候我们根本不需要这个local cache嵌入到client中,为什么这么说呢,因为很多场景下mc不只是cache,有时候它是一个remote hashmap,那么我需要其中数据的变化能立刻反应到client中,就像一个内存的berkelyDB一样使用就行了,不过bdb是local的而已。而且加local cache到client中一般来来说java程序员都能自己搞定。




----------------------------------------
前面有人说他写了好几个provider,我们一直以来也都是这样做的。其实在缓存场景中,这个方案很常用的。目的就是封装不同的cache,对外提供统一的接口。
0 请登录后投票
   发表时间:2008-09-30  
ahuaxuan 写道
搂主这个东西其实我之前也很想做(之前对现在最流行的那个client的性能真的很失望),但是由于很多原因都停下来了,不过有一点我不敢恭维,就是这个client是local+remote的方式,因为互联网的需求是很奇怪的,很多时候我们根本不需要这个local cache嵌入到client中,为什么这么说呢,因为很多场景下mc不只是cache,有时候它是一个remote hashmap,那么我需要其中数据的变化能立刻反应到client中,就像一个内存的berkelyDB一样使用就行了,不过bdb是local的而已。而且加local cache到client中一般来来说java程序员都能自己搞定。


其实楼主的local cache是可以不用的。所以看你的需求来使用,多一个功能并无大碍。

我看楼主源代码中那个MemcacheCache类上的get方法有点问题。如果我put进去的数据是有超时设定的。假如一个客户端出了问题。在数据恢复的时候就会把原来有超时设定的数据变成永久的了。
0 请登录后投票
   发表时间:2008-09-30  
robbin 写道
启动一个memcached,占大内存,和启动好几个memcached,他们的连接数量应该是一样的吧。这个并发连接数只和client端的并发访问请求有关,和memcached怎么部署应该是无关的。

看到一个介绍MemCached的系列文章,其中也提到一台机器上启动多个进程的问题:

引用
memcached服务器的典型配置如下:

    * CPU:Intel Pentium 4 2.8GHz
    * 内存:4GB
    * 硬盘:146GB SCSI
    * 操作系统:Linux(x86_64)

......

每台memcached服务器仅启动一个memcached进程。分配给memcached的内存为3GB,......

由于使用了x86_64的操作系统,因此能分配2GB以上的内存。32位操作系统中,每个进程最多只能使用2GB内存。也曾经考虑过启动多个分配2GB以下内存的进程,但这样一台服务器上的TCP连接数就会成倍增加,管理上也变得复杂,所以mixi就统一使用了64位操作系统。

文章的完整内容请见:http://tech.idv2.com/2008/07/31/memcached-005/
0 请登录后投票
   发表时间:2008-09-30  
mikesu 写道
ahuaxuan 写道
搂主这个东西其实我之前也很想做(之前对现在最流行的那个client的性能真的很失望),但是由于很多原因都停下来了,不过有一点我不敢恭维,就是这个client是local+remote的方式,因为互联网的需求是很奇怪的,很多时候我们根本不需要这个local cache嵌入到client中,为什么这么说呢,因为很多场景下mc不只是cache,有时候它是一个remote hashmap,那么我需要其中数据的变化能立刻反应到client中,就像一个内存的berkelyDB一样使用就行了,不过bdb是local的而已。而且加local cache到client中一般来来说java程序员都能自己搞定。


其实楼主的local cache是可以不用的。所以看你的需求来使用,多一个功能并无大碍。

我看楼主源代码中那个MemcacheCache类上的get方法有点问题。如果我put进去的数据是有超时设定的。假如一个客户端出了问题。在数据恢复的时候就会把原来有超时设定的数据变成永久的了。


这个问题是存在的,我也应该在说明中说了,还没考虑好如何实现
0 请登录后投票
   发表时间:2008-09-30  
cenwenchu 写道
mikesu 写道

我看楼主源代码中那个MemcacheCache类上的get方法有点问题。如果我put进去的数据是有超时设定的。假如一个客户端出了问题。在数据恢复的时候就会把原来有超时设定的数据变成永久的了。


这个问题是存在的,我也应该在说明中说了,还没考虑好如何实现


可以在数据流byte[]的前面加入这条数据的超时时间long转换为byte[]。就是每个数据都多出8个byte[]。来存储timeout。读出来的时候再处理。

但我总觉得这样不是很优雅。可惜flag只有16位,不能储存long类型,而且flag还要存放数据的类型信息,否则放在那里最合适。
0 请登录后投票
   发表时间:2008-10-01  
mikesu 写道
cenwenchu 写道
mikesu 写道

我看楼主源代码中那个MemcacheCache类上的get方法有点问题。如果我put进去的数据是有超时设定的。假如一个客户端出了问题。在数据恢复的时候就会把原来有超时设定的数据变成永久的了。


这个问题是存在的,我也应该在说明中说了,还没考虑好如何实现


可以在数据流byte[]的前面加入这条数据的超时时间long转换为byte[]。就是每个数据都多出8个byte[]。来存储timeout。读出来的时候再处理。

但我总觉得这样不是很优雅。可惜flag只有16位,不能储存long类型,而且flag还要存放数据的类型信息,否则放在那里最合适。

这样做对于其他Memcached客户端就无法使用了,破坏了原有协议了,可能不是很好。
3 请登录后投票
论坛首页 Java企业应用版

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