MemberCached 学习上【转】

缘起: 在数据驱动的web开发中,经常要重复从数据库中取出相同的数据,这种重复极大的增加了数据库负载。缓存是解决这个问题的好办法。

Memcached是什么?

Memcached是由Danga Interactive开发的,高性能的,分布式的内存对象缓存系统,用于在动态应用中减少数据库负载,提升访问速度。

Memcache

是什么

Memcache


danga.com

的一个项目,最早是为
LiveJournal

服务的,目前全世界不少人使用这个缓存项目来构建自己大负载的网站,来分担数据库的压力。

它可以应对任意多个连接,使用非阻塞的网络
IO

。由于它的工作机制是在内存中开辟一块空间,然后建立一个
HashTable


Memcached

自管理这些
HashTable

Memcache是高性能的分布式内存缓存服务器。
一般的使用目的是,通过缓存数据库查询结果,减少数据库访问次数,以提高动态Web应用的速度、
提高可扩展性。

为什么会有
Memcache


memcached

两种名称?

其实
Memcache

是这个项目的名称,而
memcached

是它服务器端的主程序文件名,

Memcache

官方网站:
http://www.danga.com/memcached

Memcache

工作原理

首先
memcached

是以守护程序方式运行于一个或多个服务器中,随时接受客户端的连接操作,客户端可以由各种语言编写,目前已知的客户端
API

包括
Perl/PHP/Python/Ruby/Java/C#/C

等等。客户端在与
memcached

服务建立连接之后,接下来的事情就是存取对象了,每个被存取的对象都有一个唯一的标识符
key

,存取操作均通过这个
key

进行,保存到
memcached

中的对象实际上是放置内存中的,并不是保存在
cache

文件中的,这也是为什么
memcached

能够如此高效快速的原因。注意,这些对象并不是持久的,服务停止之后,里边的数据就会丢失。

与许多

cache

工具类似,
Memcached

的原理并不复杂。它采用了
C/S

的模式,在
server

端启动服务进程,在启动时可以指定监听的
ip

,自己的端口号,所使用的内存大小等几个关键参数。一旦启动,服务就一直处于可用状态。
Memcached

的目前版本是通过
C

实现,采用了单进程,单线程,异步
I/O

,基于事件
(event_based)

的服务方式
.

使用
libevent

作为事件通知实现。多个
Server

可以协同工作,但这些
Server

之间是没有任何通讯联系的,每个
Server

只是对自己的数据进行管理。
Client

端通过指定
Server

端的
ip

地址
(

通过域名应该也可以
)

。需要缓存的对象或数据是以
key->value

对的形式保存在
Server

端。
key

的值通过
hash

进行转换,根据
hash

值把
value

传递到对应的具体的某个
Server

上。当需要获取对象数据时,也根据
key

进行。首先对
key

进行
hash

,通过获得的值可以确定它被保存在了哪台
Server

上,然后再向该
Server

发出请求。
Client

端只需要知道保存
hash(key)

的值在哪台服务器上就可以了。

其实说到底,
memcache
的工作就是在专门的机器的内存里维护一张巨大的
hash
表,来存储经常被读写的一些数组与文件,从而极大的提高网站的运行效率。

memcached的特征

memcached作为高速运行的分布式缓存服务器,具有以下的特点。

  • 协议简单
  • 基于libevent的事件处理
  • 内置内存存储方式
  • memcached不互相通信的分布式

协议简单

memcached的服务器客户端通信并不使用复杂的XML等格式,
而使用简单的基于文本行的协议。因此,通过telnet
也能在memcached上保存数据、取得数据。下面是例子。

$ telnet localhost 11211
Trying 127.0.0.1...
Connected to localhost.localdomain (127.0.0.1).
Escape character is ‘^]‘.
set foo 0 0 3     (保存命令)
bar               (数据)
STORED            (结果)
get foo           (取得命令)
VALUE foo 0 3     (数据)
bar               (数据)

协议文档位于memcached的源代码内,也可以参考以下的URL。

基于libevent的事件处理

