第一节 Memcached分布式缓存入门

关于Memcached的博文太多了,以下是个人学习的收集整理。

本节讨论问题:

  • 简单介绍与应用
  • 下载安装注意事项
  • 简单测试
  • Memcached分布式原理

一、介绍与应用

     在常规的WEB开发下,基本都会利用到缓存用以降低对数据库的压力,提高访问速度。有时候缓存的数据多了,并且其它站点也想获取这些缓存数据时就出现在了问题。通常IIS站点都是以应用程序池划分管理,同一个池下又可划分多个应用程序域,不管是不同的应用程序域或是不同应用程序池,其之间的缓存都是无法相互访问的。因此很多站点就会重复建立相同的缓存,以便访问。但是,一旦一个站点的缓存被更新了,又如何通知其它站点更新呢。我记得Discuz.net中做法,是通过监控配置文件的修改来实现的,其原理就是一个站点缓存更新了,就去修改对应的配置文件中的项。其它站点监控到配置文件被修改,就去检查哪一项目被改了,然后重新加载缓存。是不是不太灵活?如果缓存的数据要分布到其它服务器上,以降低对同一台服务器的压力,如何实现呢?缓存服务器又如何实现扩展呢?这便是我们这篇Memcached引入的原因。有做即时通讯,游戏大厅的还可以采用一下shuttler.net

关于Memcached以下为摘自博文http://www.cnblogs.com/zjneter/archive/2007/07/19/822780.html

Memcached是什么?
      Memcached是由Danga Interactive开发的,高性能的,分布式的内存对象缓存系统,用于在动态应用中减少数据库负载,提升访问速度。
Memcached能缓存什么?
     通过在内存里维护一个统一的巨大的hash表,Memcached能够用来存储各种格式的数据,包括图像、视频、文件以及数据库检索的结果等。
Memcached快么?
     非常快。Memcached使用了libevent(如果可以的话,在linux下使用epoll)来均衡任何数量的打开链接,使用非阻塞的网络I/O,对内部对象实现引用计数(因此,针对多样的客户端,对象可以处在多样的状态), 使用自己的页块分配器和哈希表, 因此虚拟内存不会产生碎片并且虚拟内存分配的时间复杂度可以保证为O(1).。
Memcached的特点?
     Memcached的缓存是一种分布式的,可以让不同主机上的多个用户同时访问, 因此解决了共享内存只能单机应用的局限,更不会出现使用数据库做类似事情的时候,磁盘开销和阻塞的发生。

二、下载与安装

服务端与For .net开发下载 可以参照这篇博文http://blog.csdn.net/cnkiminzhuhu/archive/2009/10/28/4739859.aspx
客户端的版本比较多,并且不能互用,因为采用了压缩机制,日志等功能,所以在选择客户端时要注意这些。

服务端源码  下载

a.windows下 直接使用memcached.exe 程序就可以了,也可以将此程序安装为windows服务。安装为windows服务后要通过telnet命令来操作服务端

命令行输入 'c:\memcached\memcached.exe -d install' 
命令行输入 'c:\memcached\memcached.exe -d start' ,该命令启动 Memcached ,默认监听端口为 11211

b.安装为单一服务不方便管理,这里有借助于memcacheddotnet_clientlib开发的一款服务端管理工具

服务端管理工具 下载  解压安装后工具里的memcached.exe比较老,可直接用最新的替换掉

我们来看一下服务端工具安装后文件结构

运行服务端管理工具,创建memcached服务端,以下为演示步骤

1 服务端配置

2 添加Memcached服务

3 状态观察

4.查看Generate配置信息,提供给客户端配置文件使用.

借助服务端管理工具可以方便的观察,或者你也可以采用telnet方式访问查看了。这样服务端工作就进行了完了,接下来就是要选择一款合的客户端开发了

Windows / .NET

a. .Net memcached client    1.1.5版本测试一下。
    https://sourceforge.net/projects/memcacheddotnet 
b. .Net 2.0 memcached client 这款应用比较广泛,不过好长时间没有更新了,最后一次更新是在2009.10 (网上其它链接提供的下载版本太老了)
    http://www.codeplex.com/EnyimMemcached
    Client developed in .NET 2.0 keeping performance and extensibility in mind. (Supports consistent hashing.) 
    http://www.codeplex.com/memcachedproviders   (PDF 文档)

   Current Release Memcached Providers 1.2(最后一版正式版)(1.2以后到1.4.4 for win32 应该都不是正式版了)
  - Walkthoughs on how to setup and use Memcached Cache Provider and Session State Provider is added to the Memcached Providers 1.2
   按照上面的意思Session State Provider is added 会话状态保存的功能已经有了? 经过下载解压后确认是有了这个功能,从1.2版本以后增加了SQL 脚本,即将Session保存到数据库中了-_-|||。很多人担心的Session问题终于有着落了。
