【实践】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缓存中,再次登录时即可从缓存中取得用户信息进行验证。以下是详细代码过程:
数据操作接口:
- namespace MemcachedLibrary
- {
- interface IDataOperator
- {
- //获取数据库连接
- SqlConnection OpenConnection();
- //获取用户信息
- void GetUserInfo(string user, string pass);
- }
- }
具体的登录业务操作:
- public class SQLDataOperator : IDataOperator
- {
- //数据库连接串
- private const string connectKey = "server=DESKTOP-ALQLV05;database=db_TencentEmailInfo;uid=sa;pwd=";
- //标记变量,标记是否已经缓存
- private bool IsMemcachedFinished = false;
- //获取用户信息
- public void GetUserInfo(UserInfo user)
- {
- Stopwatch memcachedWatch = new Stopwatch();
- memcachedWatch.Start();
- //从Memcached中取得数据,初始化SockIOPool
- SockIOPool pool = MemcachedMain.MemcachedInitialize();
- MemcachedClient client = MemcachedMain.GetMemcachedInstance();
- //检查Memcached是否缓存了User信息
- if (client.KeyExists("user") && client.KeyExists("pass"))
- {
- if (user.User == client.Get("user").ToString() && user.Pass == client.Get("pass").ToString())
- {
- Debug.WriteLine("登录成功!已从Memcached中取得用户信息!");
- }
- IsMemcachedFinished = true;
- }
- memcachedWatch.Stop();
- Debug.WriteLine("Memcached取得用户信息耗时:" + memcachedWatch.ElapsedMilliseconds + "毫秒");
- //如果Memcached中已经缓存User信息,则无需到数据库中检索数据,提高性能
- if (IsMemcachedFinished)
- {
- return;
- }
- //如果Memcached中没有缓存过数据,则从数据库中取得数据,并将结果缓存到Memcached
- Stopwatch databaseWatch = new Stopwatch();
- databaseWatch.Start();
- SqlConnection con = OpenConnection();
- string cmdsql = string.Format("select * from tb_emailInfo where email='{0}' and classCode='{1}' ", user.User, user.Pass);
- using (SqlCommand cmd = new SqlCommand(cmdsql, con))
- {
- DataTable tb = new DataTable();
- SqlDataAdapter sda = new SqlDataAdapter(cmd);
- sda.Fill(tb);
- Debug.WriteLine("登录成功!已从数据库中取得用户信息!已查询到人数:" + tb.Rows.Count);
- if (tb.Rows.Count > )
- {
- client.Set("user", user.User, DateTime.Now.AddMinutes());//Set中的第三个参数是指定缓存过期时间
- client.Set("pass", user.Pass, DateTime.Now.AddMinutes());
- }
- }
- databaseWatch.Stop();
- Debug.WriteLine("数据库取得用户信息耗时:" + databaseWatch.ElapsedMilliseconds + "毫秒");
- }
- public SqlConnection OpenConnection()
- {
- SqlConnection conn = new SqlConnection(connectKey);
- {
- conn.Open();
- Debug.WriteLine(conn.State);
- return conn;
- }
- }
下面的代码是在控制台调用的过程:
- class Program
- {
- static void Main(string[] args)
- {
- while (true)
- {
- UserInfo userInfo = new UserInfo();//只存储了用户名和密码属性的实体
- Console.WriteLine("请输入测试用户:");
- userInfo.User = Console.ReadLine();
- Console.WriteLine("请输入测试密码:");
- userInfo.Pass = Console.ReadLine();
- SQLDataOperator sqlDO = new SQLDataOperator();
- Stopwatch watch = new Stopwatch();
- watch.Start();
- sqlDO.GetUserInfo(userInfo);
- watch.Stop();
- }
- }
- }
最后的运行结果截图如下:
图一
图二
图三
图四
本文的实例是将用户信息以字符串的形式缓存起来并提供检索,其实也可以直接把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
声明:本博客原创文字只代表本人工作中在某一时间内总结的观点或结论,与本人所在单位没有直接利益关系。非商业,未授权贴子请以现状保留,转载时必须保留此段声明,且在文章页面明显位置给出原文连接。
【实践】Memcached实例解析的更多相关文章
- nodejs 实践:express 最佳实践(四) express-session 解析
nodejs 实践:express 最佳实践(四) express-session 解析 nodejs 发展很快,从 npm 上面的包托管数量就可以看出来.不过从另一方面来看,也是反映了 nodejs ...
- nodejs 实践:express 最佳实践(三) express 解析
nodejs 实践:express 最佳实践(三) express 解析 nodejs 发展很快,从 npm 上面的包托管数量就可以看出来.不过从另一方面来看,也是反映了 nodejs 的基础不稳固, ...
- nodejs 实践:express 最佳实践(五) connect解析
nodejs 实践:express 最佳实践(五) connect解析 nodejs 发展很快,从 npm 上面的包托管数量就可以看出来.不过从另一方面来看,也是反映了 nodejs 的基础不稳固,需 ...
- MySQL数据库企业级应用实践(多实例源码编译)
MySQL数据库企业级应用实践(多实例源码编译) 链接:https://pan.baidu.com/s/1ANGg3Kd_28BzQrA5ya17fQ 提取码:ekpy 复制这段内容后打开百度网盘手机 ...
- exec函数族实例解析
exec函数族实例解析 fork()函数通过系统调用创建一个与原来进程(父进程)几乎完全相同的进程(子进程是父进程的副本,它将获得父进程数据空间.堆.栈等资源的副本.注意,子进程持有的是上述存储空间的 ...
- [Reprint] C++函数模板与类模板实例解析
这篇文章主要介绍了C++函数模板与类模板,需要的朋友可以参考下 本文针对C++函数模板与类模板进行了较为详尽的实例解析,有助于帮助读者加深对C++函数模板与类模板的理解.具体内容如下: 泛型编程( ...
- [Reprint]C++普通函数指针与成员函数指针实例解析
这篇文章主要介绍了C++普通函数指针与成员函数指针,很重要的知识点,需要的朋友可以参考下 C++的函数指针(function pointer)是通过指向函数的指针间接调用函数.相信很多人对指向一般 ...
- JavaWeb实现文件上传下载功能实例解析
转:http://www.cnblogs.com/xdp-gacl/p/4200090.html JavaWeb实现文件上传下载功能实例解析 在Web应用系统开发中,文件上传和下载功能是非常常用的功能 ...
- Android实例-Delphi开发蓝牙官方实例解析(XE10+小米2+小米5)
相关资料:1.http://blog.csdn.net/laorenshen/article/details/411498032.http://www.cnblogs.com/findumars/p/ ...
随机推荐
- Android Weekly Notes Issue #219
Android Weekly Issue #219 August 21st, 2016 Android Weekly Issue #219 ARTICLES & TUTORIALS Andro ...
- 【代码笔记】iOS-自定义弹出框
代码: - (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view. [s ...
- iOS中多线程的实现方案
什么是主线程? 一个iOS程序运行后,默认会开启一条线程,称为“主线程”或“UI线程” 主线程的主要作用 1.显示/刷新UI界面 2.处理UI事件(比如点击事件,滚动事件,拖拽事件) 主线程的使用注意 ...
- 【转】浅谈JavaScript、ES5、ES6
什么是JavaScript JavaScript一种动态类型.弱类型.基于原型的客户端脚本语言,用来给HTML网页增加动态功能.(好吧,概念什么最讨厌了) 动态: 在运行时确定数据类型.变量使用之前不 ...
- GUID生成器
这个GUID生成器是一个小巧的软件,属于笔者在空余时间开发的. http://pan.baidu.com/s/1sk6VGpn
- 关于web端功能测试的测试方向
一.功能测试 1.1链接测试 链接是web应用系统的一个很重要的特征,主要是用于页面之间切换跳转,指导用户去一些不知道地址的页面的主要手段,链接测试一般关注三点: 1)链接是否按照既定指示那样,确实链 ...
- Java 根据经纬度计算两点之间的距离
package xxx.driver.business.utils; /** * <p>Represents a point on the surface of a sphere. (Th ...
- JS原型链
JS作为发展了多年了对象语言,支持继承,和完全面向对象语言不同的是,JS依赖原型链来实现对象的继承. 首先JS的对象分两大类,函数对象和普通对象,每个对象均内置__proto__属性,在不人为赋值__ ...
- Windows Installer 服务启动错误 14007 的解决办法
问题: 在 本地计算机 无法启动 Windows Installer 服务. 错误代码 14007: 在活动的激活上下文中没有找到任何查找密钥. 这个问题似乎涉及到 Windows Installer ...
- 卷积神经网络(CNN)学习算法之----基于LeNet网络的中文验证码识别
由于公司需要进行了中文验证码的图片识别开发,最近一段时间刚忙完上线,好不容易闲下来就继上篇<基于Windows10 x64+visual Studio2013+Python2.7.12环境下的C ...