libevent是个程序库,它将Linux的epoll、BSD类操作系统的kqueue等事件处理功能 封装成统一的接口。即使对服务器的连接数增加,也能发挥O(1)的性能。 memcached使用这个libevent库,因此能在Linux、BSD、Solaris等操作系统上发挥其高性能。 关于事件处理这里就不再详细介绍,可以参考Dan Kegel的The C10K Problem。

内置内存存储方式

为了提高性能,memcached中保存的数据都存储在memcached内置的内存存储空间中。 由于数据仅存在于内存中,因此重启memcached、重启操作系统会导致全部数据消失。 另外,内容容量达到指定值之后,就基于LRU(Least Recently Used)算法自动删除不使用的缓存。 memcached本身是为缓存而设计的服务器,因此并没有过多考虑数据的永久性问题。 关于内存存储的详细信息,本连载的第二讲以后前坂会进行介绍,请届时参考。

memcached不互相通信的分布式

memcached尽管是“分布式”缓存服务器,但服务器端并没有分布式功能。 各个memcached不会互相通信以共享信息。那么,怎样进行分布式呢? 这完全取决于客户端的实现。本连载也将介绍memcached的分布式。

Memcached能缓存什么?

通过在内存里维护一个统一的巨大的hash表,Memcached能够用来存储各种格式的数据,包括图像、视频、文件以及数据库检索的结果等。

Memcached快么?

非常快。Memcached使用了libevent(如果可以的话,在linux下使用epoll)来均衡任何数量的打开链接,使用非阻塞的网络I/O,
对内部对象实现引用计数(因此,针对多样的客户端,对象可以处在多样的状态), 使用自己的页块分配器和哈希表,
因此虚拟内存不会产生碎片并且虚拟内存分配的时间复杂度可以保证为O(1).。

Danga Interactive为提升Danga
Interactive的速度研发了Memcached。目前,LiveJournal.com每天已经在向一百万用户提供多达两千万次的页面访问。而这
些,是由一个由web服务器和数据库服务器组成的集群完成的。Memcached几乎完全放弃了任何数据都从数据库读取的方式,同时,它还缩短了用户查看
页面的速度、更好的资源分配方式,以及Memcache失效时对数据库的访问速度。

Memcached的特点

Memcached的缓存是一种分布式的,可以让不同主机上的多个用户同时访问, 因此解决了共享内存只能单机应用的局限,更不会出现使用数据库做类似事情的时候,磁盘开销和阻塞的发生。

Memcached的使用

一 、Memcached服务器端的安装 (此处将其作为系统服务安装)

下载文件:memcached 1.2.1 for Win32 binaries (Dec 23, 2006)

1 解压缩文件到c:\memcached

2 命令行输入 ‘c:\memcached\memcached.exe -d install‘

3 命令行输入 ‘c:\memcached\memcached.exe -d start‘ ,该命令启动 Memcached ,默认监听端口为 11211

通过 memcached.exe -h 可以查看其帮助

ps:安装时报错误的话,如果是WIN7系统,那么用管理员身份进入CMD模式,找到CMD.EXE,用右键选择管理员模式进入就可以了。

memcached.exe -p 11211 -m 64m -vv    
-p 使用的TCP端口。默认为11211
-m 最大内存大小。默认为64M
-vv 用very vrebose模式启动,调试信息和错误输出到控制台
-d
作为daemon在后台启动

-d restart 重启memcached服务

-d stop|shutdown 关闭正在运行的memcached服务

-M 内存耗尽时返回错误,而不是删除项

-c 最大同事连接数,默认是1024

-f 块大小增长因子,默认是1.25

-n 最小分配空间 key+value+flags默认是48

-h 显示帮助

二、客户端使用

下载memcached java client:http://www.whalin.com/memcached/#download

1 解压后将java_memcached-release_2.0.1.jar jar包添加到工程的classpath中

2 利用memcached java client 一个简单的应用

