将登陆信息和状态保存到哪里一直是我困惑的。保存到cookie里面?不不,太不安全;保存到session?不不,处于进程里影响性能降低还易丢失;保存到数据库?我的确这样想过也试过,安全又完整但是读数据库让我不满意;保存到HttpRunTime.Cache里面?
在查找一些资源后我了解到可以保存到缓存数据库里面,memcache就是其中一款缓存数据库,并且还拥有其他的好处。
在我们了解memcache之前,先了解以下信息:
Web程序在面临海量数据、高并发请求时,传统的数据库往往会面临以下问题:
数据库基本操作curd,死锁是数据库高并发的明显问题:r要加S锁(共享锁,可以查看但是无法cud),cud要加X锁(排他锁,可以curd,其他事务无法再次加锁),当高并发请求,数据库可能产生死锁(数据库阻塞,永远等待状态)。这是无法避免的问题。以下是解决死锁的常见手段:
读写分离
就是做数据库集群,使用主从数据库:将数据保存到多个主从数据库里面,主数据库负责cud,多个从数据库负责r,这样不仅避免死锁,也提高了速度。但是同样带来了问题:
数据同步
多个数据库要同步数据,常见三种数据库对数据同步的支持:
数据库把数据保存到磁盘上,读取慢,磁盘IO是一大原因,因为磁盘IO是硬件问题。常见解决方式如下:
水平分布和垂直分布
相当与分布式数据库:水平分布是根据数据自定义规则(如userId的奇偶)保存到不同的数据库,垂直分布是根据数据的类型(如图片库,收藏夹)保存到不同的数据库。
使用NoSql中的内存数据库
接下来使用控制台应用程序来操作memcache。
memcache官网
memcached是一种高性能,分布式的内存对象缓存系统,本质上是通用的,但最初旨在通过减轻数据库负载来加速动态Web应用程序。
这里引用IBM developerWorks里面的一篇文章部分内容
基本 memcached 客户机命令
您将使用五种基本 memcached 命令执行最简单的操作。这些命令和操作包括:
set add replace get delete
前三个命令是用于操作存储在 memcached 中的键值对的标准修改命令。它们都非常简单易用,且都使用清单 5 所示的语法:
清单 5. 修改命令语法
command +key +flags +expiration time+ bytes+
value
key key 用于查找缓存值
flags 可以包括键值对的整型参数,客户机使用它存储关于键值对的额外信息
expiration time 在缓存中保存键值对的时间长度(以秒为单位,0 表示永远)
bytes 在缓存中存储的字节点
value 存储的值(始终位于第二行)
其中key最大长度255字符。
memcache是项目的名字,memcached是项目被可执行代码的名字,一般指同一个东西。
可以将其视为应用程序的短期内存。不适合保存持久化数据。其是分布式系统,数据分布在多个机器上迁移很麻烦。也不会记录数据。这里用户的登陆状态并不需要专门保存,可以使用memcache保存。
memcache有客户端和服务端之分,客户端编程,需要引用相应的dll文件;服务端开启memcached服务。
memcache服务端本身不支持windows下使用,但是一些爱好者提供了windows下的exe程序来开启这个服务。
请搜索Memcached.ClientLibrary来下载你需要使用的dll文件和exe服务,我是在sourceforge这里下载的。
memcache经常与redis进行对比
这一步相当玉开启服务端的memcache服务。在windows下开启服务相当简单,直接打开这个exe程序就行了
但是这个程序结束后服务就关闭了。这里把它安装成windows下的一个服务。
打开管理员命令提示符,输入exe文件的路径和安装命令
然后memcached就成为windows下的一个服务了,可以设置自动手动之类的。
如果只是布置服务端的话,上一步就已经完成了。如果想要连接服务端的memcached服务并且使用命令的话,可以使用以下步骤:
1. 打开Telnet客户端服务
2. 打开管理员命令提示符连接服务端memcached服务
3. 使用命令
连接成功后就会进入控制台界面
第一行代码是不可见的,可以按enter再输入stats(或者直接stats)打开memcached统计信息
然后就可以愉快地输入你的命令了,如使用add命令来添加和get命令获取值,key值已经存在就会返回NOT_STORED提示,如果正确添加就会返回STORED提示。
注意:
命令无法退格,所以输错就按enter重新输入
memcached默认端口11211
默认memcache引用程序集会自带一个log4net.dll文件以便错误时可以记录日志,这里并不需要记录日志就不引用。
using Memcached.ClientLibrary;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace MemcachedDemo
{
class Program
{
static void Main(string[] args)
{
//SockIOPool是Memcached客户端提供的一个套接字连接池,是与Memcached服务器端交换数据的对象。
//SockIOPool在应用程序启动时初始化一次就可以了,我们可以把这个工作放在 GLOBAL.ASAX.CS的Application_Start方法里。
try
{
MemcachedClient mc = new MemcachedClient();
mc.EnableCompression = false;
string[] serverlist = {"127.0.0.1:11211"};
SockIOPool pool = SockIOPool.GetInstance();
//初始化
pool.SetServers(serverlist);
pool.InitConnections = 3;
pool.MinConnections = 3;
pool.MaxConnections = 50;
pool.SocketConnectTimeout = 1000;
pool.SocketTimeout = 3000;
pool.MaintenanceSleep = 30;
pool.Failover = true;
pool.Nagle = false;
pool.Initialize();
mc.Add("key1","这是第一个数据",0);
string value= mc.Get("key1") as string;
Console.WriteLine(value);
}
catch (Exception err)
{
//这里可以用Log4Net记录Error
}
Console.ReadLine();
}
}
}
原文:https://www.cnblogs.com/Jeely/p/10785373.html