非原创,
转载自:http://blog.163.com/minecz@126/blog/static/62590769201014111316768/
由于工作需要,2年前开始接触分布式的缓存 -- memcache。2年过去了,memcahce也发展了不少,同时也出现许多新星--TT、redis。但万变不离其宗,现将心得总结如下。
先说最早的memcache
这个东西感觉就是个BDB的内存版,就因为是纯内存的程序,所以性能异常的高。现在好像有自己的主页了(http://memcached.org/),记得最早的时候就是danga的个人主页,而且除了一个readme之外就没什么资料了,不过现在这个东西已经遍地开花了。
关于这个东西里面到底应该存放数据网上一直有很多种说法,有的说sql进行md5之后作为键值,结果作为内容存放,也有人说按照业务逻辑错放,反正是炒的不亦乐乎。
本人经过将近2年的实践,最后还是觉得要根据业务逻辑来存放,不能将sql加密然后对应结果集存放。这样做,基本上无法实现数据的及时更新,只能依靠memcahce的过期时间来更新。资讯类的静态数据比较合适,不过这种网站一般会做静态化的处理,所以memcache也发挥不了太大用途。真正有用武之地的地方是社区类网站,这类网站大部分是动态数据,而且性能要求还高,所以memcahce比较合适(貌似memcache本来就为了解决这个问题才被创造出来的)。
如果按照业务来进行存储,很容易控制数据的准确性,一般的程序每种业务都会有自己的底层数据,memcahce部分的操作何以放在这部分代码里。这样对上层程序是透明的,不会将上层的开发工程师搞的晕头转向。
memcache操作的基本逻辑:先检查在mem中是否存在,如果存在,则返回mem中的数据,如果不存在,根据条件到db中查找相应的结果,然后放入mem中,返回结果(如果mem写入失败,需要记录下日志)。这个逻辑有个弊端就是当缓存失效的时候上层程序没有感觉,结果底层程序一直会访问db,很可能导致db宕机,这就是为什么在mem写入失败的时候要记录日志的原因。以上实现了数据的存储,下面讲数据的更新,当db有insert和update操作的时候,需要根据相应的条件找到与之有关的mem键值,然后删除掉(当然您也可以在这个时候直接将修改后的数据放入mem,不过这样做性能就下降了一倍),当下次再有程序检查这个键值的时候,就会发现键值不存在,然后它会从db中再取一份新的数据出来放入mem。这样就实现了数据的被动更新。
为什我要把memcache设计成这样一个被动式更新的方式呢?因为这样做最节省资源。看看cdn的缓存方式就明白了,cdn也是一种被动式的缓存,只有当有用户访问到对应的资源是,cdn才会去检查相应的资源是否存在,不存在了去源站取回资源并缓存在自己这里。如果把memcache设计成主动更新的形式,实在是太浪费资源,因为这样做会有很多基本上没有访问的数据被放入了mem,如果想优化,还需要统计数据的使用率,然后才能决定哪部分数据不放入缓存。实现难度太高。
下面继续深入。存储逻辑清楚了,下面就开始看数据了。大家都知道,不同的业务数据的大小也是不一样的(session的数据基本上都是很小的值,基本上就几十字节,单条用户数据基本不会很大,也就1-3k,资源类的就比较大一点了,相片,投票,分享等基本在1k以上)。为什么说这个呢?这是由memcache的存储机制决定的,memcache存储在内存中的数据并不是有多长存多长的,而是预先定义小的大小,数据优先存放在能够存放的最小的空间里,至于为什么要这样做,大家可以看看memcache的帮助。由于这个实际情况,所以我们必须考虑要存放的数据的实际大小,以免内存被浪费掉(虽然内存都白菜价了,但那也是钱啊)。memcache有个启动参数-f用来控制最小空间的大小,基础空间大小是80b,然后按照80*(1+f)^n这个公式一次计算以后的空间大小。f的默认值是0.25。所以如果存储session数据,那么这个值可以适当的改小,如果存资源类的数据,这个值可以适当的改大,不建议改的太大,那样太浪费空间。其他的参数大家可以看网上的资料就可以学到了,基本上没什难得。
下面再深入,逻辑清楚了,单个进程也完美的启动了,下面是分布式的问题。memcahce的优势除了性能高之外就是分布式的结构了,这个结构可以让性能进一步的提升。既然要分布式,必然要进行hash运算,确定数据的实际存储位置。最初的memcahce只有一个余数的算法,虽然均匀性很好但是在增加以及减少机器的时候,命中率实在是低的可怜,所以后来出现了Consistent Hashing算法。这部分没什么说的,网上资料一大堆(http://ispring.javaeye.com/blog/221355)
到这里基本上程序已经运行起来了,剩下的是维护工作,经常去看看memcache服务器的状态啦,命中率啦,lru值啦,是否内存块存满啦等等,这个基本上是要和运维配合来做的事情了(因为他们有cacti,^_^)。
memcache基本上没什么了,后来出现TT,也是个很不错的东西,和memcahce一样的协议,还能定时将数据写到硬盘上,很好的解决了memcache宕机丢数据的问题。原来的session数据完全就可以挪到TT里了。
redis,这个是个更不错的东西,memcahce,TT的优点它都有,而且据说还更好。而且还有list和set,list和set解决了很多memcahe解决不了的问题,原来做list只能用memcahce做个伪的,要不然就弄个m4q,再不然找个queue软件,还要装,性能还没有redis好。要不是它现在还不太成熟,就可以将大部分缓存迁移到redis上了。不过redis的作者也偷懒,php的客户端竟然有严重bug!!!而且貌似redis的分布式也没有memcahce好。希望今年redis可以多进步点。
分享到:
相关推荐
基于固态硬盘的云存储分布式缓存策略 云存储系统的出现是为了满足海量数据存储的需求,云存储系统需要具备高性能、低延迟、低成本、可扩展性强等特点。为了提高云存储系统的性能,提出了一种基于固态硬盘的云存储...
当业务规模不断扩大,单台机器的存储和处理能力难以满足需求时,就需要引入分布式缓存策略。在这种情况下,Redis可以通过代理服务如Twemproxy来实现数据的分片和负载均衡。 **Twemproxy详解** Twemproxy,又称为...
本体论在分布式缓存策略中的应用可以帮助定义数据之间明确的语义关系,确保数据交换时具有语义的一致性和上下文相关的数据理解。 KNN算法在分布式缓存策略中的作用,则是通过搜索每个请求点的K个最近邻居来优化数据...
然而,由于内存资源有限,缓存数据往往需要根据特定的缓存策略(如最近最少使用(LRU),先进先出(FIFO)等)来淘汰旧数据。 在Go语言实现分布式缓存方面,Go以其简洁的语法和并发性能的优势,成为了开发高性能...
Ehcache的主要优势在于它的快速响应、易用性和丰富的缓存策略。它提供了两种级别的缓存存储:内存和磁盘,这使得即使在内存容量有限的情况下,也能有效地存储大量数据。此外,Ehcache还具备在虚拟机重启后自动将缓存...
4. **缓存策略** Memcached采用LRU(最近最少使用)策略进行缓存淘汰。当内存满时,最不常使用的项将被删除以为新的数据腾出空间。`item.c/h`文件包含了关于缓存项的数据结构和管理逻辑。 5. **并发与线程安全** ...
2. **缓存策略**:根据数据访问模式选择合适的缓存策略,如按需加载、预加载等。 3. **缓存重用**:如果多个作业共享相同的数据,考虑将它们放入缓存,以减少重复的HDFS读取。 学习这份源码,开发者可以理解Hadoop...
为了解决这个问题,本文提出了一种基于变化数据捕获(Change Data Capture, CDC)机制的分布式缓存一致性策略。变化数据捕获是一种监控数据库变化的机制,可以实时地捕捉数据库数据的变化,并触发相应的更新操作。 ...
3. **专业指导**:在分布式缓存的应用实践中,文档可能提供了具体的技术指导,帮助技术人员在云计算环境下更好地实施分布式缓存策略。 ### 部分内容知识点 1. **NoSQL技术的发展**:NoSQL技术的发展与互联网大数据...
由于网络延迟的存在,合理的缓存策略显得尤为关键。在分布式缓存系统中,选择合适的缓存替换算法是提升整体性能的关键。 传统分布式缓存替换算法存在一定的局限性,特别是对于动态数据的处理能力不足。为了解决这个...
分布式缓存是现代Web应用程序中不可或缺的一部分,它能显著提高系统的响应速度和处理能力,减少对后端数据库的依赖。本文将深入探讨Ehcache作为JVM缓存和分布式缓存的角色,以及Redis作为分布式缓存的解决方案,包括...
Redis,作为一个高性能的键值数据存储系统,常被用作分布式缓存,以提升应用程序的性能和响应速度。本文将深入探讨Redis分布式缓存的原理、应用及其优势。 分布式缓存是解决大型互联网应用高并发访问和大数据量存储...
- 调整数据结构和缓存策略:根据业务场景选择合适的数据结构,如使用Set代替List以节省内存。 - 监控与调优:定期检查缓存的性能指标,如命中率、TPS等,及时调整参数。 通过深入理解这些知识点,并结合笔记.docx...
这通常包括设置缓存节点、配置缓存集群、定义缓存策略等步骤。一旦Velocity环境准备就绪,你可以启动MDCAdminTool来监控和管理缓存实例,查看性能指标,进行添加、删除、更新缓存项的操作,以及配置和调整缓存设置。...
而对于读写频繁的场景,则可能需要采用更复杂的缓存策略。 5. 分布式缓存系统的扩展性:云计算环境下,业务规模的快速扩展要求分布式缓存系统能够进行平滑扩展。系统必须设计得足够灵活,以支持水平扩展。 6. 安全...
为了避免这种情况的发生,并提高系统的响应速度和整体性能,采用分布式缓存策略变得尤为重要。本文将详细介绍五种常用的Java分布式缓存框架,帮助开发人员更好地理解如何利用这些工具来优化应用程序。 ### 1. ...
在IT行业中,分布式缓存是一种优化高并发场景下数据访问性能的重要技术,它通过在网络中的多台服务器上分发数据来提高系统的响应速度和可扩展性。本文将深入探讨基于JGROUPS的Ehcache实现的分布式缓存复制,这是一种...
分布式缓存是现代大型互联网应用中不可或缺的一部分,它能够有效地解决单机缓存容量有限以及高并发场景下的数据访问性能问题。本项目基于C#语言实现了分布式缓存系统,提供了详细的类库使用说明,旨在帮助开发者更好...