大型网站技术架构:核心原理与案例分析----Memcached分布式缓存集群的访问模型剖析

news/2024/5/20 21:51:41/文章来源:https://blog.csdn.net/wangcomputer2010/article/details/52768160

前提:

  • 本文是基于memcached1.4版本的,之前的版本与该版本在一些地方是不一样的(eg.《memcached全面剖析》的memcached1.2的内存管理方式就与1.4不同)
  • 在看本文之前,最好先看一下memcached在实际开发中怎么进行操作的,链接《第八章 企业项目开发--分布式缓存memcached》

1、memcached特征

  • 协议简单(文本协议、二进制协议)
  • 基于libevent的事件处理,libevent封装了Linux的epoll模型的时间处理功能。
  • slab存储模型
  • 集群中服务器间互不通信(在大集群的情况下,其性能远超其他同步更新缓存的缓存器,当然小集群下,memcached的性能也十分优秀)

 

2、memcached访问模型

说明:

Xmemcached的具体使用代码查看"Java企业项目开发实践"系列博客的《第八章 企业项目开发--分布式缓存memcached》,下面的解释会依据该代码进行。

在上图中,memcached客户端假设使用XMemcached

  • 服务器列表:在根pom.xml文件中进行了配置
  • 路由算法有两种:(可以在程序中指定)
    • 一致性hash算法(推荐)
    • 简单求余法
  • 通信模块:
    • 通信协议:TCP协议
    • 序列化协议:二进制协议(推荐)、文本协议
  • Memcached API(缓存的增删改查):在程序中编写

整个流程:

应用程序(AdminService)调用Memcached API(假设为add操作),向memcached服务器添加缓存,这时候,程序会首先根据配置的路由算法(假设是一致性hash算法)在服务器列表中选出一台服务器(假设是node1),之后该API通过序列化协议序列化对象(当然,这个是可无的,eg.value是一个String),并通过TCP协议将将要存储的key-value对存入相应的服务器。在get时,只要采用的是与add时相同的hash算法,就会选中add时的那一台服务器。

看完这一段,流程明白了。但是有几点疑问:

  • 两种路由算法是怎样实现的?为什么使用一致性hash算法
  • 缓存到达服务器的时候究竟怎么存储?(slab内存模型)
  • 当缓存超过一定的容量后,缓存的自动删除是采用什么策略,怎样删除的?(LRU)
  • 两种序列化协议有什么优缺点?

 

3、hash算法

3.1、简单求余法

原理步骤:求得key的整数hash值(对于Java对象而言,直接使用其hashCode()方法就好),再除以服务器台数,获取余数,根据该余数选择服务器。

注意:如果选择的服务器无法连接时,会进行rehash,即:将连接次数添加到键中,重新计算hash值后,再重新连接。当然可以禁止rehash。

优点:

  • 简单
  • hash分散性好(因为hashCode()的值具有随机性)

缺点:

  • 添加或删除服务器的时候,缓存的获取就会出问题了(因为服务器台数变了,求余的时候分母变了,余数也就可能变了),假设在99台memcached服务器中又新添加而一台,则缓存的不命中率是99%,即n/(n+1),n表示原有的服务器。

注意:

  • 在XMemcached中仍保留了该算法
  • 适用于不需要考虑集群伸缩性的时候(即机器总数不变)

3.2、一致性hash算法

对于绝大部分系统,集群的伸缩性是五个非功能需求中比较重要的一个,也就是说必须克服"简单求余法"的缺点。

  • 原理:先构造一个长度为0~232的整数环(使用二叉树构造),根据节点(memcached服务器)名称的hash值将缓存服务器节点放置在这个hash环上,然后根据需要缓存的数据的key来计算其hash值,然后在hash环上顺时针查找距离这个key的hash值最近的缓存服务器节点,完成key到服务器的hash映射查找。
    • 如果超过232还找不到,则存在第一台memcached上(依旧是顺时针)
  • 存在的问题:当服务器数量比较少的情况下,有可能造成负载不均衡的情况,为了防止这种情况的发生,使用将物理服务器先虚拟化成多台虚拟服务器,然后将这些虚拟服务器的hash值放在环上,当客户端路由到某台虚拟服务器上时,找到该虚拟服务器所对应的物理服务器即可。
    • 一般而言,一台物理服务器虚拟化为150台虚拟服务器最合适,太少会造成负载不均,太多会影响性能
  • Memcached采用这样的算法,在我们新加入服务器或集群中的某台服务器宕机时,都不会有太大的影响,只会影响一小段(见下图),确保了集群的可用性与伸缩性

