【实践】Memcached实例解析

一、关于Memcached

Memcached是一个自由开源的,高性能分布式内存对象缓存系统。 Memcached是一种基于内存的Key-Value存储,用来存储小块的任意数据(字符串、对象)。这些数据可以是数据库调用、API调用或者是页面渲染的结果。 Memcached简洁而强大。它的简洁设计便于快速开发,减轻开发难度,解决了大数据量缓存的很多问题。它的API兼容大部分流行的开发语言。 本质上,它是一个简洁的key-value存储系统。 一般的使用目的,是通过缓存数据库查询结果,减少数据库访问次数,以提高动态Web应用的速度、提高可扩展性。

二、Memcached特征

Memcached作为高速运行的分布式缓存服务器,具有以下的特点。

  • 协议简单
  • 基于libevent的事件处理
  • 内置内存存储方式
  • Memcached不互相通信的分布式

Memcached的分布式部署极其简单,通常较小的应用一台Memcached服务器就可以满足需求,但是大中型项目可能就需要多台Memcached服务器了,这就牵涉到一个分布式部署的问题。对于多台Memcached服务器,怎么确定一个数据应该保存到哪台服务器呢?有两种方案,一是普通Hash分布,二是一致性Hash分布。普通Hash分布对于Memcached服务器数量固定的情况推荐使用,比较简单。但是当服务器数量发生改变时,问题就出来了。因为同一个KEY经Hash算法处理后,与服务器数量取模,会导致结果与服务器数量未变化时不同,这就导致之前保存的数据丢失。采取一致性Hash分布可以有效的解决这个问题,把丢失的数据减到最小(注意这里并没有说完全不丢失)。

三、Memcached实际运用

下面通过一个简单的实例来说明Memcached的高性能,以及Memcached是如何工作的。数据源采用的是随机生成的1500万条记录,通过控制台程序来模拟用户登录的业务逻辑,如果首次登录成功,则把用户信息写入Memcached缓存中,再次登录时即可从缓存中取得用户信息进行验证。以下是详细代码过程:

数据操作接口:

 1 namespace MemcachedLibrary
 2 {
 3     interface IDataOperator
 4     {
 5         //获取数据库连接
 6         SqlConnection OpenConnection();
 7         //获取用户信息
 8         void GetUserInfo(string user, string pass);
 9     }
10 }