Java代码

  1. public class TestMemberCache {
  2. // 创建全局的唯一实例
  3. protected static MemCachedClient mcc = new MemCachedClient();
  4. static {
  5. // 服务器列表和其权重
  6. String[] servers = { "127.0.0.1:11211" };
  7. Integer[] weights = { 3 };
  8. // 获取socke连接池的实例对象
  9. SockIOPool pool = SockIOPool.getInstance();
  10. // 设置服务器信息
  11. pool.setServers(servers);
  12. pool.setWeights(weights);
  13. // 设置初始连接数、最小和最大连接数以及最大处理时间
  14. pool.setInitConn(5);
  15. pool.setMinConn(5);
  16. pool.setMaxConn(250);
  17. pool.setMaxIdle(1000 * 60 * 60 * 6);
  18. // 设置主线程的睡眠时间
  19. pool.setMaintSleep(30);
  20. // Tcp的规则就是在发送一个包之前,本地机器会等待远程主机
  21. // 对上一次发送的包的确认信息到来;这个方法就可以关闭套接字的缓存,
  22. // 以至这个包准备好了就发;
  23. // 设置TCP的参数,连接超时等
  24. pool.setNagle(false);
  25. pool.setSocketTO(3000);
  26. pool.setSocketConnectTO(0);
  27. // 初始化连接池
  28. pool.initialize();
  29. // 压缩设置,超过指定大小(单位为K)的数据都会被压缩
  30. mcc.setCompressEnable(true);
  31. mcc.setCompressThreshold(64 * 1024);
  32. }
  33. public static void bulidCache() {
  34. // set(key,value,Date) ,Date是一个过期时间,如果想让这个过期时间生效的话,这里传递的new Date(long
  35. // date) 中参数date,需要是个大于或等于1000的值。
  36. // 因为java client的实现源码里是这样实现的 expiry.getTime() / 1000 ,也就是说,如果
  37. // 小于1000的值,除以1000以后都是0,即永不过期
  38. mcc.set("test", "This is a test String", new Date(10000));
  39. mcc.set("test", "This is a test String111", new Date(10000));// 十秒后过期
  40. User u = new User();
  41. u.setUsername("aaaa");
  42. mcc.set("user", u);
  43. User u1 = (User) mcc.get("user");
  44. System.out.println(u1.getUsername());
  45. // add 當這個 key 不存在的時候才保存 value
  46. // replace 當 key 相同的時候才替換 value
  47. // set 直接寫入新的 value ,如果 key 存在就是替換 value
  48. }
  49. public static void output() {
  50. // 从cache里取值
  51. String value = (String) mcc.get("test");
  52. System.out.println(value);
  53. }
  54. public static void main(String[] args) {
  55. bulidCache();
  56. output();
  57. }
  58. }

输出结果为:

aaaa

This is a test String111

转载自http://zy116494718.iteye.com/blog/1664190

MemberCache及其他缓存等相关知识:

1)JBOSS CACHE, EHCACHE,
等JAVA写成的CACHE,一般都是和主程序在同一机器上,内存直接访问,比memcached要快。但如果有多个server,每个server都有
自己的一份cache,要采用一些notification or replicate机制才能synchronize。而且,cache
size受制于heap size setting。memcached 运行在主程序以外的机器上,通过网络访问来传递数据。因为是专门的server,所以size不受限制。如果cache data 不大(300MB以下?),无须用memcached.

2)memcached组成它的n台机器里有一个down了,并不会整个挂掉,只会访问某些cache内容无法命中,就算全部挂掉,Cache就是减少对数据库访问的,所以无非就是对数据库压力大一些而已,如果希望Cache持久化,或者带有故障切换功能,可以用memcachedb。

3)Cache Server的可靠性比DB Server还要高

4)memcached 要求set的对象必须是可序列化对象,jboss cache等java obect cache是没有这个说法的,这是本质的不同的,但是他可以在网络上用,所以必须序列化也可理解