注意:

  • hash环是一个二叉树,最后边叶子与最左边相连成环
  • 整个缓存的查找过程就是找一个刚刚大于等于查找数的最小值

疑问:(这一点没查到资料)

  • 服务器的hash算法是怎样的
  • 计算缓存key的hash算法是否要与服务器的一致,还能不能使用原来的hashCode()

思路:hash算法实际上就是"先将字符串转化为整数,然后再将该整数放到相应的服务器上或环上",对于key不用讲,我们可以用crc32将字符串的key转化为整数,之后放在0~232的环上的一点,对于服务器我们可以采用将"ip:port"这个字符串使用crc32转化为整数,之后放在环上(当然这里我们需要将一个实例"ip:port"虚拟化成一堆虚拟节点,每台虚拟节点可以使用"ip:port-i"作为节点名称,其中i是>0的整数,将每台虚拟节点的名称采用crc32算法算出整数放到环上)。

4、slab内存模型

4.1、为什么使用slab内存模型?

  在最一开始的内存分配与回收是通过malloc和free来处理的,该方式会产生内存碎片,加重内存管理器的负担,严重缓存操作影响效率。

slab模型的出现就是为了:

  • 提高缓存操作效率
  • 完全的解决内存碎片问题。

注意:

  • 第一个目的:已经实现了(因为直接定位合适的chunk会很快)
  • 第二个目的:采用slab机制依旧会产生内存碎片,或者说成是内存浪费

4.2、slab模型原理

说明:该图摘自一篇博客(图中有标记,但是看不清),但是是很久以前摘的了,忘记了。以后找到了,我会标明出处的。

memcached的内存分配就是下面这一句话:采用分组管理预分配方式。

4.2.1、分组管理

  • 分组方式:Memcached将内存空间分为一组slab,每个slab的大小固定为1M,每个slab里又包含一组chunk,同一个slab里的每个chunk大小相同。根据这些slab中的chunk的大小,将这些slab编号slab class(也就是上图中的Classes i)。
  • 存储原理:当来一个要存储的key-value对时,我们查看这个数据的大小,选择最适合的slab class中的空闲chunk放置该对象。
    • 最合适的chunk:即该chunk的大小刚刚大于等于所存储数据的大小,而比该chunk小一级的大小刚刚比所要存储的数据小。

以上这种方式会造成内存大量浪费(我认为这也是内存碎片)。

  • 减少内存浪费的方式:预估自己的缓存数据的大小,然后在启动Memcached时合理的指定参数-f(增长因子)和-n(chunk最小尺寸)来划分内存大小,根据公式chunk size = 80*f*(n-1)将内存分配为若干个slab class。

疑问:上边这个若干到底是多少?

我们可以根据f,n,以及一个slab最大为1M来确定。(例子,我不举了,自己想想)

4.2.2、预分配

  在启动Memcached时通过-m参数为Memcached分配可用内存(假设-m 1024,即分配了1G内存),但是启动的时候不会把这些内存一次全部分配出去,而是默认先分配若干个slab class(数量取决于-f与-n参数),当其中的一个slab class被用完之后,Memcached就会再次申请1M空间,产生一个该slab class。这一块儿结合缓存删除机制中的LRU算法来看。(这一块如果有误,请大神帮忙指出来)

 

5、缓存删除机制

  • memcached不会释放已分配的内存,记录超时后,其存储空间即可重复使用
  • memcached内部不会监视缓存是否过期(即memcached不会在过期监视上耗费CPU时间),在get时查看缓存的时间戳,检查缓存是否过期
  • memcached会优先使用已超时的缓存的空间,但是当所有空间都没有超时,所有内存都已经分配完了,就删除最近最少使用(LRU)的缓存,将其空间分配给新缓存(注意,假设防止一个100k的数据,而最合适的chunk是112k,假设最合适的chunk全部用完了,这时候就取剩下的内存分配112k chunk的slab,若是剩下的内存页分配完了,不会使用刚刚大于112k的144k chunk,而是会采用LRU算法删除最近最少使用的元素,其实这样的话,就会有一个可能,就是原本112k中的数据还未过期,就有可能被踢出去了,这就是"老数据被踢现象")

