300分钟吃透分布式缓存-13讲:如何完整学习MC协议及优化client访问?

协议分析

异常错误响应

接下来,我们来完整学习 Mc 协议。在学习 Mc 协议之前,首先来看看 Mc 处理协议指令,如果发现异常,如何进行异常错误响应的。Mc 在处理所有 client 端指令时,如果遇到错误,就会返回 3 种错误信息中的一种。

& 第一种错误是协议错误,一个"ERROR\r\n"的字符串。表明 client 发送了一个非法命令。

& 第二种错误是 client 错误,格式为"CLIENT_ERROR <error-描述信息>\r\n"。这个错误信息表明 ,client 发送的协议命令格式有误,比如少了字段、多了非法字段等。

& 第三种错误是"SERVER_ERROR <error-描述信息>\r\n"。这个错误信息表明 Mc server 端,在处理命令时出现的错误。比如在给 key/value 分配 Item 空间失败后,会返回"SERVER_ERROR out of memory storing object" 错误信息。

存储协议命令

现在再来看看 Mc 的存储协议。Mc 的存储协议命令不多,只有 6 个。

Mc 存储指令分 2 行。第一行是报文首部,第二行是 value 的 data block 块。这两部分用 \r\n 来进行分割和收尾。

存储类指令的报文首行分 2 种格式,其中一种是在 cmd 存储指令,后面跟 key、flags、expiretime、value 字节数,以及一个可选的 noreply。

其中 flags 是用户自己设计的一个特殊含义数字,Mc 对 flag 只存储,而不进行任何额外解析处理,expiretime 是 key 的过期时间,value 字节数是 value block 块的字节长度,而带上 noreply 是指 Mc 处理完后静默处理,不返回任何响应给 client。

这种 cmd 指令包括我们最常用的 set 指令,另外还包括 add、replace、append、reppend ,总共 5 个指令:

& Set 命令用于存储一个 key/value;

& Add 命令是在当 key 不存在时,才存储这个 key/value;

& Replace 命令,是当 key 存在时,才存储这个 key/value;

& Append 命令,是当 key 存在时,追加 data 到 value 的尾部;

& Prepend 命令,是当 key 存在时,将 data 加到 value 的头部。

另外一种存储协议指令,主要格式和字段与前一种基本相同,只是多了一个 cas unique id,这种格式只有 cas 指令使用。cas 指令是指只有当这个 key 存在,且从本 client 获取以来,没有其他任何人修改过时,才进行修改。cas 的英文含义是 compare and set,即比较成功后设置的意思。

存储命令响应

Mc 在响应存储协议时,如果遇到错误,就返回前面说的3种错误信息中的一种。否则就会返回如下 4 种正常的响应,"STORED\r\n”、"EXISTS\r\n”、“NOT_STORED\r\n”、"NOT_FOUND\r\n“。

其中,stored 表明存储修改成功。NOT_STORED 表明数据没有存储成功,但并不是遇到错误或异常。这个响应一般表明 add 或 replace 等指令,前置条件不满足时,比如 add,这个 key 已经存在 Mc,就会 add 新 key 失败。replace 时, key 不存在,也无法 replace 成功。EXISTS 表明待 cas 的key 已经被修改过了,而 NOT_FOUND 是指待 cas 的 key 在 Mc 中不存在。

Mc 对存储命令的请求及响应协议,可以参考下面的思维导图来有一个完整的印象。
在这里插入图片描述
获取命令

Mc 的获取协议,只有 get、gets 两种指令,如下图所示。格式为 get/gets 后,跟随若干个 key,然后 \r\n 结束请求命令。get 指令只获取 key 的 flag 及 value,gets 会额外多获取一个 cas unique id值。gets 主要是为 cas 指令服务的。

获取命令的响应,就是 value 字串,后面跟上 key、flag、value 字节数,以及 value 的 data block 块。最后跟一个 END\r\n 表明所有存在的 key/value 已经返回,如果没有返回的 key,则表明这个 key 在 Mc 中不存在。
在这里插入图片描述
其他指令

