Memcached 快速入门
Memcached简介
Memcached是一个专门用来做缓存的服务器,而且缓存的数据都在内存中。Memcached就相当于一个Dictionary键值对集合,保存的是键值对,然后根据key取value。
当然web服务器和Memcached之间还是要网络间通讯,效率还是没有进程内缓存效率高。Memcached程序重启之后数据就会消失。
32位系统 1.4.4版本:http://static.runoob.com/download/memcached-win32-1.4.4-14.zip
64位系统 1.4.4版本:http://static.runoob.com/download/memcached-win64-1.4.4-14.zip
32位系统 1.4.5版本:http://static.runoob.com/download/memcached-1.4.5-x86.zip
64位系统 1.4.5版本:http://static.runoob.com/download/memcached-1.4.5-amd64.zip
安装
在 1.4.5 版本以前 memcached 可以作为一个服务安装,而在 1.4.5 及之后的版本删除了该功能。因此我们以下介绍两个不同版本 1.4.4 及 1.4.5的不同安装方法:
memcached <1.4.5 版本安装
1、解压下载的安装包到指定目录。
2、在 1.4.5 版本以前 memcached 可以作为一个服务安装,使用管理员权限运行以下命令:
c:\memcached\memcached.exe -d install
注意:你需要使用真实的路径替代 c:\memcached\memcached.exe。
3、然后我们可以使用以下命令来启动和关闭 memcached 服务:
c:\memcached\memcached.exe -d start
c:\memcached\memcached.exe -d stop
4、如果要修改 memcached 的配置项, 可以在命令行中执行 regedit.exe 命令打开注册表并找到 "HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\memcached" 来进行修改。
如果要提供 memcached 使用的缓存配置 可以修改 ImagePath 为:
"c:\memcached\memcached.exe" -d runservice -m 512
-m 512 意思是设置 memcached 最大的缓存配置为512M。
此外我们还可以通过使用 "c:\memcached\memcached.exe -h" 命令查看更多的参数配置。
5、如果我们需要卸载 memcached ,可以使用以下命令:
c:\memcached\memcached.exe -d uninstall
.NET连接Memcached
安装Memcached 的.Net 开发包:Install-Package EnyimMemcached
写一个简陋的帮助类,后面再完善
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Enyim.Caching;
using Enyim.Caching.Configuration;
using Enyim.Caching.Memcached;
namespace ConsoleApp1
{
public class MemCachedHelper<T>
{
private static string SERVER = "127.0.0.1:11211";
//过期时间:20分钟
private static int TimeSpanExpired = 20;
private static MemcachedClientConfiguration mcConfiguration = new MemcachedClientConfiguration();
static MemCachedHelper()
{
mcConfiguration.AddServer(SERVER);
}
/// <summary>
/// Set设置key,value
/// </summary>
/// <param name="key"></param>
/// <param name="value"></param>
/// <returns></returns>
public static Boolean SetKey(string key, object value)
{
using (MemcachedClient client = new MemcachedClient(mcConfiguration))
{
/*
* MemcachedClient.Store(StoreMode mode, string key, object value); 使用缓存键将项插入到缓存中, 以引用其位置。
* StoreMode mode 定义项在缓存中的存储方式。
*/
return client.Store(StoreMode.Set, key, value,TimeSpan.FromMinutes(TimeSpanExpired));
}
}
/// <summary>
/// 获取值
/// </summary>
/// <param name="name"></param>
/// <returns></returns>
public static T GetValue(string name)
{
using (MemcachedClient client = new MemcachedClient(mcConfiguration))
{
return (T)client.Get(name);
}
}
}
}
1.Memcache存入的是键值对。
Memcache存入数据的3中模式Set、Replace、Add,
根据名字就能猜出来:
Set:存在则覆盖,不存在则新增
Replace:如果存在则覆盖,并且返回true;如果不存在则不处理,并且返回false;
Add:如果不存在则新增,并且返回true;如果存在则不处理,并且返回false;
没特殊要求一般用Set就可以了。
2.对象序列化
如果保存普通类对象,则对象必须可序列化(不同Memcached客户端保存对象的机制都不尽相同)。
例子:
public class Student
{
public Student(int age, string name)
{
this.age = age;
this.name = name;
}
private int age { get; set; }
private string name { get; set; }
}
这里
//返回false
Console.WriteLine(MemCachedHelper<Student>.SetKey("student", student));
应该添加
[Serializable]
public class Student
{
...
}
3.存入设置过期时间
设置最后一个TimeSpan类型的参数:
client.Store(Enyim.Caching.Memcached.StoreMode.Set, "name", "tangsansan",TimeSpan.FromSeconds(5));
4.读取:client.Get("name")
如果找不到,则返回null。当然也可以用public bool TryGet(string key, out object value)。还支持泛型的public T Get<T>(string key)。
5.Remove(string key)
则是删除一个key对应的内容。
Key的长度最高是250个字符,Value最长1M(大约
524288个字)。
6.ExecuteXXX
与Store、Get、Remove配套的还有ExecuteXXX方法,唯一区别就是返回值信息更详细。
7.Key的选择(命名)
Memcached就相当于一个大键值对,不同系统放到Memcached中的数据都是不隔离的,因此设定Key的时候要选择好Key,这样就不容易冲突。
建议规则“系统名字_模块名字_业务Key”,比如“Shop_Admin_FilterWords”
8. Increment、Decrement
是用来对计数器进行增减的,不过用得少。用Redis更合适。
2.CAS(乐观锁)
用来解决并发问题:读出一个值,做一些判断或者处理,再写回,有可能有并发的问题。
Cas是Memcached 1.2.5之后引入的特性,类似于数据库的“乐观锁”,查询的时候查出一个cas值,在写入的时候带着这个cas值,如果发现cas值已经变了,则说明已经有别人改过了。
辅助类
namespace ConsoleApp1
{
public class MemCachedHelper<T>
{
private static string SERVER = "127.0.0.1:11211";
//过期时间:20分钟
private static int TimeSpanExpired = 20;
private static MemcachedClientConfiguration mcConfiguration = new MemcachedClientConfiguration();
static MemCachedHelper()
{
mcConfiguration.AddServer(SERVER);
}
/// <summary>
/// Set设置key,value
/// </summary>
/// <param name="key"></param>
/// <param name="value"></param>
/// <returns></returns>
public static bool SetKey(string key, object value)
{
using (MemcachedClient client = new MemcachedClient(mcConfiguration))
{
/*
* MemcachedClient.Store(StoreMode mode, string key, object value); 使用缓存键将项插入到缓存中, 以引用其位置。
* StoreMode mode 定义项在缓存中的存储方式。
*/
return client.Store(StoreMode.Set, key, value, TimeSpan.FromMinutes(TimeSpanExpired));
}
}
/// <summary>
/// 设置Cas
/// </summary>
/// <param name="key"></param>
/// <param name="value"></param>
/// <param name="cas"></param>
/// <returns></returns>
public static CasResult<bool> SetCas(string key, object value, ulong cas)
{
using (MemcachedClient client = new MemcachedClient(mcConfiguration))
{
/*
* MemcachedClient.Cas(StoreMode mode, string key, object value, TimeSpan validFor, ulong cas);
* StoreMode mode 定义项在缓存中的存储方式。
*/
return client.Cas(StoreMode.Set, key, value, TimeSpan.FromMinutes(TimeSpanExpired), cas);
}
}
/// <summary>
/// 获取值
/// </summary>
/// <param name="key"></param>
/// <returns></returns>
public static T GetValue(string key)
{
using (MemcachedClient client = new MemcachedClient(mcConfiguration))
{
return (T)client.Get(key);
}
}
/// <summary>
/// Cas获取值
/// </summary>
/// <param name="key"></param>
/// <returns></returns>
public static CasResult<T> GetCasValue(string key)
{
using (MemcachedClient client = new MemcachedClient(mcConfiguration))
{
return client.GetWithCas<T>(key);
}
}
/// <summary>
/// 删除Key
/// </summary>
/// <param name="key"></param>
/// <returns></returns>
public static Boolean Remove(string key)
{
using (MemcachedClient client = new MemcachedClient(mcConfiguration))
{
return client.Remove(key);
}
}
}
}
实例:
var res = MemCachedHelper<string>.GetCasValue("student");
Console.WriteLine("Result:{0},Cas:{1},StatusCode:{2}", res.Result, res.Cas, res.StatusCode);
Console.ReadKey();
CasResult<bool> casR = MemCachedHelper<string>.SetCas("student", "acc", res.Cas);
if (casR.Result)
{
Console.WriteLine("更新成功,cas值:{0}",casR.Cas);
}
else
{
Console.WriteLine("更新失败,已经有人先更新了,cas值:{0}",casR.Cas);
}
Console.ReadKey();

