前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >如何编写一个 Java memcached 客户端

如何编写一个 Java memcached 客户端

作者头像
勇哥java实战分享
发布2024-07-08 16:17:47
1010
发布2024-07-08 16:17:47
举报
文章被收录于专栏:勇哥编程游记

非常喜欢读开源项目,每次读源码,都会觉得自己修炼某种武学功法,期待修炼完成后,可以大杀四方。

从2012年开始,陆续阅读了 Cobar、Druid、Xmemcached、RocketMQ、MetaQ、Canal、ShardingJdbc、Sofa-Jraft 等开源项目。

这篇文章,聊聊笔者阅读 Xmemcached 源码的心得体会,希望对大家有所帮助。

1 Xmemcached 简介

XMemcached 是一个 Java memcached 客户端。

可能有的同学对 Memcached 并不熟悉,它和 Redis 一样都是分布式内存缓存系统,用于加速动态 Web 应用程序,通过减少数据库负载来提高性能 。

笔者当时服务于一家彩票公司,公司的核心系统订单服务、调度中心、业务网关都使用 XMemcached 操作 memcached 。

基于一个非常朴素的好奇心:“如何用 Java 编写一个缓存客户端 ?” 笔者花了接近两个月的时间将 Xmemcached 源码浏览了一次。

浏览完源码后,笔者有三点心得:

  • 设计模式
  • 网络命令编解码
  • 一致性哈希算法

2 设计模式

下图是 Xmemcached 的使用范例:

我们可以清晰的发现流程分为三个部分 :

  • 客户端构造器通过 servers 参数创建客户端 ;
  • 通过客户端调用 set、 get、 delete 方法 ;
  • 关闭客户端。

MemcachedClient 接口定义了基本的缓存操作方法,比如 get、set、add 、cas 方法,而 XmemcachedClient 是 MemcachedClient 的实现类。

真正创建客户端对象 XmemcachedClient 是通过构造器 XMemcachedClientBuilder 来实现的,这是一个非常典型的设计模式:Builder 模式

Builder 模式是一种创建型设计模式,它允许你分步骤创建复杂对象。与直接构造对象不同,Builder 模式通过一个构建过程,逐步设置对象的不同部分,从而使对象的创建过程更加灵活和可控。

我们在配置 构造器 XMemcachedClientBuilder 时,可以配置序列化对象、命令工厂、服务器列表等配置。

最后,调用构造器的 build 方法创建 MemcachedClient 对象,见下图:

下面是 XMemcached 的主要类的 UML 图:

3 网络命令编解码

在网络编程中,一个重要的步骤是对发送的数据包进行编码、对接受的数据包进行解码

1、发送命令,进行编码

因为 Xmemcached 使用了自研的网络通讯框架 ,每次发送命令时,都会调用命令的 encode 方法,将命令对象转换成 IoBuffer 对象通过网络发送。

下图是 TextGetOneCommand 的 encode 方法 :

2、接收命令,进行解码

当通讯框架收到响应字节数组时,可能收到的数据包并不完整,在收到数据包时,通过 decode 方法判断数据包是否完整,当数据完整之后,将同步请求的 countDownLatch 计数减 1 。


当笔者理解了网络命令编解码的技巧之后,后来用 Netty 写了个分库分表 proxy 轮子时,在设计 MySQL 命令包编解码就使用了类似的技巧。

4 一致性 Hash 算法

一致性 Hash 算法非常典型的应用就是缓存集群,它能够很大程度上(注意不是完全解决)解决余数哈希的增加服务器导致缓存失效的问题。

我们需要进行如下步骤,使用一致性哈希(Consistent Hashing)将键值对映射到 memcached 服务器上。

  1. 计算 memcached 服务器(节点)的哈希值,并将其配置到 0~2^32 的圆上。
  2. 用同样的方法计算存储数据的键的哈希值,并映射到圆上。
  3. 从键的哈希值对应的位置开始顺时针查找,将数据保存到找到的第一个服务器上。
  4. 如果超过 2^32 仍然找不到服务器,就会保存到第一台 memcached 服务器上。

下图,我们新增一台 memcached 服务器 node5 。

img

假如是我们使用余数分布式算法,保存键的服务器会发生很大变化从而影响缓存的命中率,但一致性哈希算法仅仅如图中所示 node2 和 node 5 之间小部分黄色区域会有影响。

KetamaMemcachedSessionLocator.java 实现了一致性哈希算法, 使用的 Hash 算法是 KETAMA HASH 算法。

1、根据服务器列表生成 Hash 环 ,存储容器 TreeMap

2、通过 key 得到 TreeMap 的 tailMap,然后找到 firstKey

5 写到最后

阅读 Xmemcached 源码,让笔者的眼界大大提升,比如序列化方式、构造器 Builder 设计模式、一致性哈希算法、通讯命令编解码、failover 设计等等。

比较可惜的是,笔者当时能力有限,并没有完全理解自研网络框架 yanf4j 。

尽管如此,当读完 Xmemcached 源码后,笔者对于“如何用 Java 编写一个缓存客户端 ?” 这个问题,脑海里已经有了概念,当笔者对于 Netty 更加熟悉之后,这个问题也就变得不是问题了。

对于 Xmemcached 源码作者,笔者也一直抱着非常欣赏和学习的态度,他的另外一个非常有名的作品 MetaQ ,笔者也阅读过多次,颇有心得,改天和大家分享。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2024-07-03,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 勇哥java实战分享 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1 Xmemcached 简介
  • 2 设计模式
  • 3 网络命令编解码
  • 4 一致性 Hash 算法
  • 5 写到最后
相关产品与服务
云数据库 MySQL
腾讯云数据库 MySQL(TencentDB for MySQL)为用户提供安全可靠,性能卓越、易于维护的企业级云数据库服务。其具备6大企业级特性,包括企业级定制内核、企业级高可用、企业级高可靠、企业级安全、企业级扩展以及企业级智能运维。通过使用腾讯云数据库 MySQL,可实现分钟级别的数据库部署、弹性扩展以及全自动化的运维管理,不仅经济实惠,而且稳定可靠,易于运维。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档