Mc 的其他协议指令包括 delete、incr、decr、touch、gat、gats、slabs、lru、stats 这 9 种指令。

其中 delete 用于删除一个 key。

incr/decr 用于对一个无符号长整型数字进行加或减。

touch、gat、gats 是 Mc 后来增加的指令,都可以用来修改 key 的过期时间。不同点是 touch 只修改 key 的过期时间,不获取 key对应的value。

而 gat、gats 指令,不仅会修改 key 的过期时间,还会获取 key 对应的 flag 和 value 数据。gats 同 gets,还会额外获取 cas 唯一 id 值。

Slabs reassign 用于在 Mc 内存达到设定上限后,将 slab 重新在不同的 slabclass 之间分配。这样可以规避 Mc 启动后自动分配而产生随机性,使特殊 size 的数据也得到较好的命中率。Slabs automove 是一个开关指令,当打开时,就允许 Mc 后台线程自行决定何时将 slab 在slabclass 之间重新分配。

lru 指令用于 Mc LRU 的设置和调优。比如 LRU tune 用于设置 HOT、WARM LRU 的内存占比。LRU mode 用来设置 Mc 只使用 COLD LRU,还是使用新版的 4 个 LRU 的新策略。LRU TEMP_TTL 用来设置 Mc 的 TEMP LRU 的TTL值,默认是 61s,小于这个 TMEP_TTL 的 key会被插入到 TEMP LRU。

Stats 用于获取 Mc 的各种统计数据。Stats 后面可以跟 statistics、slabs、size 等参数,来进一步获取更多不同的详细统计。

Client 使用

Mc 在互联网企业应用广泛,热门语言基本都有 Mc client 的实现。以 Java 语言为例,互联网业界广泛使用的有 Memcached-Java-Client、SpyMemcached、Xmemcached 等。

Memcached-Java-Client 推出时间早,10 年前就被广泛使用,这个 client 性能一般,但足够稳定,很多互联网企业至今仍在使用。不过这个 client 几年前就停止了更新。

SpyMemcached 出现的比较晚,性能较好,但高并发访问场景,稳定性欠缺。近几年变更很少,基本停止了更新。

Xmemcached 性能较好,综合表现最佳。而且社区活跃度高,近些年也一直在持续更新中。Java 新项目启动,推荐使用 Xmemcached。

在使用 Mc client 时,有一些通用性的调优及改进方案。比如,如果读写的 key/value 较大,需要设置更大的缓冲 buf,以提高性能。在一些业务场景中,需要启用 TCP_NODELAY,避免 40ms 的延迟问题。同时,如果存取的 key/value size 较大,可以设置一个压缩阀值,超过阀值,就对value 进行压缩算法,减少读写及存储的空间。

为了避免缓存雪崩,并更好地应对极热 key 及洪水流量的问题,还可以对 Mc client 进行封装,加入多副本、多层级策略,使 Mc 缓存系统在任何场景下,都可做到高可用、高性能。

讲到这里,Mc 的核心知识点就基本讲完了,知识点结构图如下所示。
在这里插入图片描述
回顾一下最近几节课的内容。首先,学习了 Mc 的系统架构,学习了 Mc 基于 libevent 的网络模型,学习了 Mc 的多线程处理,包括主线程、工作线程如何进行网络 IO 协调及处理,学习了 Mc 的状态机。然后,继续学习了 Mc 用于定位 key 的哈希表,学习了用于数据生命周期管理的 LRU,还学习 slab 分配机制,以及 Mc 数据的存储机理。最后,还完整学习了 Mc的协议,了解了以 Java 语言为例的 3 种 Mc client,以及 Mc client 在线上使用过程中,如何进行调优及改进。

根据下面 Mc 协议的思维导图,查看自己是否对所有指令都有理解,可以结合 Mc 的协议文档,启动一个 Mc 实例,进行各个命令的实际操练。
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/407081.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

探索无限:Sora与AI视频模型的技术革命 - 开创未来视觉艺术的新篇章