3.集群
memcached重启之后短时间内大量的请求会涌入数据库,给数据库造成压力,解决这个的方法就是使用集群,有多台Memcached服务器提供服务。
当memcached服务器压力大了之后也有必要搞memcached集群来分担压力。
3.1 “雪崩”问题
Memcached服务器的“雪崩”问题:如果所有缓存设置过期时间一样,那么每隔一段时间就会造成一次数据库访问的高峰.
解决的方法:
就是缓存时间设置不一样,比如加上一个随机数。
3.2 集群方法
Memcached的集群实现很简单,集群节点直接不进行通讯、同步,只要在多个服务器上启动多个Memcached服务器即可,客户端决定把数据写入不同的实例,不搞主从复制,每个数据库实例保存一部分内容。
然后mcConfig.AddServer("127.0.0.1:11211");添加多个服务器ip地址,然后客户端根据自己的算法决定把数据写入哪个Memcached实例,取数据库的时候再根据同样的定位算法去哪台服务器上去取。
3.3 节点定位算法
节点定位算法有很多种,最常用的有两种 Ketama、VBucket。建议用Ketama就可以了。节点定位算法会自动处理故障服务器。
mcConfig.NodeLocatorFactory = new KetamaNodeLocatorFactory()。
缓存要求都不高。
Consistent Hashing最大限度地抑制了hash键的重新分布。另外要取得比较好的负载均衡的效果,往往在服务器数量比较少的时候需要增加虚拟节点来保证服务器能均匀的分布在圆环上。因为使用一般的hash方法,服务器的映射地点的分布非常不均匀。使用虚拟节点的思想,为每个物理节点(服务器)在圆上分配100~200个点。这样就能抑制分布不均匀,最大限度地减小服务器增减时的缓存重新分布。用户数据映射在虚拟节点上,就表示用户数据真正存储位置是在该虚拟节点代表的实际物理服务器上。
3.3.1 Ketama(常用)
Ketama是根据Key算出一个hash值,根据hash值再算到服务器;
3.3.2 VBucket
VBucket也是根据key算出hash值,但是不是直接根据hash值算出服务地址,而是维护一个VBucket表,在表中指定不同的hash值由不同的服务器处理,还可以临时改变指向。
Memcached 快速入门的更多相关文章
- 分布式缓存系统 Memcached 快速入门
Memcached介绍 官网地址 Memcached 是一个高性能的分布式内存对象缓存系统,用于动态Web应用以减轻数据库负载.它通过在内存中缓存数据和对象来减少读取数据库的次数,从而提 ...
- Memcached快速入门
1.基本概念 基于高性能的key-value的内存数据库.单进程多线程,协议简单,使用文本行的协议,支持数据类型简单,不支持持久化,轻量级锁CAS机制,集群互不通信,缓存策略(LRU,FIFO,LFU ...
- [你必须知道的NOSQL系列]专题二:Redis快速入门
一.前言 在前一篇博文介绍了MongoDB基本操作,本来打算这篇博文继续介绍MongoDB的相关内容的,例如索引,主从备份等内容的,但是发现这些内容都可以通过官方文档都可以看到,并且都非常详细,所以这 ...
- Redis快速入门:安装、配置和操作
本文是有关Redis的系列技术文章之一.在之前的文章中介绍了<Redis快速入门:初识Redis>,对Redis有了一个初步的了解.今天继续为大家介绍Redis如何安装.配置和操作. 系列 ...
- 二:Redis快速入门及应用
Redis的使用难吗?不难,Redis用好容易吗?不容易.Redis的使用虽然不难,但与业务结合的应用场景特别多.特别紧,用好并不容易.我们希望通过一篇文章及Demo,即可轻松.快速入门并学会应用. ...
- kolla-ansible快速入门
kolla-ansible快速入门 kolla-ansible是一个结构相对简单的项目,它通过一个shell脚本,根据用户的参数,选择不同的playbook和不同的参数调用ansible-playbo ...
- Redis快速入门及应用
Redis的使用难吗?不难,Redis用好容易吗?不容易.Redis的使用虽然不难,但与业务结合的应用场景特别多.特别紧,用好并不容易.我们希望通过一篇文章及Demo,即可轻松.快速入门并学会应用.一 ...
- 中小型研发团队架构实践五:Redis快速入门及应用
Redis的使用难吗?不难,Redis用好容易吗?不容易.Redis的使用虽然不难,但与业务结合的应用场景特别多.特别紧,用好并不容易.我们希望通过一篇文章及Demo,即可轻松.快速入门并学会应用. ...
- 中小型研发团队架构实践:Redis快速入门及应用
Redis的使用难吗?不难,Redis用好容易吗?不容易.Redis的使用虽然不难,但与业务结合的应用场景特别多.特别紧,用好并不容易.我们希望通过一篇文章及Demo,即可轻松.快速入门并学会应用. ...
随机推荐
- OpenCV 入门
1.入门攻略[安装用] https://www.cnblogs.com/linshuhe/p/5764394.html 2.VS2017配置opencv教程(超详细!!!) https://blog. ...
- linux+php实现定时任务[链接]
1.crontab 详细用法 定时任务 https://www.cnblogs.com/aminxu/p/5993769.html 2.查看crontab日志 https://www.cnblogs. ...
- Shell-匹配FTP文件名
想弄个脚本,下载每日构建的版本,由于版本文件名中有构建时间(不是固定值),只能按日期确认文件名,例如:project_name_2019-01-04*.exe 搜索了下,可以用dir filename ...
- vc++高级班之窗口篇[4]---让程序只运行一个实例
大家都看过或者使用过类似只运行一个实例的程序,比如:QQ游戏.部分浏览器 等等! 让一个程序只运行一个实例的方法有多种,但是原理都类似,也就是在程序创建后,有窗口的程序在窗口创建前, 检查系统中是 ...
- python操作mysql数据库增删改查的dbutils实例
python操作mysql数据库增删改查的dbutils实例 # 数据库配置文件 # cat gconf.py #encoding=utf-8 import json # json里面的字典不能用单引 ...
- O(big oh) (big omega) (big theta)
big oh big omega big theta more
- Appium+Java(三)搭建环境之踩过的坑
一.原因 有最少两年多没写手机自动化测试了,正巧公司有需求搞TOC端自动化测试调研,先入为主,因为之前写过appium所以先用它埋点试水了 二.现象: 1.我早期的appium版本是v1.4.16 2 ...
- peizhiwenjian
自定义配置文件 如果你不想使用application.properties作为配置文件,怎么办?完全没问题 java -jar myproject.jar --spring.config.locati ...
- Modbus库开发笔记:Modbus ASCII Slave开发
与Modbus RTU在串行链路上分为Slave和Master一样,Modbus ASCII也分为Slave和Master,这一节我们就来开发Slave.对于Modbus ASCII从站来说,需要实现 ...
- Modbus库开发笔记之十:利用协议栈开发Mosbus RTU Slave应用
上一节我们使用协议占开发了一个Modbus TCP Server应用.接下来我们使用协议栈在开发一个基于串行链路的Mosbus RTU Slave应用. 根据前面对协议栈的封装,我们需要引用Modbu ...