memcache讲解和在.net中初使用
memcache讲解和在.net中初使用
前言
将登陆信息和状态保存到哪里一直是我困惑的。保存到cookie里面?不不,太不安全;保存到session?不不,处于进程里影响性能降低还易丢失;保存到数据库?我的确这样想过也试过,安全又完整但是读数据库让我不满意;保存到HttpRunTime.Cache里面?
在查找一些资源后我了解到可以保存到缓存数据库里面,memcache就是其中一款缓存数据库,并且还拥有其他的好处。
在我们了解memcache之前,先了解以下信息:
传统数据库面临的问题
Web程序在面临海量数据、高并发请求时,传统的数据库往往会面临以下问题:
数据库死锁
数据库基本操作curd,死锁是数据库高并发的明显问题:r要加S锁(共享锁,可以查看但是无法cud),cud要加X锁(排他锁,可以curd,其他事务无法再次加锁),当高并发请求,数据库可能产生死锁(数据库阻塞,永远等待状态)。这是无法避免的问题。以下是解决死锁的常见手段:
- 死锁预防
使用数据库逻辑上来预防死锁,但是这显然还会出现慢的问题。 读写分离
就是做数据库集群,使用主从数据库:将数据保存到多个主从数据库里面,主数据库负责cud,多个从数据库负责r,这样不仅避免死锁,也提高了速度。但是同样带来了问题:数据同步
多个数据库要同步数据,常见三种数据库对数据同步的支持:- SqlServer
sqlserver在数据同步方面很弱,并不适合数据同步。主要有三种方法实现:买中间件(不可靠)、发布订阅(主库生成数据库快照给其他数据库,但是有延迟)、代码实现写入多个数据库(不好)。 - Mysql
有很多第三方组件可以实现,很多成功的例子。 - Oracle
本身就支持数据库同步,只需要配置以下就好了。(另外Oracle因为会最大程序占用资源,所以效率很高)
- SqlServer
磁盘IO
数据库把数据保存到磁盘上,读取慢,磁盘IO是一大原因,因为磁盘IO是硬件问题。常见解决方式如下:
水平分布和垂直分布
相当与分布式数据库:水平分布是根据数据自定义规则(如userId的奇偶)保存到不同的数据库,垂直分布是根据数据的类型(如图片库,收藏夹)保存到不同的数据库。使用NoSql中的内存数据库
- NoSql定义
NoSQL(NoSQL = Not Only SQL ),意即“不仅仅是SQL”,非关系型数据库,存储数据更多的是保存数据本身,不需要预先定义数据格式。 - 内存数据库
memcache是分布式内存数据库,使用key-value存储数据。将数据缓存到内存中可以高速存取。因为只是key-value集合即不会有死锁。并且实现了数据共享,试想下某度贴吧和云盘反复当你登陆,不是很好的感觉吧。
- NoSql定义
接下来使用控制台应用程序来操作memcache。
正文
了解memcache
memcache官网
memcached是一种高性能,分布式的内存对象缓存系统,本质上是通用的,但最初旨在通过减轻数据库负载来加速动态Web应用程序。
原理
- 内存处理
- 内存分区解决内存碎片问题
memcache实现会对可用内存进行划分分区,每个区内分成若干块,同一个区内块的大小固定。当进行数据存储,就会自动寻找适合的区存进块内。最大的块是1M。比如第一个区内只存0.5M的块,第二个块只存0.6M的数据,现在过来一个0.55M的数据就会存到第二个区内,占用0.6M的空间,虽然块内有空间浪费,但是块与块之间没有缝隙。- 惰性删除
memcache并没有提供数据监控机制,而是查询到某个数据,如果过期才会删除。
如果内存满了,就会策略LRU闲置>过期>最少访问来清空删除数据
- 惰性删除
- 内存分区解决内存碎片问题
- 客户端实现分布式:
给memcache配置多个服务器ip,当需要查询时会寻找哪台服务器或者添加一个数据时会保存到哪一个服务器上呢?memcache对key值进行哈希计算然后对配置的服务器总数进行取余,余数是几就向第几台服务器进行操作。这就导致了一个问题:当服务器数量发生变化时会导致部分数据丢失(查询指向服务器错误)。想要这种影响降低到最低,可以使用一致性哈希算法。 - 走socket
数据通信走的是socket。
基本命令
这里引用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是项目的名字,memcached是项目被可执行代码的名字,一般指同一个东西。
memcache的适用范围
可以将其视为应用程序的短期内存。不适合保存持久化数据。其是分布式系统,数据分布在多个机器上迁移很麻烦。也不会记录数据。这里用户的登陆状态并不需要专门保存,可以使用memcache保存。
memcache的客户端和服务端
memcache有客户端和服务端之分,客户端编程,需要引用相应的dll文件;服务端开启memcached服务。
memcache服务端本身不支持windows下使用,但是一些爱好者提供了windows下的exe程序来开启这个服务。
请搜索Memcached.ClientLibrary来下载你需要使用的dll文件和exe服务,我是在sourceforge这里下载的。
memcache与redis异同
memcache经常与redis进行对比
- 相同点:
都使用内存;效率都很高,1s内读1w次,写10w次都很平常; - 不同点:
- 线程
memcache是多线程,redis是单线程,所以写多数据时memcache效率更好。 - 数据类型
memcached使用key-value存储,本身就是一个hash(哈希表)。
redis现阶段提供五种数据类型:string(字符串类型)、list(链表)、set(集合)、zset(有序集合)、hash(哈希表)。 - 数据存储
memcache是分布式系统,每个服务器都值保存一部分数据,迁移很弱(memcache定位就是短期内存,保存在memcache里面的数据本来就是不需要迁移的)。断电丢失数据。
redis启用内存但是可以保证数据持久化、完整性和同步,即每个服务器都保存完整数据。这是因为redis的存储分为内存存储、磁盘存储和log文件三部分,配置文件中有三个参数对其进行配置,断电之后可以通过文件来恢复数据;使用快照的方式进行数据同步。
- 线程
简单使用memcached
打开memcache服务
这一步相当玉开启服务端的memcache服务。在windows下开启服务相当简单,直接打开这个exe程序就行了
但是这个程序结束后服务就关闭了。这里把它安装成windows下的一个服务。
打开管理员命令提示符,输入exe文件的路径和安装命令
然后memcached就成为windows下的一个服务了,可以设置自动手动之类的。
使用memcached命令
如果只是布置服务端的话,上一步就已经完成了。如果想要连接服务端的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();
}
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
运行效果
引申
- 集群和分布式
数据库集群:往往在同一局域网,使用同一个IP,每个数据库有完整数据,难点是数据同步,迁移方便。
数据库分布式:每个系统拥有部分数据,使用使用简单,数据迁移麻烦。 - Redis主从数据库
主库负责写,从库负责读,压力分流。
主库挂掉,随机选择一个从库成为主库。
数据如何同步:快照。
总结
- memcache的key值最大255字符
- memcached的块最大1M
若有错误请指正,不胜感激。
memcache讲解和在.net中初使用的更多相关文章
- Consul在.Net Core中初体验
Consul在.Net Core中初体验 简介 在阅读本文前我想您应该对微服务架构有一个基本的或者模糊的了解 Consul是一个服务管理软件,它其实有很多组件,包括服务发现配置共享键值对存储等 本文主 ...
- 简单讲解iOS应用开发中的MD5加密的相关使用
简单讲解iOS应用开发中的MD5加密的相关使用 作者:文顶顶 字体:[增加 减小] 类型:转载 时间:2015-12-19 我要评论 这篇文章主要介绍了iOS应用开发中的MD5加密的相关使用, ...
- 第三百三十六节,web爬虫讲解2—urllib库中使用xpath表达式—BeautifulSoup基础
第三百三十六节,web爬虫讲解2—urllib库中使用xpath表达式—BeautifulSoup基础 在urllib中,我们一样可以使用xpath表达式进行信息提取,此时,你需要首先安装lxml模块 ...
- 2016.8.15上午纪中初中部NOIP普及组比赛
2016.8.15上午纪中初中部NOIP普及组比赛 链接:https://jzoj.net/junior/#contest/home/1333 这次比赛不怎么好,因为这套题目我并不是很擅长. 可同学们 ...
- 2016.8.18上午纪中初中部NOIP普及组比赛
2016.8.18上午纪中初中部NOIP普及组比赛 链接:https://jzoj.net/junior/#contest/home/1336 翻!车!啦!好吧,那是因为大神归来. 进度: 比赛:AC ...
- 2016.8.17上午纪中初中部NOIP普及组比赛
2016.8.17上午纪中初中部NOIP普及组比赛 链接:https://jzoj.net/junior/#contest/home/1335 本来觉得自己能考高分,但只得160分,并列第九.至少又挤 ...
- 2016.8.16上午纪中初中部NOIP普及组比赛
2016.8.16上午纪中初中部NOIP普及组比赛 链接:https://jzoj.net/junior/#contest/home/1334 这次也翻车了,感觉比之前难多了. 辛辛苦苦改完了,太难改 ...
- 安装php扩展模块参数memcache和memcached在php中的应用
一, memcache和memcached的区别与关系统php要想去访问memcached就得需要memcache扩展,这个道理和php连接mysql一样. 你不安装memcache扩展就没法识别me ...
- 多测师讲解python _函数中参数__高级讲师肖sir
函数中讲解参数: 形参和实参的认识 函数无参数的调用 函数单个参数的调用 函数多个参数的调用 # #调试函数给默认参数传新值,则函数使用新值 # 注意:当多种参数同时出现在函数中,默认参数要放在最后的 ...
随机推荐
- laravel接值 get post
laravel使用一种简单的方式来访问用户提交的信息. 你可以用统一的方式来访问用户提交的信息,而不用为用户提交信息的方式操心. 引用类:use Illuminate\Support\Facades\ ...
- babel在项目里的使用
1.手动在项目里创建文件 .babelrc 2.安装 $ npm install --save-dev babel-cli # ES2015转码规则 $ npm install --save-dev ...
- angular url 传参
1.路由里配置参数operation 2.页面A跳转时带上参数 $scope.goPage = function (op) { $state.go("app.productConfigadd ...
- 【CSS学习】--- 文本水平对齐属性text-align和元素垂直对齐属性vertical-align
一.文本水平对齐属性---text-align text-align属性是将块级标签以及单元格里面的内容进行相应的对齐,块级标签里的内联元素会被整体进行移动,而子块级元素或子单元格则会继承父元素的te ...
- BZOJ 1874: [BeiJing2009 WinterCamp]取石子游戏(SG函数)
Time Limit: 5 Sec Memory Limit: 162 MBSubmit: 871 Solved: 365[Submit][Status][Discuss] Description ...
- 关于TensorFlow你需要了解的9件事
关于TensorFlow你需要了解的9件事 https://mp.weixin.qq.com/s/cEQAdLnueMEj0OQZtYvcuw 摘要:本文对近期在旧金山举办的谷歌 Cloud Next ...
- 在Arcmap中加载互联网地图资源的4种方法
前一段时间想在Arcmap中打开互联网地图中的地图数据,如影像数据.基础地图数据等,经过简单研究目前总结了四种方法,整理下与大家分享,有些内容可能理解有误,希望大家多多指教.4种方法如下: a) ...
- Statement和PreparedStatement的异同
1.首先两个都是java向数据库执行sql语句的对象! java代码连接数据库,并且执行sql语句的步骤如下: //1.注册数据库的驱动程序 Class.forName(driverClass); / ...
- 自己动手写Android插件化框架,让老板对你刮目相看
欢迎大家前往腾讯云+社区,获取更多腾讯海量技术实践干货哦~ 本文由达文西发表于云+社区专栏 最近在工作中接触到了Android插件内的开发,发现自己这种技术还缺乏最基本的了解,以至于在一些基本问题上浪 ...
- LeetCode题解之Keys and Rooms
1.题目描述 2.问题分析 使用深度优先遍历 3.代码 bool canVisitAllRooms(vector<vector<int>>& rooms) { int ...