具体的登录业务操作:

 1 public class SQLDataOperator : IDataOperator
 2     {
 3         //数据库连接串
 4         private const string connectKey = "server=DESKTOP-ALQLV05;database=db_TencentEmailInfo;uid=sa;pwd=";
 5
 6         //标记变量,标记是否已经缓存
 7         private bool IsMemcachedFinished = false;
 8
 9         //获取用户信息
10         public void GetUserInfo(UserInfo user)
11         {
12             Stopwatch memcachedWatch = new Stopwatch();
13             memcachedWatch.Start();
14
15             //从Memcached中取得数据,初始化SockIOPool
16             SockIOPool pool = MemcachedMain.MemcachedInitialize();
17             MemcachedClient client = MemcachedMain.GetMemcachedInstance();
18             //检查Memcached是否缓存了User信息
19             if (client.KeyExists("user") && client.KeyExists("pass"))
20             {
21                 if (user.User == client.Get("user").ToString() && user.Pass == client.Get("pass").ToString())
22                 {
23                     Debug.WriteLine("登录成功!已从Memcached中取得用户信息!");
24                 }
25                 IsMemcachedFinished = true;
26             }
27             memcachedWatch.Stop();
28             Debug.WriteLine("Memcached取得用户信息耗时:" + memcachedWatch.ElapsedMilliseconds + "毫秒");
29
30             //如果Memcached中已经缓存User信息,则无需到数据库中检索数据,提高性能
31             if (IsMemcachedFinished)
32             {
33                 return;
34             }
35
36
37             //如果Memcached中没有缓存过数据,则从数据库中取得数据,并将结果缓存到Memcached
38             Stopwatch databaseWatch = new Stopwatch();
39             databaseWatch.Start();
40             SqlConnection con = OpenConnection();
41             string cmdsql = string.Format("select * from tb_emailInfo where email=‘{0}‘ and classCode=‘{1}‘ ", user.User, user.Pass);
42             using (SqlCommand cmd = new SqlCommand(cmdsql, con))
43             {
44                 DataTable tb = new DataTable();
45                 SqlDataAdapter sda = new SqlDataAdapter(cmd);
46                 sda.Fill(tb);
47                 Debug.WriteLine("登录成功!已从数据库中取得用户信息!已查询到人数:" + tb.Rows.Count);
48                 if (tb.Rows.Count > 0)
49                 {
50                     client.Set("user", user.User, DateTime.Now.AddMinutes(30));//Set中的第三个参数是指定缓存过期时间
51                     client.Set("pass", user.Pass, DateTime.Now.AddMinutes(30));
52                 }
53             }
54             databaseWatch.Stop();
55             Debug.WriteLine("数据库取得用户信息耗时:" + databaseWatch.ElapsedMilliseconds + "毫秒");
56         }
57
58         public SqlConnection OpenConnection()
59         {
60             SqlConnection conn = new SqlConnection(connectKey);
61             {
62                 conn.Open();
63                 Debug.WriteLine(conn.State);
64                 return conn;
65             }
66         }

下面的代码是在控制台调用的过程:

 1 class Program
 2     {
 3         static void Main(string[] args)
 4         {
 5
 6             while (true)
 7             {
 8                 UserInfo userInfo = new UserInfo();//只存储了用户名和密码属性的实体
 9                 Console.WriteLine("请输入测试用户:");
10                 userInfo.User = Console.ReadLine();
11                 Console.WriteLine("请输入测试密码:");
12                 userInfo.Pass = Console.ReadLine();
13
14                 SQLDataOperator sqlDO = new SQLDataOperator();
15                 Stopwatch watch = new Stopwatch();
16                 watch.Start();
17                 sqlDO.GetUserInfo(userInfo);
18                 watch.Stop();
19
20             }
21         }
22     }

最后的运行结果截图如下:

图一

图二

图三

图四

本文的实例是将用户信息以字符串的形式缓存起来并提供检索,其实也可以直接把UserInfo实体对象缓存到Memcached中,取出来后进行转化即可,前提是Userinfo需要有序列化关键字serializable关键字。后面有时间在更新下Memcached缓存实体的实例。

参考资料:

http://www.runoob.com/memcached/memcached-tutorial.html  Memcached详细教程

https://blog.phpha.com/backup/archives/1303.html  Memcached分布式部署

作者:悠扬的牧笛

博客地址:http://www.cnblogs.com/xhb-bky-blog/p/5782444.html

声明:本博客原创文字只代表本人工作中在某一时间内总结的观点或结论,与本人所在单位没有直接利益关系。非商业,未授权贴子请以现状保留,转载时必须保留此段声明,且在文章页面明显位置给出原文连接。

时间: 2024-08-18 03:34:30

【实践】Memcached实例解析的相关文章

搭建NFS文件共享--实例解析

1 NFS简介 NFS 是Network File System的缩写,即网络文件系统.一种使用于分散式文件系统的协定,由Sun公 司开发,于1984年向外公布.功能是通过网络让不同的机器.不同的操作系统能够彼此分享个别的数据, 让应用程序在客户端通过网络访问位于服务器磁盘中的数据,是实现磁盘文件共享的一种方法. NFS 的基本原则是"容许不同的客户端及服务端通过一组RPC分享相同的文件系统",它是独立于操作 系统,容许不同硬件及操作系统的系统共同进行文件的分享. 2 NFS服务器的配

第7章 Android HAL实例解析

第7章 Android HAL实例解析 通过本章介绍Android的HAL知道HAL是为了一些硬件提供商提出的保护专利的驱动程序而产生的,是为了避开Linux的GPL束缚.HAL主要的存储目录有:1.libhardware_legany  2.libhardware:3.ril   4.msm7k.主要包含以下一些模块:Gps.Vibrator.Wifi.Copybit.Audio.Camera.Lights.Ril.Overlay等.大概了解了Android  HAL. 第1中方法 直接调用s

基于Android2.3.5系统:JNI与HAL实例解析[一]

*************************************************************************************************************************** 作者:EasyWave                                                                                                           时间:2015.

memcached—Java操作Memcached实例

前面博客介绍了如何在Windows操作系统中安装Memcached,总结一下如何使用Java操作Memcached实例: 代码一: package com.ghj.packageoftool; import java.io.BufferedWriter; import java.io.FileWriter; import java.io.IOException; import java.io.PrintWriter; import java.io.StringWriter; import jav

ASP连接sql server实例解析

1.首先确定自己的iis没有问题 2.其次确定自己sqlserver没有问题 然后在iis的文件夹wwwroot里,建立一个文件 名为testSqlServer.asp,编写代码例如以下就可以 <% 'ole db连接 set cnn1 = Server.CreateObject("ADODB.Connection") '连接串需要注意sqlserver的实例名,是否是默认,非默认必需要写出来 cnn1.Open "provider=sqloledb;data sour

Android开发之UI更新交互机制与实例解析

android开发过程中,经常需要更新UI的状态和文案等.这是就需要对UI进行 更新.在android中更新UI一般有三种方法,handler机制.RunOnUiThread方法以及AsyncTask异步类方法等 本文下面就这三种方法进行了演示和代码实现. a.Handler机制通过使用消息机制来实现 b.RunOnUiThread方法是通过运行UI线程来达到更新UI的目的 c.AsyncTask是异步类,通过异步更新来更新UI 效果图如下:           (1)Java功能实现代码如下:

深入浅出实例解析linux内核container_of宏

做一件事情首先应该知道它的目的是什么. container_of的目的:如何通过结构中的某个变量获取结构本身的指针. 总体思路:假想一下,你的结构体中有好几个成员,你如何通过里面的"任一成员"获取整个结构体的首地址呢.container_of的做法就是通过typeof定义一个与"任一成员"同类型的指针变量pvar_a(假设变量名就是pvar_a),并让指针变量pvar_a指向这个"任一成员",然后用 "pvar_a的地址" 减

jQuery CSS()方法改变CSS样式实例解析

转自:http://www.jbxue.com/article/24588.html 分享一个jQuery入门实例:使用CSS()方法改变现有的CSS样式表,css()方法在使用上具有多样性.其中有一种可接受两个输入参数:样式属性和样式值,两者之间用逗号分隔.比如要改变链接颜色,可以这样编写代码: $("#61dh a").css('color','#123456');//选择器‘$("#61dh a")'表示ID为‘#61dh'的元素下的所有链接.//.css(‘

Android开发之IPC进程间通信-AIDL介绍及实例解析

一.IPC进程间通信 IPC是进程间通信方法的统称,Linux IPC包括以下方法,Android的进程间通信主要采用是哪些方法呢? 1. 管道(Pipe)及有名管道(named pipe):管道可用于具有亲缘关系进程间的通信,有名管道克服了管道没有名字的限制,因此,除具有管道所具有的功能外,它还允许无亲缘关系进程间的通信:   2. 信号(Signal):信号是比较复杂的通信方式,用于通知接受进程有某种事件发生,除了用于进程间通信外,进程还可以发送信号给进程本身:linux除了支持Unix早期