✨✨ 欢迎大家来访Srlua的博文&#xff08;づ&#xffe3;3&#xffe3;&#xff09;づ╭❤&#xff5e;✨✨ &#x1f31f;&#x1f31f; 欢迎各位亲爱的读者&#xff0c;感谢你们抽出宝贵的时间来阅读我的文章。 我是Srlua&#xff0c;在这里我会分享我的知识和经验。&#x…

【C++初阶】--类和对象(下)

目录 一.const成员 1.权限放大问题 2.权限的缩小 二.再谈构造函数 1.构造函数体赋值 2.初始化列表 (1)概念 (2)使用 ①在对象实例化过程中&#xff0c;成员变量先依次进行初始化 ②再进行函数体内二次赋值 3.explicit关键字 (1)C为什么要存在自动隐式类型转换…

泰山众筹:掀起一场全民参与的购物狂潮!

随着互联网的快速发展&#xff0c;传统的商业模式已经无法满足消费者的多元化需求。在这个数字化时代&#xff0c;泰山众筹模式以其独特的魅力&#xff0c;正迅速成为新零售市场的热门话题。它不仅为消费者带来了前所未有的购物体验&#xff0c;还为企业的发展注入了新的活力。…

Visual Sudio 2022 引入第三方库(MySQL.H)

参考博客 Visual Studio 2022 C配置第三方库(libsndfile)、 fatal error LNK1107: 文件无效或损坏: 无法在 0x2C8 处读取 &#x1f33b;&#x1f33b;&#x1f33b;感谢两位博主在配置第三方库时给我提供的帮助&#x1f33b;&#x1f33b;&#x1f33b; 目录 一、准备好第三方库…

Win11网络连接选项和蓝牙选项突然消失的解决办法

在设置或者开始栏里搜索“网络重置” 打开网络重置&#xff1a; 然后点击立即重置&#xff0c;之后按照系统提示操作即可

vue教程

v 创建一个vue实例插值表达式{{}}vue响应式特性vue指令v-if vs. v-show 指令v-else-if 指令v-on指令 注册监听内联语句methods中的函数名![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/8b9d81539ba74e6691b27694813e0f65.png)v-on 调用传参 v-bind 动态的设置html…

(十一)【Jmeter】线程(Threads(Users))之jp@gc-Ultimate Thread Group

简述 操作路径如下: 作用:提供了高级的线程组控制选项,支持更复杂的场景模拟。配置:设置多种线程控制参数,如启动延迟、启动线程数、并发压测持续时间、关闭线程时间等。使用场景:针对特定需求进行高级的并发访问模拟,如流量控制、延迟启动等。优点:提供了丰富的控制…

HarmonyOS Stage模型 应用配置文件讲解

好&#xff0c;上文 HarmonyOS Stage模型基本概念讲解 中&#xff0c;我们简单讲解了HarmonyOS 中 Stage模型的基本概念 那么 我们继续学习Stage模型的相关知识 上文之后 我们肯定对它的概念和基本结构 有了一个了解 那么 我们就来看一下 基于Stage模型 它里面一些基本的配置文…

算法沉淀——动态规划之斐波那契数列模型(leetcode真题剖析)

算法沉淀——动态规划之斐波那契数列模型 01.第 N 个泰波那契数02.三步问题03.使用最小花费爬楼梯04.解码方法 动态规划&#xff08;Dynamic Programming&#xff0c;简称DP&#xff09;是一种通过将原问题分解为相互重叠的子问题并仅仅解决每个子问题一次&#xff0c;将其解存…

CSRF攻击和防御

CSRF:Cross Site Request Forgery 跨站请求伪造 攻击&#xff1a; 攻击者盗用你的身份&#xff0c;以你的名义发送恶意请求&#xff08;邮件&#xff0c;消息&#xff0c;盗取账号&#xff0c;购买物品&#xff09; GET请求的伪造方式 POST请求的伪造方式 防御&#xff1a…

[c++] 工厂模式 + cyberrt 组件加载器分析