5)memcached 并发连接可以上到1w,我手头的应用常常保持在3-5k;它的快不仅是因为用了libevent,还因为它采取了“用内存冗余换存取速度”的内存管理策
略,网上有文章专门分析它的内存分配回收管理的源码,讲的很清楚,在这上面jboss
cache、ehcache、oscache跟它没法比;memcached的集群也非常好,听说国外有200+的memcached集群,我们也有这方
面的尝试,效果也很好,一台down掉根本不会引起其他机器down掉,只是这台的数据丢了,需要慢慢积累回来;而且支持多客户端,java、php、
python、ruby可以共享数据,就把它当作数据库用。

我的建议是:你的应用访问量比较大,对响应速度要求很高,对数据一致性要求一般时,用它,挡在数据库前面,非常爽(memcached是互联网公司开发的,正好满足这三个条件);如果应用不忙,用用ehcache就行了。

6)ehcache、oscache
的数据都是在本机服务器上的,访问时走的仅是系统总线。而memcached走的是网络。关于传输速度来讲我们的应用读取memcached的网络流量是每秒有2MB的流量,是读取数据库的网络流量的大约5倍。但是你要知道现在随便的PC机都是千兆网卡,因此
memcached的get/set操作的延时非常少,并不比echache的get/set慢多少。在一个完整的web应用当中,我的压力测试表明,性
能差异 <= 5%

7)论坛、sns这样的应用,会使用多种技术进行缓存。

拿sohu的bbs来说吧,pv为5000w,峰值8000w

其中帖子、评论读写频繁,其他部分读频繁。

帖子列表、评论列表使用c开发(其中排序算法很巧妙),socket调用

帖子、评论内容使用squid缓存

其他读频繁的部分使用memcached、squid、定时生成静态页面等多种技术。

数据库用mysql,分表。

个人认为,小规模应用中,jvm级别的cache可以用用,memcached可用可不用

大规模网站应用,肯定是系统水平切分,多种cache结合。

8)memcached非常快,但我没说过比本机的ehcache还快,但用本地缓存有两点不爽:

1.缓存放在内存or放在磁盘?应用重启会导致内存缓存丢失,放在磁盘又不够快。内存开多大合适?如果是大访问量应用,缓存对象集中淘汰可能引起服务器load急剧波动(我们吃过亏,现在也开ehcache,但缓存对象的上限开的很小)

2.集群应用里缓存对象如何共享?jboss cache用的是广播,访问量大的时候,可以把你的服务拖死,这个我们也吃过亏

当然,有人谈到了sohu的例子,一旦访问量大了,各种缓存都得用着,目前我们就是squid + memcached + ehcache。squid也是好东西,但缓存内容删除不太灵活,比较适合web1.0,比如新浪搜狐的新闻

另外,java memcached client用1.6好了,没必要升级到2.1,2.X似乎还不太稳定。

时间: 2024-10-29 03:58:43

MemberCached 学习上【转】的相关文章

李笑来老师在《把时间当作朋友》曾说过:“所有学习上的成功,都只靠两件事:策略和坚持,而坚持本身就应该是最重要的策略之一

高效编程=工具+方法+体系+专注 前面根据个人的经验,分享了一些提高编程效率的个人心得.每个人的经历经验不尽相同,相信其实每个人心中都有一份自己的清单.但最最重要的是坚持投入,不断地练习.练习.练习.练习.练习…… 这里引用最近看到的名言自我勉励一下,来自Bruce Lee李小龙: “I fear not the man who has practiced 10,000 kicks once, but I fear the man who has practiced one kick 10,00

学习上的思考与心得

由于这段时间在c语言的学习中,表现的很努力并且完成作业态度认真,所以得到了老师奖励的小黄衫. 以下是我对于c语言的学习感受与心得. 学习感受与心得 我选择计算机的这个专业,是因为我对计算机的学习很有兴趣.c语言是我以前从来没有接触过.也没有了解过的,所以当我知道要学习c语言的时候,我是有一些紧张的.当我看到书上的一堆代码,我害怕学不会,学不懂.但当我上完第一次课时,我发现c语言其实并没有想象中的那么遥远,那么不可接近,通过几次简单的实验练习,就可以记住它的大致结构.在运用c-free时,它也会提

学习上的感悟

