关于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/ ...
随机推荐
-
Poj(2253),Dijkstra松弛条件的变形
题目链接:http://poj.org/problem?id=2253 题意: 给出两只青蛙的坐标A.B,和其他的n-2个坐标,任一两个坐标点间都是双向连通的.显然从A到B存在至少一条的通路,每一条通 ...
-
Oracle 动态视图1 V$LOCK
v$lock显示数据库当前持有锁情况 Column Datatype Description SID NUMBER 会话ID TYPE VARCHAR2(2) 表示锁的类型.值包括TM,TX,等 ID ...
-
mysql 主从同步 实现增量备份
数据库复制 replication 的实现原理 1:主服务器凡运行语句,都产生一个二进制日志 binlog 2:从服务器不断读取主服务器的binlog 3:从主服务读取到的binlog,转换为自身可执 ...
-
数据分析 大数据之路 三 numpy
import numpy as np a = np.arange(9) b = a.reshape(3,3) print(b) print(b.max(axis=0)) # axis=0 示为 Y 轴 ...
-
Centos7 MongoDB-3.4
MongoDB 是一个介于关系数据库和非关系数据库之间的产品,是非关系数据库当中功能最丰富,最像关系数据库的 关系型数据库遵循ACID规则 事务在英文中是transaction,和现实世界中的交易很类 ...
-
DNS解析分析
一.基本概念 域名系统: 域名系统(英文:Domain Name System,缩写:DNS)是因特网的一项服务.它作为将域名和IP地址相互映射的一个分布式数据库,能够使人更方便地访问互联网.DNS使 ...
-
微信小程序-1
微信小程序 (开发微信小程序基础:HTML+js+css) l 准备工作 工具安装 开发工具是由微信官方提供 项目的预览(校验环境) l 开发体验阶段 - Hello world ...
-
C#如何提取.txt文件中的每个字符串
C#如何提取.txt文件中的每个字符串,并将其存放到一个类中. 将其中的编号 菜名 价格 分别存入不同的数组中. 注:在用ReadLine读取一行信息时为什么读取的中文字符变成了乱码. 20 满意答案 ...
-
java高并发总结-常用于面试复习
定义: 独占锁是一种悲观保守的加锁策略,它避免了读/读冲突,如果某个只读线程获取锁,则其他读线程都只能等待,这种情况下就限制了不必要的并发性,因为读操作并不会影响数据的一致性. 共享锁则是一种乐观锁, ...
-
[ActionScript 3.0] AS向php发送二进制数据方法之——在URLRequest中构造HTTP协议发送数据
主类 HTTPSendPHP.as package { import com.JPEGEncoder.JPGEncoder; import com.fylib.httpRequest.HttpRequ ...