QCon 演讲火热征集中,快来分享技术实践与洞见! 了解详情
写点什么

Memcached 的 JGroups 实现支持失败转移和 JMX

  • 2008-10-10
  • 本文字数:2982 字

    阅读完需:约 10 分钟

Memcached 是一个分布式内存对象缓存系统, 用于动态 Web 应用以减轻数据库负载。它通过在内存中缓存数据和对象来减少读取数据库的次数,从而提高动态、数据库驱动网站的速度。Memcached 基于的是一个存储键 / 值对的 hashmap。其守护进程(daemon )是用 C 写的,但是客户端可以用任何语言来编写,并通过 memcached协议与守护进程通讯。但是它并不提供冗余(例如,复制其hashmap 条目);当某个服务器S 停止运行和崩溃了,所有存放在S 上的键/ 值对都将丢失。

Bela Ban, JBoss JGroups 和 Clustering 团队的领导,最近写了一个基于 JGroups 的 memcached实现,它允许 Java 客户端直接访问 memcached。该实现完全是用 Java 编写的,而且拥有少量优于 memcached 框架的特性 :

  • Java 客户端和 PartitionedHashMap(org.jgroups.blocks.PartitionedHashMap)可以在同一地址空间运行,因此不需要使用 memcached 协议进行通信。这使得 servlet 可以直接访问缓存,而不需要在其上进行序列化。
  • 所有 PartitionedHashMap 进程彼此知道对方,当一个集群成员发生改变时,它们能够决定做什么。例如,一个要停止服务的服务器可以把它管理的所有键都迁移到下一个服务器。使用 memcached,存 放在 S 服务器上的条目在 S 关机的时候就丢失了。
  • 当一个集群成员发生改变时(例如,一个新服务器 S 启动了),那么所有服务器都检查自己所保存的一个条目事实上是否应该存放在 S 上。它们会把所有条目都转给 S。这样的好处是不需要再次从 DB 中 重新读取这些条目并插入到缓存中(memcached 正是这么做的),但是缓存要自动地使自己重新达到平衡 。
  • PartitionedHashMap 拥有一个一级缓存(level 1 cache——L1 cache)。这就可以使缓存的数据离真正需要它的地方很近。例如,如果我们拥有 A、B、C、D 和 E 几个服务器,且一个客户端给 C 增加了一个(要被高度访问的)报纸文章,那么 memcached 总是把所有对该文章的单一请求都转给 C。这样,一个正在访问 D 的客户端总是会触发一个从 D 到 C 的 GET 请求,并返回一篇文章。JGroups 在第一次访问时把这 篇文章缓存在 D 的 L1 缓存中,这样所有从 D 访问这篇文章的其它客户端将获得这个被缓存的文章,因而我 们可以避免又一轮对 C 的访问。注意,每个条目都有其失效时间,它将导致该条目在失效时被从 L1 缓存中删除,那么下一个访问将不得不重新从 C 获取该文章并再次把它放在 D 的 L1 缓存中。这个失效时间是由该文章的提交者定义的。
  • 因为 GET、SET 和 REMOVE 的 RPC 都使用 JGroups 作为传输,传输的类型和服务的质量可以通过定义传输的底层 XML 文件来控制和定制。例如,我们可以压缩或者加密所有 RPC 信息。它还让我们可以选用 UDP (IP 多点传送和 / 或 UDP 数据报)或 TCP。
  • 连接器(org.jgroups.blocks.MemcachedConnector)负责分析 memcached 协议并调用 PartitionedHashMap 上的请求(PartitionedHashMap 代表了 memcached 的实现),服务器 (org.jgroups.demos.MemcachedServer)和 L1 及 L2 缓存(org.jgroups.blocks.Cache)可以被随意装配或替代。因此定制 JGroups memcached 实现很简单;比如使用一个不同的 MemcachedConnector 来处理二进制协议(当然需要与客户端代码匹配)。
  • 所有管理信息和操作经由 JMX 被暴露。

