关于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包

View 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

第一节 Memcached分布式缓存入门相关推荐

  1. 缓存应用--Memcached分布式缓存简介(二)

    1 命令行查看状态 很多时候我们需要去查看Memcached 的使用状态,比如Memcached 的运行时间,使用状态等等.在Windows系统中我们可以使用telnet 命令来查看Memcached ...

  2. WEB缓存技术之阿堂教程:聊聊memcached分布式缓存技术--好文转载

    转自:http://blog.sina.com.cn/s/blog_4c925dca010193sy.html 阿堂最早接触memcached技术,实际 上是在原来的一家游戏公司,因为阿堂带领项目组开 ...

  3. 逆战小白学习日記(第一节)——web前端入门准备

    在接下来的时间里,我将系统的从入门到深入给大家分享我的学习经历,为大家介绍并讲解从一名小白到老鸟,都要学习哪些东西,喜欢的可以关注我一下...... 首先,入门的两大神器 PhotoshopCC,Vi ...

  4. mysql php 入门_第一节 数据库概述_MySQL_php入门教程

    数据库是数据管理的有效技术,是计算机科学的重要分支.随着时代的发展,今天信息资源已经成为一种宝贵的财富.从校务管理系统到电子政务.商务系统,这些社会的方方面面都会产生庞大的数据,管理和使用这些数据成为 ...

  5. 19 分布式缓存集群的伸缩性设计

    不同于应用服务器集群的伸缩性设计,分布 式缓存集群的伸缩性不能使用简单的负载均衡手段来实现. 和所有服务器都部署相同应用的应用服务器集群不同,分布式缓存服务器集群中不同服务器中缓存的数据各不相同,缓存 ...

  6. 服务端分布式缓存与本地缓存

    缓存技术是保障系统性能的基础技术.核心技术. 缓存发挥的作用 ① 最大程度上避免对数据库的并发查询,从而降低因为数据库资源不足导致的系统故障. ② 提升系统的响应速度,保证用户体验 总之缓存使系统稳定 ...

  7. 分布式缓存和本地缓存的区别

    分布式缓存和本地缓存的区别 redis/memcached**分布式缓存**和map/guava**本地缓存**的区别 什么是缓存一致性? redis/memcached分布式缓存和map/guava ...

  8. php分布式缓存系统 Memcached 入门

    Memcached 是一个分布式的缓存系统, 但是 Memcachd 到底是什么意思,有什么作用呢?缓存一般用来保存一些经常被存取的数据和资源(例如:浏览器会将访问过的网页会话缓存起来),因为通过缓存 ...

  9. memcached java 客户端优化,分布式缓存技术memcached学习系列(五)—— memcached java客户端的使用...

    Memcached的客户端简介 我们已经知道,memcached是一套分布式的缓存系统,memcached的服务端只是缓存数据的地方,并不能实现分布式,而memcached的客户端才是实现分布式的地方 ...

最新文章

  1. Error running app: Instant Run requires 'Tools | Android | Enable ADB integration' to be enabled.
  2. 强化学习如何真正实现任务自动化?不妨试试「两步走」策略!
  3. [CF]Codeforces Round #528 Div.2
  4. ORA-01994 故障一例
  5. sklearn处理文本和分类属性的方式
  6. Spring4.2.6+SpringMVC4.2.6+MyBatis3.4.0 整合
  7. 第五章 MVC之Bundle详解
  8. 第三届人本沙龙12月活动小结
  9. charts 画折线图
  10. android编译make错误——javalib.jar invalid header field”、classes-full-debug.jar 错误 41 ...
  11. Java实现简单计算器
  12. Word控件Spire.Doc 转换教程(二十一):将非标准字体的word文档转换为PDF
  13. HDU - 6070
  14. ios相机黑边_iOS照相机去黑框
  15. 亚马逊服务器个人文档,AmazonAWS入门-文档.PDF
  16. PL2303驱动不支持Win11及以上版本解决方案
  17. JAVA最佳学习方法
  18. 微信JS-SDK实现自定义分享功能,分享给朋友,分享到朋友圈
  19. 网络测速全解析之一:自定义View基础知识(八)
  20. 《读者》的“卷首语” (二)

热门文章

  1. Jenkins 部署vue到服务器
  2. HBase数据备份及恢复(导入导出)的常用方法
  3. 京东布局消费物联网 聚合产业链共建生态
  4. JAVA解析纯真IP地址库
  5. [LeetCode] Power of Two 判断2的次方数
  6. Android开发群
  7. Windows Phone 实用开发技巧(3):输入框自动聚焦并打开SIP
  8. 食品安全--牛奶和蛋白质浅谈
  9. python初学者_面向初学者的20种重要的Python技巧
  10. leetcode 485. 最大连续1的个数