使用对象的时候&#xff0c;可以直接 new 一个&#xff0c;为什么还需要工厂模式 &#xff1f; 工厂模式属于创建型设计模式&#xff0c;将对象的创建和使用进行解耦&#xff0c;对用户隐藏了创建逻辑。 个人感觉上边的表述并没有说清楚为什么需要使用工厂模式。因为使用 new 创…

[面试] 如何保证Redis和MySQL数据一致性?

为什么要在Redis存数据 Redis 用来实现应用和数据库之间读操作的缓存层&#xff0c;主要目的是减少数据 库 IO&#xff0c;还可以提升数据的 IO 性能。 因为Redis基于内存, 查询效率比MySQL快很多, 所以有限查询Redis中的数据,如果Redis没有就查询数据库然后同步到Redis 出…

Vue+SpringBoot打造快递管理系统

目录 一、摘要1.1 项目介绍1.2 项目录屏 二、研究内容2.1 数据中心模块2.2 快递类型模块2.3 快递区域模块2.4 快递货架模块2.5 快递档案模块 三、界面展示3.1 登录注册3.2 快递类型3.3 快递区域3.4 快递货架3.5 快递档案3.6 系统基础模块 四、免责说明 一、摘要 1.1 项目介绍 …

Flink ML 的新特性解析与应用

摘要&#xff1a;本文整理自阿里巴巴算法专家赵伟波&#xff0c;在 Flink Forward Asia 2023 AI特征工程专场的分享。本篇内容主要分为以下四部分&#xff1a; Flink ML 概况在线学习的设计与应用在线推理的设计与应用特征工程算法与应用 一、Flink ML 概况 Flink ML 是 Apache…

MySQL运维实战(7.2) MySQL复制server_id相关问题

作者&#xff1a;俊达 主库server_id没有设置 主库没有设置server_id Got fatal error 1236 from master when reading data from binary log: Misconfigured master - server_id was not set主库查看server_id mysql> show variables like server_id; ----------------…

Spring Boot 笔记 029 用户模块

1.1 用户信息需要在多个链接使用&#xff0c;所以需要用pinia持久化 1.1.1 定义store import {defineStore} from pinia import {ref} from vue const useUserInfoStore defineStore(userInfo,()>{//定义状态相关的内容const info ref({})const setInfo (newInfo)>{i…

基于ElementUI封装省市区四级联动下拉选择

基于ElementUI封装的省市区下拉级联选择 效果 数据 最新省市区JSON数据获取&#xff1a;https://xiangyuecn.github.io/AreaCity-JsSpider-StatsGov/ 参数说明 参数说明inputNumShow下拉框的数量&#xff0c;最多4个defaultAddress默认显示省市区 例&#xff1a;[‘安徽’, …

C语言:指针的进阶讲解

目录 1. 二级指针 1.1 二级指针是什么&#xff1f; 1.2 二级指针的作用 2. 一维数组和二维数组的本质 3. 指针数组 4. 数组指针 5. 函数指针 6. typedef的使用 7. 函数指针数组 7.1 转移表 1. 二级指针 如果了解了一级指针&#xff0c;那二级指针也是可以很好的理解…

Redis(十六)缓存预热+缓存雪崩+缓存击穿+缓存穿透

文章目录 面试题缓存预热缓存雪崩解决方案 缓存穿透解决方案 缓存击穿解决方案案例&#xff1a;高并发聚划算业务 总结表格 面试题 缓存预热、雪崩、穿透、击穿分别是什么?你遇到过那几个情况?缓存预热你是怎么做的?如何避免或者减少缓存雪崩?穿透和击穿有什么区别?他两是…

JDK下载安装

资源展示 安装说明 傻瓜式安装&#xff0c;下一步即可。建议&#xff1a;安装路径不要有中文或者空格等特殊符号。本套课程会同时安装JDK8 和 JDK17&#xff0c;并以JDK17为默认版本进行讲解。 安装步骤 &#xff08;1&#xff09;双击jdk-17_windows-x64_bin.exe文件&#…
最新文章