c. BeIT Memcached Client (optimized C# 2.0)   这款最后一次更新时间是2010.8.4
    http://code.google.com/p/beitmemcached 
d. jehiah
    http://jehiah.cz/projects/memcached-win32 



经过一番比较,我还是比较看中a,b,c三款,分别下载下来测试一下吧。(鉴于服务端管理工具匹配还是推荐enyim比较好)

三、简单测试

1.memcacheddonet client测试 1.1.5版本 源码有SRC包

ExpandedBlockStart.gifView Code
public class MemcachedBench
{
/// <summary>
/// Arguments:
/// arg[0] = the number of runs to do
/// arg[1] = the run at which to start benchmarking
/// </summary>
/// <param name="args"></param>
[STAThread]
public static void Main(String[] args)
{
int runs = 100;
int start = 200;
if(args.Length > 1)
{
runs
= int.Parse(args[0]);
start
= int.Parse(args[1]);
}

//设置服务器列表
string[] serverlist = { "172.16.76.98:11211", "172.16.0.21:11211", "172.16.125.76:11211", "172.16.125.76:11212" };

// initialize the pool for memcache servers 创建连接池
SockIOPool pool = SockIOPool.GetInstance();
//设置服务器列表
pool.SetServers(serverlist);
//初始化
pool.InitConnections = 3;
pool.MinConnections
= 3;
pool.MaxConnections
= 5;
pool.SocketConnectTimeout
= 1000;
pool.SocketTimeout
= 3000;
pool.MaintenanceSleep
= 30;
pool.Failover
= true;
pool.Nagle
= false;
pool.Initialize();

// initialize the pool for memcache servers 全属性注入
// SockIOPool pool = SockIOPool.Instance;
// pool.Servers = serverlist; //属性方式配置//
// pool.InitConn = 5;
// pool.MinConn = 5;
// pool.MaxConn = 50;
// pool.MaintSleep = 30;
// pool.SocketTO = 1000;//
// pool.Nagle = false;
// pool.Initialize();

// // get client instance
MemcachedClient mc = new MemcachedClient();
mc.EnableCompression
= false; //是否启用压缩(通过ICSharpCode.SharpZipLib对存储的数据压缩)

// MemcachedClient mc = new MemcachedClient();
// mc.CompressEnable = false;
// mc.CompressThreshold = 0;
// mc.Serialize = true; //新的类中已没有此属性了,是默认帮你序列了?还是要自己实现呢?

string keyBase = "testKey";
string obj = "This is a test of an object blah blah es, serialization does not seem to slow things down so much. The gzip compression is horrible horrible performance, so we only use it for very large objects. I have not done any heavy benchmarking recently";

//循环记时往服务器缓存上插入数据 等会我们要观察一下数据都存到哪个服务器上的Memcached server上了
long begin = DateTime.Now.Ticks;
for(int i = start; i < start+runs; i++)
{
mc.Set(keyBase
+ i, obj);
}
long end = DateTime.Now.Ticks;
long time = end - begin;

//计算存储这些数据花了多长时间
Console.WriteLine(runs + " sets: " + new TimeSpan(time).ToString() + "ms");

//开始取数据,并记时
begin = DateTime.Now.Ticks;
int hits = 0;
int misses = 0;
for(int i = start; i < start+runs; i++)
{
string str = (string) mc.Get(keyBase + i);
if(str != null)
++hits; //成功取到数据
else
++misses; //丢失次数
}
end
= DateTime.Now.Ticks;
time
= end - begin;

//获取这些数据花了多长时间
Console.WriteLine(runs + " gets: " + new TimeSpan(time).ToString() + "ms");
Console.WriteLine(
"Cache hits: " + hits.ToString());
Console.WriteLine(
"Cache misses: " + misses.ToString());
Console.WriteLine(
"--------------------------------------------------------\r\n");

Console.WriteLine(
"各服务器状态:");
Console.WriteLine(
"-------------------------------------------------------");
IDictionary stats
= mc.Stats();
foreach(string key1 in stats.Keys)
{
Console.WriteLine(key1);
Hashtable values
= (Hashtable)stats[key1];
foreach(string key2 in values.Keys)
{
Console.WriteLine(key2
+ ":" + values[key2]);
}
Console.WriteLine(
"-------------------------------------------------------");
}
//从这里可以看出SockIOPool应该建立了一张HashTable去管理所有连接池实例
SockIOPool.GetInstance().Shutdown();

Console.ReadLine();
}

分别设置了3台,4台,5台服务器测试了3次,测试结果如下:

 

100条数据都确实存上去成功了,但是取数据命中率会随着服务器增多急剧下降!才几台测试服务器,结果就如此差!问题出在哪里了呢? 服务器的memcached.exe太老了? 还是看一下memcached的实现原理了

这里有我之前下载的一版memcached的原理介绍 下载

里面提到查找服务器端数据的算法 是求余算法 ,而这中算法的命中率很差,并且随便服务器节点的变动(增加或删除节点)命中率急剧下降。

难道是这个原因? 了解到memcached的客户端算法已经修改为Consistent Hashing算法,难道是我下载的客户端版本确实很老了? 顺便说一下这个Consistent Hashing算法是将服务器按环形分布在一个圆上,按我个人理解,服务器数量越多,环形分布越相对稳定,这个时候增删服务器对定位的影响都比较小。在之后两个客户端的版本再测试一次看看结果,这节就到这里吧。附一张用MemcacheD Manager监控图

Memcached分布式原理

由于测试读取数据的命中率太差,去查阅了一下Memcached的分布式原理。

先看一下应用场景

 

 第一次访问先从数据库中得到数据并保存到缓存中,第二次再读数据就从缓存中获取,这是正常情情,当第二次没有命中数据?这个时候你是否回数据库中读取数据呢?读取数据后,你是否还要保存到缓存中呢,但这个数据缓存中又是存在的,如何处理呢? 这就是Memcached客户端没有命中数据导致的后果。

我们来看一下Memcached的原理:

memcached虽然称为“分布式”缓存服务器,但服务器端并没有“分布式”功能,而是完全由客户端程序库实现的。服务端之间没有任何联系,数据存取都是通过客户端的算法实现的。客户端初始化的获取所有服务器的哈希列表,当需要存取数据就会检索这个哈希列表查找到对应的服务器。看下图

当客户端要存取数据时,首先会通过算法查找自己维护到的服务器哈希列表,找到对应的服务器后,再将数据存往指定服务器。这里关键点是使用了什么算法!

这个问题也不追查,接着往下看,我来再去取原先这个数据

查找数据的原理和存取的原理是一样,首先通过算法在维护的哈希列表查到对应服务器,然后再去指定服务器读取数据。那问题来了,他是如何准确的找到这台服务器的呢?算法,算法就是他的原因,只要你在存和取的时候使用的算法是一样的,那算法计算的结果也是一致的,所以就可以正确的找到服务器了。

那为什么我们在第三节的测试中,命中率会如此之差呢?

我们使用的Memcachedonet client 老版本使用的是求余算法,我们来看看这个求余算法的定义--“根据服务器台数的余数进行分散”。即求得键的整
数哈希值,再除以服务器台数,根据其余数来选择服务器。我们在存数据的时候,计算出这个数据键的CRC值,用这个值除以服务器台数求得余数来存往指定的服务器。那反过来取数据依然是这个算法,那结果肯定是一致的。问题是,为什么不同台数的服务器测试中,命中率会变化这么大呢。余数计算的方法简单,数据的分散性也相当优秀,但也有其缺点。那就是当添加或移除服务器时,缓存重组的代价相当巨大。添加服务器后,余数就会产生巨变,这样就无法获取与保存时相同的服
务器,从而影响缓存的命中率。因为增删服务器后,数据键的CRC值是不变的,但是服务器的台数变了,导致求余的结果也发生变化了,从而影响了命中率。

我们再来看一下改进的Consistent Hashing算法,可以确定是的,Memcachedonet的版本是没有采用这个算法。

Consistent Hashing如下所示:首先求出memcached服务器(节点)的哈希值,并将其配置到0~2的32次方的圆(continuum)上。然后用同样的方法求出存储数据的键的哈希值,并映射到圆上。然后从数据映射到的位置开始顺时针查找,将数据保存到找到的第一个服务器上。如果超过2的32次方仍然找不到服务器,就会保存到第一台memcached服务器上。

当从上图的状态中添加一台memcached服务器。余数分布式算法由于保存键的服务器会发生巨大变化而影响缓存的命中率,但Consistent Hashing中,只有在continuum上增加服务器的地点逆时针方向的第一台服务器上的键会受到影响。如下图

 从上图可以看到,添加新的节点5时并不会重新分布所有节点,而是在之前的基础上某个位置插入新的节点,这样保证了整体的分布没有发生太大变化,并且顺时针方向的没有影响,逆时针方向的从第一台就开始有影响了。因此,Consistent Hashing最大限度地抑制了键的重新分布。但是这样的误差还是有的,因为根据服务器的哈希值来分布本身就是不均匀的。后面有提到改进的Consistent Hashing算法,即在圆环上预先分布为每台服务器分布一定数量的虚定拟节点,相当于我们均匀分布了圆环上的节点,当有节点增加或删除时都是在指定的位置上进行的就抑制了分布不均匀,最大限度地减小服务器增减时的缓存重新分。使用Consistent Hashing算法的memcached客户端函数库进行测试的结果是,由服务器台数(n)和增加的服务器台数(m)计算增加服务器后的命中率计算公式如下:(1 n/(n+m)) * 100

(参考之前提供下载的PDF原理一文)

     memcachedonet 使用的是余数算法,可能是导致误差的原因。在下一节中,我们来学习一下enyim.client(memcachedproviders),并进行相关测试。

转载于:https://www.cnblogs.com/aaa6818162/archive/2011/11/20/2255820.html

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

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

相关文章

tomcat 拦截指定url_一口气说出 过滤器 和 拦截器 6个区别,别再傻傻分不清了

点击“ 程序员内点事 ”关注&#xff0c;选择“ 设置星标 ”坚持学习&#xff0c;好文每日送达&#xff01;周末有个小伙伴加我微信&#xff0c;向我请教了一个问题&#xff1a;老哥&#xff0c;「过滤器 (Filter) 和 拦截器 (Interceptor) 有啥区别啊&#xff1f;」 听到题目我…

[html] 如何使用纯html制作一个进度条?

[html] 如何使用纯html制作一个进度条&#xff1f; HTML中的progress () 元素用来显示一项任务的完成进度.虽然规范中没有规定该元素具体如何显示,浏览器开发商可以自己决定,但通常情况下,该元素都显示为一个进度条形式.个人简介 我是歌谣&#xff0c;欢迎和大家一起交流前后…

Java 多线程练习---创建两个子线程,每个线程交替输出“你好--来自线程***”...

|--需求说明 |--实现思路 1、创建一个类&#xff0c;实现Runnable&#xff0c;在这个类里面重写run()方法&#xff0c;在run()方法里面写一个20的for循环 2、创建一个类&#xff0c;实例化上面的类&#xff0c;用这个类的对象创建线程 |--代码内容 1 package cn.thread;2 3 /**…

关于Android的应用程序的发布的学习(一)

上一次写了一篇关于android应用程序打包成apk文件的签名&#xff0c;地址&#xff1a;http://blog.csdn.net/zqiang_55/article/details/6939170 最近再看sdk的时候发现其实在sdk中又了详细的少说明&#xff0c;现在将主要的翻译如下&#xff1a; 在Dev Gudie标签页中的Publish…

手动封装js的call和apply和bind和typeof和new方法

我是歌谣 放弃很容易 但是坚持一定很酷 微信公众号关注小歌谣一起学习前后端知识 闲来无事做 不如敲代码今天讲一下js里面的callapply和bind和typeof方法的手动封装由于最近比较忙但是有时间就会记录一下平时学习工作的一些代码用来分享这边就不直接多说开始我们的直接代码书写…

js保留两位小数的函数_使用率低但功能强大的6个Excel函数公式应用技巧解读!...

在Excel函数公式中&#xff0c;有部分函数的使用率是比较低的&#xff0c;但是其功能也是非常强大的。一、Median函数。功能&#xff1a;返回一组数的中值。中值就是一组数的中间数值&#xff0c;如果参数包含的数值是偶数&#xff0c;Median函数将返回位于中间两个值的平均值。…

IP包的生成和发送接口(1)

http://blog.sina.com.cn/s/indexlist_1657348185_2.html IP包的生成和发送接口 (1) Linux内核中有3种基本的IP包生成器, 它们分别为ip_build_xmit(), ip_queue_xmit(), ip_build_and_send_pkt(). ip_build_and_send_pkt()是一简单的IP包头封装接口, 它接照输入包的路由添加一…

.net复习之七

表A&#xff1a; 表B&#xff1a; 1&#xff0e; SELECT * FROM A JOIN B ON A.Id B.Id 將顯示 9 條數據。 Inner join(等值连接)只返回两个表中联结字段相等的行 2&#xff0e; SELECT * FROM A LEFT JOIN B ON A.Id B.Id 將顯示 12 條數據…

原生js实现tab栏切换效果

我是歌谣 放弃很容易 但是坚持一定很酷 微信公众号关注小歌谣一起学习前后端知识 运行效果 首先我们来看一下原生js实现的效果 下面就开始直接上代码了 index.html <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"&…

线程八大核心+java并发核心知识体系精讲_Java从业者如果不懂这些,面试80%都会挂在这些核心知识上面...

JVM无论什么级别的Java从业者&#xff0c;JVM都是进阶时必须迈过的坎。不管是工作还是面试中&#xff0c;JVM都是必考题。如果不懂JVM的话&#xff0c;薪酬会非常吃亏(近70%的面试者挂在JVM上了)详细介绍了JVM有关于线程、内存模型、JVM运行时内存、垃圾回收与算法、Java中四种…

Ajax技术简单入门

随着Google公司推出的Gmail服务后,越来越多的人开始关注Ajax技术了,所谓Ajax(Asynchronous JavaScript and XML缩写)技术,就是指运用JavaScript和XML在不用刷新Web页的情况下与Web服务器通信的技术&#xff0e;一般来说&#xff0c;使用Ajax技术主要有两个原因&#xff1a;一是…

我所知的javascript之prototype

一&#xff1a;prototype大概概念和用途“prototype”字面翻译是“原型”&#xff0c;是javascript实现继承的主要手段。粗略来说就是&#xff1a;prototype是javascript中的函数(function)的一个保留属性&#xff0c;并且它的值是一个对象&#xff08;我们可以称这个对象为&qu…

哪些模块可用于python性能分析_Python调用C模块以及性能分析

一.c&#xff0c;ctypes和python的数据类型的对应关系ctypes type ctype Python typec_char char 1-character stringc_wchar wchar_t 1-character unicode stringc_byte char int/longc_ubyte unsigned char int/longc_short short int/longc_ushort unsigned short int/longc…

[html] webp与jpg、png比较,它有什么优劣势?如何选择?

[html] webp与jpg、png比较&#xff0c;它有什么优劣势&#xff1f;如何选择&#xff1f; 优势更优的图像数据压缩算法 带来更小的图片体积肉眼识别无差异的图片质量支持有损和无损压缩支持动画 透明色彩丰富 24-bit颜色数劣势存在兼容性问题选择​ 当 图片较少 体积不大 且存…

Alt Gr or Shift

This is interesting. The keyboard here is different from what we always use in China. Characters and layout are different. Hans gave me the password to logon the system. There s a “” character in it. With Chinese keyboard, I will use “Shift 2″ to gener…

Vue之前端页面使用json编辑框

转自: https://blog.csdn.net/Wjhsmart/article/details/85757045 转载于:https://www.cnblogs.com/jiushixihuandaqingtian/p/11310713.html

[html] html5的video如何附带字幕?

[html] html5的video如何附带字幕&#xff1f; <video controls width"400" height"300"> <source src"../hangge.mp4" type"video/mp4"> <track src"hangge.vtt" srclang"zh" kind"subtitl…

window.addeventlistener 不能调用方法_Java入门第十四课:如何定义”方法“

第十四课&#xff0c;学习定义方法。一个对象包含三种最常见的成员&#xff1a;构造器、Field和方法。Field用于定义状态数据&#xff0c;而方法是行为特征的抽象。那么什么是方法呢&#xff1f;在Java中&#xff0c;方法就是用来完成解决某件事情或实现某个功能的办法。方法实…

remmina连接xfce桌面的centos7

vnc无法连到linux server&#xff0c;但ssh可以的解决方法 原文引自&#xff1a;https://blog.csdn.net/h00ahaha/article/details/84440449 今天用vnc连远程服务器&#xff0c;一直给我提示Failed to connect to server.记录下解决该问题的步骤&#xff1a;1 确认ssh能登录&am…

[html] 你有使用过html5的rt标签吗?它有什么应用场景?

[html] 你有使用过html5的rt标签吗&#xff1f;它有什么应用场景&#xff1f; <ruby>汉 <rt>Hn</rt>字 <rt>Z</rt> </ruby>个人简介 我是歌谣&#xff0c;欢迎和大家一起交流前后端知识。放弃很容易&#xff0c; 但坚持一定很酷。欢迎大…