软件工程,顾名思义,是一门用工程化的思想去开发软件的学科.它实际上是一个工程,并不是大多数人所以为的,软件工程就是开发软件这么简单,写写语言代码这么幼稚. 数学和算法以及基础课,在计算机领域中极其的重要,是我们最需要学好的!前段时间,曾经看到有篇文章,大致讲的是,现在的开发都是基于新技术.基于框架.基于封装进行开发,花时间去学数学呀,算法呀,基础课的话,真的没什么必要,因为,开发的时候,根本就用不到!说实话,从完成软件产品的角度来说的话,还真是,因为我大二做了一年的项目,所以做项目的流程也非常清

ASP.NET MVC Model验证学习—上

蒋大师的MVC框架解析确实是越学越有趣,即使是跟着学写些示例代码也是收获良多,尤其是关于类型.反射和委托等方面,平时在应用开发中确实很少会有机会写这样的代码.今天学习的ASP.NET MVC中的Model的验证,刚开时会以为这一章会比较简单,因为之前已经学习过了Model元数据的解析.Model绑定,Model的验证可能就只是DataAnnotation相关类的介绍.但实际学习的过程中,尤其是自定义用于修饰Action的验证特性让我到现在仍然感觉是比较萌萌哒,毕竟这一块对于框架的扩展基本上涉及到

Hearbeat 学习 上

官方网址:http://linux-ha.org/wiki/Main_Page     Hearbeat 简介  Hearbaet 一款开源高可用(Highly-Available)服务的软件,通过hearbeat,  可以将资源(ip及程序服务等资源)从一台已故障的计算机快速转移到另一台正常运转的机器上继续提供服务,一般称之为高可用服务.在实际成产应用场景中,heartbeat的功能和另一个高可用开源软件keeplived有很多相同之处,但在生产中,对应实际的业务应用也是有区别的,例如:kee

SpringMVC 学习-上传文件分解器 CommonsMultipartResolver 类

Spring 组件 CommonsMultipartResolver 类的主要作用是配置文件上传的一些属性,也可以控制上传文件的大小. 在 springmvc-servlet.xml 配置文件中: <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver"> <property name="d

oc学习上自己遇到的问题

遇到问题:p只是一个指针,怎么能代表整个对象 , 操作上这样的语句[p 方法]让我理解不了? Car *p = [Car new]; 返回的是Car类型的地址,所以用指向Car类型的指针接收 理解方式一: 定义了一个Car类型的指针变量 指针变量指向新申请的内存空间 理解方式二: 用Car类实例化了一个实例对象,对象的名称是p 比较奇怪的是这二种说法竟然能统一起来,p是指针,也竟然是对象名,代表了创建的对象,难度只能硬记. 遇到问题02: 字符串后面跟的是0还是\0 多态实质要深入内存考虑,但仍

5月学习月~比拼学习 上浮力

5月学习月活动 一.活动对象 所有微职位学员 二.活动时间 2018年5月7日-2018年5月27日 (合计三周,21天) 三.活动目标 提升大家的学习能力,形成被动学习变成主动学习的好习惯.通过学习排行榜的学习时长数据排名 能激发大家学习的积极性和主动性,能更好的促进大家进行深度学习. 四.活动规则 (1)班级学习时长排行榜每周一(14.21.28日)发布:班级学习时长前10名同学 (2)学院学习时长排行总榜 (29日)发布:计算(5月7日-5月27日)每个班学员的学习时长数据,计算微职位的排

Python学习—面向对象学习上

面向对象简介 OOP编程是利用"类"和"对象"来创建各种模型来实现对真实世界的描述,使用面向对象编程的原因一方面是因为它可以使程序的维护和扩展变得更简单,并且可以大大提高程序开发效率 ,另外,基于面向对象的程序可以使它人更加容易理解你的代码逻辑,从而使团队开发变得更从容. 面向对象的三大特性 Encapsulation 封装把客观事物封装成抽象的类,并且类可以把自己的属性和方法只让可信的类或者对象操作,对不可信的进行信息隐藏.注意的是.这里说的属性并不仅仅是基本数据