注意:第三条与内存分配部分的预分配结合来看。

LRU算法原理:

当某个单元被请求时,维护一个计数器,通过计数器来判断最近最少被使用的元素被踢出去。 

 

6、两种序列化协议

  • 文本协议:
    • XML、JSON
    • key的长度为256字节
  • 二进制协议:相较于文本协议
    • jdk序列化机制、protobuf
    • 不需要文本协议的解析处理,速度更快
    • 具有更长的key,理论上最大可使用65536字节长度的key
    • 出现在1.4,推荐使用

注意:对于以上两种协议,自己选择吧。

  • 二进制协议+JDK的序列化机制,那么由于JDK自己的序列化机制低效,所以在速度上未必会比使用了fastjson的文本协议更快
  • 二进制协议+protobuf,速度很快,但是使用起来不太方便
  • 文本协议+fastjson

 

7、部分API

  • add:仅当存储空间中不存在相同key的数据时才保存
  • replace:替换。即仅当存储空间中存在相同的数据时才保存
  • set:add+replace。即无论何时都保存
  • delete(key, '阻塞时间(秒)')
  • 增1、减1操作,做计数器
  • get_multi(key1, key2):一次性非同步的同时(即并发的)获取多个键,比循环调用getKIA数十倍

 

注意点:

  • 对于memcached的监视:可以采用"nagios"

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

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

相关文章

【转】nbsp;实现网站的中英文转换

1.新建一个asp.net web应用程序 2.创建的项目如下图所示 3.右击web项目名称,添加一个全局资源文件夹"app_GlobalResources" ,这个是asp.net 2.0特有的 4.右击"app_GlobalResources"文件夹,添加两个资源文件: language.resx(简体资源文件) 和language.en-u…

【转】ASP.NET网站实现中英文转换…

摘要:随着计算机网络的发展,一些商业机构也开始向国际市场迈进。因此这些商业的机构的网站 也开始面向全世界的用户,要求网站具有多语言的选择,实现本地化。在.NET1.1框架下面,如果你要实现本地化,你可能要…

这个网站他不简单系列(一)低调而强大的DICT.CN

这个网站他不简单系列(一)低调而强大的DICT.CN emilmatthew 08/06/25 OK,闲话少说,我们先看网站:DICT.CN,不知诸位看下来有何感觉?是啊,不就是个在线词典吗?是啊,我也觉得不就是个在…

[8.18]东西放久了会发霉的,网站也一样,拿出来晒晒~~~

这个网站叫DOUPACK(中文名称叫豆瓣包裹),主要的意图就是可以在屏幕上拖动你的豆瓣小组,组成一个你喜欢的样子.感觉最后会变成一个恶搞度>实用度的应用.由于整个用户系统都要弄下来,所以制作时间有些长... 去年11月开始做的,原先是利用业余时间做的,弄了4个月,还差一个月的工…

web2.0网站的四大特性简述

本文文字内容转自天极网: http://homepage.yesky.com/216/2634716.shtml 本文图片转自: http://web2.wsj2.com/architectures_of_participation_the_next_big_thing.htm 收集和学习了大家对于Web2.0特性的看法,加上这几天的思考,整理我对于Web2.0到底是…

Gin + GoCv + Element 简单搭建图片风格迁移网站

成品效果 输入:jpg/png 格式图片 输出:风格迁移后的图片 目录结构 # tree├─controller // 控制器 ├─models // 风格迁移模型 │ ├─eccv16 │ └─instance_norm ├─router // 路由转发 ├─static // 静态资源 ├─sys // 系统配置 ├─tem…

手机访问网站 点击手机号码直接拨打电话

