memcached是应用最广的开源cache产品,它本身不提供分布式的解决方案,我猜想一方面它想尽量保持产品简单高效,另一方面cache的 key-value的特性使得让memcached分布式起来比较简单。memcached的分布式主要在于客户端,通过客户端的路由处理来搭建 memcached集群环境,因此在服务端,memcached集群环境实际上就是一个个memcached服务器的堆积品,环境的搭建比较简单。下面从 客户端做路由和服务端集群环境搭建两方面来谈如何让memcached分布式
客户端做路由
客户端做路由的原理非常简单,应用服务器在每次存取某key的value时,通过某种算法把key映射到某台memcached服务器nodeA上,因此这个key所有操作都在nodeA上,结构图如下所示:
存储某个key-value
取某个key-value
因此关键在于算法的选择,最基本的要求就是能让数据平均到所有服务器上。这自然而然让我想到了hash算法,spymemcached是一个用得比 较广的java客户端,它就提供了一种简单的hash算法,实现类为ArrayModNodeLocator,从key映射到node的源码如下:
- public MemcachedNode getPrimary(String k) {
- return nodes[getServerForKey(k)];
- }
- private int getServerForKey(String key) {
- int rv=(int)(hashAlg.hash(key) % nodes.length);
- assert rv >= 0 : "Returned negative key for key " + key;
- assert rv < nodes.length
- : "Invalid server number " + rv + " for key " + key;
- return rv;
- }
从上面可知它是把所有node放在数组里,通过hash算法把key映射到某index,然后通过这个index在数组里取node
再则需要考虑如何容错,比如当某个node当掉了,如何自动地转到其他node上,上面的简单hash路由策略采用的方法是在数据组里顺序向下轮询node,找第一个工作正常的node即可。
最后要考虑当需要移除node或添加node的时候,如何有效地调整映射关系,这自然又让我们想到一致性hash算法,关于一致性hash算法就不多说,博文分布式设计与开发(二)------几种必须了解的分布式算法 有所涉及,这里可以看看spymemcached是如何利用这个算法来做路由的,实现类为KetamaNodeLocator,从key映射到node的源码如下:
- public MemcachedNode getPrimary(final String k) {
- MemcachedNode rv=getNodeForKey(hashAlg.hash(k));
- assert rv != null : "Found no node for key " + k;
- return rv;
- }
- MemcachedNode getNodeForKey(long hash) {
- final MemcachedNode rv;
- if(!ketamaNodes.containsKey(hash)) {
- // Java 1.6 adds a ceilingKey method, but I'm still stuck in 1.5
- // in a lot of places, so I'm doing this myself.
- SortedMap<Long, MemcachedNode> tailMap=ketamaNodes.tailMap(hash);
- if(tailMap.isEmpty()) {
- hash=ketamaNodes.firstKey();
- } else {
- hash=tailMap.firstKey();
- }
- }
- rv=ketamaNodes.get(hash);
- return rv;
- }
这段代码非常清晰,就是通过ketamaNodes这个数据结构按照一致性hash算法把node分区,每次都把映射到一个分区的key对于到负责这个分区的node上。
从上面几段代码和图示,我们大致能弄明白在客户端如何做路由来让memcached分布式,其实在大多数的项目中,以上这些简单的处理办法就足够了
memcached服务端集群
由上面可知一般的应用中memcached服务端集群不用做太多工作,部署一堆memcached服务器就可以了,大不了就是要做好监控的工作,但 像facebook这样的大型互联网应用,并且又是那么依赖memcached,集群的工作就很有学问了。今年Qcom的会议上facebook就介绍了 是如何通过扩展memcached来应付这么多数据量的,ppt可见Facebook的扩展Memcached实战。 这个PPT比较抽象,我没看得太懂,并且facebook也只是蜻蜓点水,没透露太多的细节,但公司的资深架构师陈大峰同学做了些解析,才多多少少有点眉 目。facebook所有数据的存取都基本上是在memcached上完成,后端的数据库mysql仅仅只是做持久化的作用,由于数据量巨大,做了类似与 mysql的读写分离的结构,结构图如下所示:
其中非常重要的一点,当West的memcached要向East同步数据的时候,它没有采取memcached之间的同步,而是走MySQL replication,如下图所示:
这么做的原因我没法搞得太清楚,大概是比较信赖MySQL replication的简单稳定吧,并且像sns这种应用本身就不需要即时一致性,只要最终一致就行了。
另外在数据分布上是很有讲究的,facebook上面有很多很热的数据,比如LadyGaGa发布一条消息,将会有千万的人收到这个消息,如何把 LadyGaGa和普通的用户同等对待就很可能会把这个memcached节点搞垮,甚至访问冲向后面的数据库后会把数据搞垮,如下图所示:
因此就需要一些策略来控制这些热点数据和热点访问,这些策略细节是什么facebook没说太清楚,一般说来可以把热点数据分布到其他节点,另外对于数据库可以加锁控制流量,只有拿到锁的访问才能直接访问数据库,没拿到的需要等候和竞争。
另外一个数据分布的难题是每个用户可能会有成百上千的好友,而这些好友的数据分布在成百上千台的memcached的节点,这样一个客户端就需要连接成千上万的memcached的节点,如下图所示:
这种问题一般说来可以采取数据重组,把有关联的数据重组在一起,而不是分布在n台机器上。
以上的这些facebook的实践只能说是走马观花地看看了,从我们可以看到一个简简单单memcached也能完成这么多玩样来,可以猜想到 facebook的那些天才工程师们在亿万数据压力下被逼出了多少创新的设计,这些设计不一定适用于我们,不了解情景也没办法深究里面的细节,我们要做的 是围绕我们自己的应用,让memcached玩出点味道来。
相关推荐
【分布式设计与开发基础】 分布式设计与开发是现代软件系统中的关键组成部分,特别是在高可用性、高并发和大规模数据处理的场景下。本篇将探讨几种必须了解的分布式算法,这些算法是解决分布式环境中一致性问题的...
标题中的"session共享 memcached-session-manager 1.9.6 jar"指的正是这个库的特定版本1.9.6,它是与Tomcat 7和8兼容的。`memcached-session-manager`通过将用户的session数据存储在Memcached服务器上,而不是每个...
4. **分布式缓存**:为了降低对数据库的依赖,提升读取速度,项目可能会使用Redis或Memcached等分布式缓存技术,存储频繁访问的数据。 5. **消息队列**:在订单创建、支付处理等关键业务流程中,消息队列(如...
10. **性能优化**:Python-memcached库设计得非常轻量级,它使用最少的网络通信开销,以提高与Memcached服务器之间的通信效率。 Python-memcached库的使用方法相对简单,通常需要导入库,创建客户端,然后通过...
Python-Memcached是一个Python接口,用于与Memcached内存缓存系统进行交互。Memcached是一种高性能、分布式内存对象缓存系统,用于减少数据库负载,通过在内存中存储数据来加速网络应用。这个`python-memcached-...
在本文中,我们将深入探讨Laravel开发中的一个关键组件——`laravel-memcached-plus`扩展。这个扩展针对Laravel5的内置Memcached缓存驱动进行了增强,为开发者提供了更全面的功能,包括持久连接、SASL认证以及自定义...
- **memcached**:Memcached是由Danga Interactive开发的一个开源、高性能、分布式内存对象缓存系统。它主要用于加速动态Web应用,通过将数据存储在内存中,避免了频繁的数据库查询,从而提高了应用的响应速度。 - ...
《Hibernate与Memcached整合详解——基于hibernate-memcached-1.1.0源码分析》 在当今的Web开发领域,数据持久化是一个必不可少的环节,而Hibernate作为Java领域广泛使用的对象关系映射(ORM)框架,极大地简化了...
而Memcached则是一种高性能的分布式内存对象缓存系统,常用于减轻数据库负载,提高网站的响应速度。 "Nagios-Plugins-Memcached-0.02.tar.gz" 是一个针对Nagios的插件包,专门用于监控Memcached服务。这个压缩包...
- `memcached`常与Web开发框架(如PHP、Python、Ruby等)结合使用,提供数据缓存功能。 - 也可以与NoSQL数据库如Redis、MongoDB等搭配,作为它们的缓存层,进一步提升性能。 总结,`memcached-1.5.4`是实现高效...
**hibernate-memcached包** 是一个专为Hibernate框架设计的扩展,目的是将流行的分布式内存缓存系统Memcached整合到Hibernate中,作为其二级缓存解决方案。在大型分布式应用中,缓存技术是提高性能的关键,特别是...
Memcached 是一个高性能、分布式内存对象缓存系统,它广泛应用于Web应用中,用来减轻数据库负载,提高数据访问速度。Memcached的设计理念是简单而快速,通过在内存中存储键值对来提供高速的数据访问。这里我们关注的...
hibernate-memcached, 在Hibernate中,使用Memcached作为第二级分布式缓存的库 休眠 memcachedHibernate中使用Memcached作为第二级分布式缓存的库。基于优秀的spymemcached客户端包含对 Whalin ( danga ) memcached...
2. **Java Servlet会话管理**:在Java Web开发中,Servlet规范定义了会话接口HttpSession,memcached-session-manager 是一个实现该接口的第三方库,允许开发者将默认的基于内存的会话存储替换为分布式存储。...
Memcached是一款高性能的分布式内存对象缓存系统,最初设计用于加速动态网页应用,通过将数据暂存到内存中,减少对数据库的访问,从而提高网站的响应速度。它支持多种编程语言,包括PHP,使得开发者可以轻松地集成到...
六、 Memcached的局限性与替代方案 虽然Memcached在很多场景下表现优秀,但也有其局限性,如不支持持久化、数据安全性较低等。在特定情况下,可能会考虑使用Redis这样的更全面的缓存解决方案,它支持更多的数据结构...
`laravel-memcached-view`是一个针对Laravel5设计的扩展,其核心目标是利用Memcached作为存储引擎,为视图渲染提供更快速的响应。 Laravel是一个流行的PHP web开发框架,以其优雅的语法和强大的功能受到开发者们的...
为了优化这个问题,我们可以使用`memcached-session-manager`,它是一个专门为Tomcat设计的插件,使得Tomcat能够将用户的session数据存储在Memcached服务器上,实现session的分布式管理。 本文将详细介绍如何在...
这表明我们正在处理的是与Memcached相关的开发资源,一个是Windows上的Memcached服务器版本1.2.1,另一个是Java客户端库的release 1.6。 描述中提到,这些资源适用于基于Java的Memcached数据缓存的开发。这暗示我们...