启动 JGroups memcached 实现的主类是 org.jgroups.demos.MemcachedServer。它创建了一个 L1 缓存( 如果配置了)、一个 L2 缓存(存储所有条目的默认 hashmap)、以及一个 MemcachedConnector。API 非常 简单且包含如下缓存方法:

  • public void put(K key, V val):按照默认的缓存时间把键 / 值对存入缓存
  • public void put(K key, V val, long caching_time):与上面方法相同,但是可以定义缓存失效时间。0 表示永远缓存,-1 表示不缓存,任何正值代表了该条目要缓存的毫秒数
  • public V get(K key):获得键 K 所对应的值
  • public void remove(K key):从缓存(L2 及 L1,如果启用的话)中删除一个键 / 值对

InfoQ 就 memcached 的 JGroups 实现背后的动机采访了 Bela Ban。他说 memcached 的 JGroups 实现使得他们可以试验分布式缓存并看看不同的缓存策略适应 JBoss 集群的程度如何。他还阐明了这个新的 memcached 实现与 JBossCache 缓存框架的比较:

我们把缓存看作是一个连续统一体:从分布式缓存(数据跨越集群中多个节点,但是没有 冗余)到完全复制数据缓存(每个数据条目整体复制到每个集群节点上)。在分布式和整体复制之间, 我们还有 buddy replication ,它只把数据复制到一些选定的后备节点上。这可以被比作 RAID,RAID 0 没有冗余(分 布式),RAID 0+1 是全冗余,而 RAID 5 是部分冗余。当前,JGroups 的 PartitionedHashMap 提供了分布式缓存,JBossCache 提供了全复制和部分复制(使用 Buddy Replication)缓存。其想法是让用户定义他们要放在集群中的 K(每个数据项——per data item )值,K=0 表示分布式,但是如果一个节点保存有一个或多个条目,节点崩溃则数据就会丢失;K=X(这 里 X

memcached 的 JGroups 实现是尝试 K=0 的第一步,它是纯数据分布式缓存,没有冗余。其最终会被纳入到 JBossCache 中。

memcached 实现适合放在 JBoss 应用服务器的哪个模块?

它将成为 Clustering 子系统的一部分,由 JBossCache 提供。注意我们的实现是真正给“Java”客户端写的,因此不必使用那些非常低效的 memcached 协议,而是在上层使用了编组 (marshalling)/ 解读(unmarshalling)/ 复制(copying)。

谈到使用 memcached 的 JGroups 实现的典型使用场景,Bela 说道:

运行在 JBoss 或 Tomcat 集群上的服务器端代码(例如 servlets),其访问一个 DB 并需要缓存以提高速度并避免 DB 瓶颈。其它使用场景也类似,只是访问的不是 DB 而是文件系统。例如,一个 HTML 页面缓存服务器(Squid 立刻浮现在脑海里)。

有无计划将来把 memcached 引入到 JBoss 应用服务器中。

当然有。数据分区( Data Partitioning)特性将使得用户可以按照自己的需要来配置缓存。这样使得分布式缓存看上去 不像是一个新特性,而是 JBossCache 的配置而已。更酷的是这是动态的,因此开发者可以决定他们所放 进 JBossCache 的每个数据项(per data item)要使用哪种冗余特性(none=distribution,full=total replication 或 partial)。

至于该项目新特性的未来方向,Bela 罗列了要做的一些事情:

  • 基于缓存中的字节数而不是元素数提供一种逐出策略。
  • 把从远端服务器接受到元素存储为 byte[] buffer 而不是对象。在第一次访问时,把 byte buffer 解读成对象。这在 JBoss 的 HTTP 会话复制代码中被使用且一直表现良好:因为不需要解读过程因此不会影响到性能。
  • 实现全部 memcached 协议:现在我只提供 GET、GET-MULTI、SET 和 DELETE。尽管其它的(APPEND 、PREPEND、CAS)很容易实现,但是我还没有做,因为 Java 客户端的主要使用场景位于我们 memcached 实现的同一 JVM 中,因此不需要 memcached 协议。
  • 提供一个更好的一致散列的实现。

memcached 的 JGroups 实现和其依赖类库可以从其 sourceforge 站点上下载。下面是运行该程序的命令:

java -jar memcached-jgroups.jar<br></br>Bela 正在期待着社区的反馈。他说这是一个试验特性,但是将成为 JBossCache 支持的一个特性,社区意见将会极大影响这一特性的方向。

查看英文原文: JGroups Implementation of Memcached Supports Failover and JMX

2008-10-10 22:062578
用户头像

发布了 150 篇内容, 共 46.6 次阅读, 收获喜欢 10 次。

关注

评论

发布
暂无评论
发现更多内容

BATJ互联网月薪38K的Java岗面试题首曝光,掌握这些大厂Offer指定跑不了

程序知音

Java java面试 后端技术 秋招 Java面试八股文

iMazing高效便捷的数据转移功能

淋雨

ios iphone

iMazing怎么恢复备份?iMazing恢复备份教程分享

淋雨

ios iphone

StratoVirt 中的 PCI 设备热插拔实现

openEuler

开源 操作系统 虚拟机 openEuler

小程序容器,组装式应用的一种方案

Geek_99967b

小程序

Java高手怎样炼成?阿里大牛一份火爆GitHub的1046页笔记帮你解决

钟奕礼

Java 程序员 架构 后端 java面试

一次 Rancher 和 openEuler 的上云之旅

openEuler

Linux 开源 openEuler rancher suse

概述服务网格的优劣势

穿过生命散发芬芳

服务网格 9月月更

22年程序员更卷了,金九银十“面试必备小册”最新开源

程序知音

Java 阿里 后端技术 秋招 Java面试题

面试凉凉,阿里学长甩我一份24w字Java核心技术面试手册,真香

钟奕礼

Java 架构 后端 java面试

2021 金三银四面试必备?体系化带你学习:分布式进阶技术手册

钟奕礼

Java 架构 后端 java面试

openEuler 资源利用率提升之道 04:CPU 抢占和 SMT 隔离控制

openEuler

开源 openEuler

【云原生 | 从零开始学Kubernetes】十一、k8s污点、容忍度和pod状态

泡泡

Docker 云计算 云原生 k8s 9月月更

小程序怎样影响传媒产业的数字化

Geek_99967b

小程序

开源实习 | 毕昇JDK发布国密算法实习任务

openEuler

开源 openEuler 毕昇 JDK

开源之夏 | 【结项报告】毕昇Fortran编译器内联动态库函数str_copy

openEuler

开源 操作系统 openEuler 毕昇 JDK

别让你的 SaaS 产品由赋能变为“负能”

产品海豚湾

产品设计 产品运营 SaaS平台 B端产品 9月月更

阿里面试官内部题库,阿里发布2022年Java岗(正式版)面试题

程序知音

Java java面试 后端技术 秋招 Java面试八股文

八家知名大厂联合手写的Java面试手册刚上线!竟就到达巅峰?

钟奕礼

Java 架构 后端 java面试

如何在笔记本上安装openEuler 22.03 LTS

openEuler

开源 操作系统 openEuler

面试突击87:说一下 Spring 事务传播机制?

王磊

Java 面试

测试开发面试真题 | 测试老兵进阶突破,成功挑战大厂 P7 Offer!

测吧(北京)科技有限公司

测试

从规模化平台工程实践,我们学到了什么?

SOFAStack

从融云社交泛娱乐出海白皮书,看「社交+X」的全球攻略

融云 RongCloud

即时通讯 白皮书 泛娱乐社交

阿里被转载上100W次的Java面试题教程!已助我拿下9家大厂offer!

钟奕礼

Java 架构 后端 java面试

GitHub获百万推荐的面试涨薪秘籍(Java岗)惨遭封杀?

钟奕礼

Java 后端 java面试 后端架构

Embedded SIG | 树莓派的UEFI支持和网络启动

openEuler

开源 树莓派 操作系统 openEuler

公司内部分享文档应该怎么写?看这篇就够了

Baklib

数据治理的核心:维度建模下的数仓构建

Taylor

数据仓库 维度建模 维度 数仓分层 分层划域

编译器优化那些事儿(6):别名分析概述

openEuler

开源 编译器 openEuler 毕昇 JDK

揭开HPC应用的神秘面纱

openEuler

开源 openEuler

Memcached的JGroups实现支持失败转移和JMX_Java_Srini Penchikala_InfoQ精选文章