分享一下我老师大神的人工智能教程!零基础,通俗易懂!http://blog.csdn.net/jiangjunshow 也欢迎大家转载本篇文章。分享知识,造福人民,实现我们中华民族伟大复兴! 手机访问网站,点击手机号码直接拨打电话: …

使用IntelliJ IDEA开发SpringMVC网站

转自https://my.oschina.net/gaussik/blog/385697 1.安装jdk,maven和tomcat 2.创建maven web项目 Create New Project 最后生成结果如下图,注意左侧部分 上侧部分选择Auto-Import就好 如果生成过慢,可以参看下面两篇文章: 文章1&a…

回首10年前的30个最受欢迎的网站

10年前的Web技术还比较落后,浏览器功能也非常有限,你知道现在最受欢迎的这些网站,在10年前甚至更早的时候是什么样子吗?文中为你揭示包括Google、雅虎、eBay、维基百科等网站的老面孔: 1. Google (1998) Google (1998…

让你的Onedrive网盘秒变网站,文件展示,直连下载,视频在线播放

之前我们介绍了免费的5TB的Onedrive网盘,不但能做本地硬盘使用,还能扩展你的硬盘,今天我们就来介绍一下另一款Onedrive网盘的神器OneIndex,这是针对Onedrive网盘的一个开源程序。可以将Onedrive存储的文件展示,直连下载。视频还能…

LAMP网站架构方案分析

LAMP(Linux-Apache-MySQL-PHP)网站架构是目前国际流行的Web框架,该框架包括:Linux操作系统,Apache网络服务器,MySQL数据库,Perl、PHP或者Python编程语言,所有组成产品均是开源软件&a…

如何更改VS2005调试网站的浏览器类型

选择网站根目录,右键单击 选择“浏览方式” 在这里就可以设置浏览器的类型了 转载于:https://www.cnblogs.com/qishichang/archive/2007/11/25/971588.html

微软官宣IE将“退役”,老网站如何 实现在Chrome、Firefox中兼容运行?

问题 美国微软公司为了推广其Chromium内核的Edge浏览器,在2021年5月19日突然宣布,自2022年6月15日起,绝大多数版本的Windows 10系统将不再支持IE浏览器,因此IE即将彻底退出互联网的舞台。具体来说微软决定将不再支持Windows 10所…

Python必去的6个网站

1.The Hitchhiker’s Guide to Python。 equests作者创建的网站,对于Python的方方面面都有指导作用 2. Python 3 Module of the Week 和 Python Module of the Week。 Python 3 Module of the Week系列文章,每篇介绍一个 Python 标准库的使用 3. …

你的网站被流量冲崩了吗?稳住!ab来帮你了

【来源】 ab 全称 Apache Benchmar , 顾名思义是Apache提供的一种性能测试工具。主要作用是检测web服务每秒可以处理多少个请求。它可以用于apache、IIs、tomcat、nginx等服务器的简单压力测试 【语法】 格式:ab [options] path 其中options参数常用有以下&#xf…

推荐大家研究一个网站tineye.com

http://www.tineye.com/,这个站点做得很有想法,详细体验我过几天发出,有兴趣的朋友可以先看看。 刚刚用这个站点上传了我硕士毕业的标准照,回顾了那段意气奋发的年代。

如何应对高并发 —— 动态网站静态化

零. 前言 为了应对高并发, 大多数网站在更新不频繁的页面都做了动态网页静态化处理。 典型的如: 淘宝的首页、 网易新闻的首页等。 当然这些网站加载速度这么快, 不仅仅是静态化, 还有 CDN、 缓存等各个方面的优化。 从阿里在 Inf…

HTML5移动端手机网站开发流程

最近一直在研究移动手机网站的开发,发现做手机网站没有想象中的那么难。为什么会这么说呢?我们试想下:我们连传统的PC网站都会做,难道连一个小小的手机网站难道都搞不定吗?其实手机网站就是一个微缩版的PC网站罢了!至于…

网站pc版转成手机版的三种方法

现在做自媒体博客的朋友有很多,可是,大家的自媒体博客都是PC版,只适用于电脑,平板上面,对于手机来说的话就不适合了,影响用户体验。下面,邵连虎博客就教大家三种方法把自媒体博客PC版转换成手机…