Memcached使用
一、Memcached简介
Memcached 是一个高性能的分布式内存对象缓存系统,用于动态Web应用以减轻数据库负载。它通过在内存中缓存数据和对象来减少读取数据库的次数,从而提高动态、数据库驱动网站的速度。Memcached基于一个存储键/值对的hashmap。其守护进程(daemon )是用C写的,但是客户端可以用任何语言来编写,并通过memcached协议与守护进程通信。
目前有多种平台的Memcached版本,比如Linux、FreeBSD、Solaris 、Mac OS X及Windows平台。
可在官网下载到最新版本: http://memcached.org/ (LINUX) 。
这里,官网上好像没有找到Memcached for windows
我们安装Windows版本来演示。
32bit:下载 memcached-win32-1.4.4-14.zip
64bit:如果需要win64版,下载 memcached-win64-1.4.4-14.zip
二、安装和启动
首先,我解压文件路径
D:\Memcached\Memcached32

安装命令
以管理员身份运行 cmd.exe
进入到解压文件
D:\>cd Memcached\Memcached32
安装
D:\Memcached\Memcached32>memcached.exe -d install
启动
D:\Memcached\Memcached32>memcached.exe -d start

OK,命令咱们已经执行完了.怎么才知道Memcached服务已经安装成功并启动了呢?
cmd 命令 services.msc

有时候,为了方便起见,我们也不能每次安装,停止和启动服务的时候都打开cmd命令框吧
常见的办法是做成批处理命令,如下:

install.bat
memcached.exe -d install
start.bat
memcached.exe -d start
stop.bat
memcached.exe -d stop
unInstall.bat
memcached.exe -d uninstall
三、.net 项目中使用
笔者查阅了相关资料,发现有很多支持Memcached的客户端,这里由于笔者的个人喜好,
选择了EnyimMemcached.2.13
可以通过Nuget安装
PM> Install-Package EnyimMemcached

笔者特意做了一个Demo来体验一下,EnyimMemcached使用
首先,我们要连接到这个分布式数据库服务,类似以前的关系型数据库,这里也是需要配置连接的,配置如下

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<configSections>
<sectionGroup name="enyim.com">
<section name="memcached" type="Enyim.Caching.Configuration.MemcachedClientSection,Enyim.Caching" />
</sectionGroup>
<section name="memcached" type="Enyim.Caching.Configuration.MemcachedClientSection, Enyim.Caching"/>
</configSections>
<enyim.com>
<memcached>
<servers>
<!-- put your own server(s) here-->
<add address="127.0.0.1" port="11211" />
</servers>
<socketPool minPoolSize="10" maxPoolSize="100" connectionTimeout="00:00:10" deadTimeout="00:02:00" />
</memcached>
</enyim.com>
<memcached keyTransformer="Enyim.Caching.TigerHashTransformer,Enyim.Caching">
<servers>
<add address="127.0.0.1" port="11211" />
</servers>
<socketPool minPoolSize="2" maxPoolSize="100" connectionTimeout="00:00:10" deadTimeout="00:02:00" />
</memcached>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
</startup>
</configuration>

为了方便使用,可以再封装一下,便于调用,

using Enyim.Caching;
using Enyim.Caching.Configuration;
using Enyim.Caching.Memcached;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading.Tasks;
namespace MemcachdDemo.Helper
{
public sealed class MemCachedHelper
{
private static MemcachedClient MemClient;
static readonly object padlock = new object();
//线程安全的单例模式
public static MemcachedClient getInstance()
{
if (MemClient == null)
{
lock (padlock)
{
if (MemClient == null)
{
MemClientInit();
}
}
}
return MemClient;
}
static void MemClientInit()
{
try
{
MemClient = new MemcachedClient();
/*MemcachedClientConfiguration config = new MemcachedClientConfiguration();
config.Servers.Add(new System.Net.IPEndPoint(IPAddress.Parse("127.0.0.1"), 11211));
config.Protocol = MemcachedProtocol.Binary;
//config.Authentication.Type = typeof(PlainTextAuthenticator);
//config.Authentication.Parameters["userName"] = "memcache";
//config.Authentication.Parameters["password"] = "password";
MemClient = new MemcachedClient(config);*/
/*MemcachedClientConfiguration config = new MemcachedClientConfiguration();
//config.Servers.Add(new IPEndPoint("127.0.0.1", 11211));
config.Servers.Add(new System.Net.IPEndPoint(IPAddress.Parse("127.0.0.1"), 11211));
config.Protocol = MemcachedProtocol.Binary;
config.Authentication.Type = typeof(PlainTextAuthenticator);
config.Authentication.Parameters["userName"] = "username";
config.Authentication.Parameters["password"] = "password";
config.Authentication.Parameters["zone"] = "";
MemClient = new MemcachedClient(config);*/
}
catch (Exception ex)
{
throw ex;
}
}
#region getAllKeys
public static List<string> GetAllKeys(string ipString, int port)
{
List<string> allKeys = new List<string>();
//var ipString = "127.0.0.1";
//var port = 11211;
var socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
socket.Connect(new IPEndPoint(IPAddress.Parse(ipString), port));
var slabIdIter = QuerySlabId(socket);
var keyIter = QueryKeys(socket, slabIdIter);
socket.Close();
foreach (String key in keyIter)
{
if (!allKeys.Contains(key))
allKeys.Add(key);
}
return allKeys;
}
/// <summary>
/// 执行返回字符串标量
/// </summary>
/// <param name="socket">套接字</param>
/// <param name="command">命令</param>
/// <returns>执行结果</returns>
static String ExecuteScalarAsString(Socket socket, String command)
{
var sendNumOfBytes = socket.Send(Encoding.UTF8.GetBytes(command));
var bufferSize = 0x1000;
var buffer = new Byte[bufferSize];
var readNumOfBytes = 0;
var sb = new StringBuilder();
while (true)
{
readNumOfBytes = socket.Receive(buffer);
sb.Append(Encoding.UTF8.GetString(buffer));
if (readNumOfBytes < bufferSize)
break;
}
return sb.ToString();
}
/// <summary>
/// 查询slabId
/// </summary>
/// <param name="socket">套接字</param>
/// <returns>slabId遍历器</returns>
static IEnumerable<String> QuerySlabId(Socket socket)
{
var command = "stats items STAT items:0:number 0 \r\n";
var contentAsString = ExecuteScalarAsString(socket, command);
return ParseStatsItems(contentAsString);
}
/// <summary>
/// 解析STAT items返回slabId
/// </summary>
/// <param name="contentAsString">解析内容</param>
/// <returns>slabId遍历器</returns>
static IEnumerable<String> ParseStatsItems(String contentAsString)
{
var slabIds = new List<String>();
var separator = "\r\n";
var separator2 = ':';
var items = contentAsString.Split(separator, StringSplitOptions.RemoveEmptyEntries);
for (Int32 i = 0; i < items.Length; i += 4)
{
var itemParts = items[i].Split(separator2, StringSplitOptions.RemoveEmptyEntries);
if (itemParts.Length < 3)
continue;
slabIds.Add(itemParts[1]);
}
return slabIds;
}
/// <summary>
/// 查询键
/// </summary>
/// <param name="socket">套接字</param>
/// <param name="slabIdIter">被查询slabId</param>
/// <returns>键遍历器</returns>
static IEnumerable<String> QueryKeys(Socket socket, IEnumerable<String> slabIdIter)
{
var keys = new List<String>();
var cmdFmt = "stats cachedump {0} 200000 ITEM views.decorators.cache.cache_header..cc7d9 [6 b; 1256056128 s] \r\n";
var contentAsString = String.Empty;
foreach (String slabId in slabIdIter)
{
contentAsString = ExecuteScalarAsString(socket, String.Format(cmdFmt, slabId));
keys.AddRange(ParseKeys(contentAsString));
}
return keys;
}
/// <summary>
/// 解析stats cachedump返回键
/// </summary>
/// <param name="contentAsString">解析内容</param>
/// <returns>键遍历器</returns>
static IEnumerable<String> ParseKeys(String contentAsString)
{
var keys = new List<String>();
var separator = "\r\n";
var separator2 = ' ';
var prefix = "ITEM";
var items = contentAsString.Split(separator, StringSplitOptions.RemoveEmptyEntries);
foreach (var item in items)
{
var itemParts = item.Split(separator2, StringSplitOptions.RemoveEmptyEntries);
if ((itemParts.Length < 3) || !String.Equals(itemParts.FirstOrDefault(), prefix, StringComparison.OrdinalIgnoreCase))
continue;
keys.Add(itemParts[1]);
}
return keys;
}
}
/// <summary>
/// String扩展函数
/// </summary>
static class StringExtension
{
/// <summary>
/// 切割
/// </summary>
/// <param name="str">字符串</param>
/// <param name="separator">分隔符</param>
/// <param name="options">选项</param>
/// <returns>切割结果</returns>
public static String[] Split(this String str, Char separator, StringSplitOptions options)
{
return str.Split(new Char[] { separator }, options);
}
/// <summary>
/// 切割
/// </summary>
/// <param name="str">字符串</param>
/// <param name="separator">分隔符</param>
/// <param name="options">选项</param>
/// <returns>切割结果</returns>
public static String[] Split(this String str, String separator, StringSplitOptions options)
{
return str.Split(new String[] { separator }, options);
}
#endregion
}
}

因为EnyimMemcached帮我们封装的很好,剩下的就是调用了

private void button3_Click(object sender, EventArgs e)
{
try
{
if (String.IsNullOrEmpty(this.txtKey.Text))
{
MessageBox.Show("key不能为空!");
return;
}
else
{
var key = this.txtKey.Text.Trim();
var value = this.txtValue.Text.Trim();
var bRet = client.Store(StoreMode.Set, key.Trim(), txtValue.Text.Trim());
}
}
catch (Exception ex)
{
throw ex;
}
}

截图如下

由于是key-value存储,查询方法:
var value = mc.Get("name");

对于Memcached的安装,启动和基本使用,有了简单的介绍,希望对你有用, 有用的话,请支持一下哈!
Memcached使用的更多相关文章
- 支持 .NET Core 的 Memcached 客户端 EnyimMemcachedCore
1. 介绍 EnyimMemcachedCore 是一个支持 .NET Core 的 Memcached 客户端,是从 EnyimMemcached 迁移至 .NET Core的,源代码托管在 Git ...
- Key/Value之王Memcached初探:二、Memcached在.Net中的基本操作
一.Memcached ClientLib For .Net 首先,不得不说,许多语言都实现了连接Memcached的客户端,其中以Perl.PHP为主. 仅仅memcached网站上列出的语言就有: ...
- ASP.Net MVC4+Memcached+CodeFirst实现分布式缓存
ASP.Net MVC4+Memcached+CodeFirst实现分布式缓存 part 1:给我点时间,允许我感慨一下2016年 正好有时间,总结一下最近使用的一些技术,也算是为2016年画上一个完 ...
- 缓存、队列(Memcached、redis、RabbitMQ)
本章内容: Memcached 简介.安装.使用 Python 操作 Memcached 天生支持集群 redis 简介.安装.使用.实例 Python 操作 Redis String.Hash.Li ...
- 企业做数据缓存是使用Memcached还是选Redis?
企业是使用Memcached还是选Redis? 在构建一款现代且由数据库驱动的Web应用程序并希望使其拥有更为出色的性能表现时,这个问题总会时不时出现.并给每一位开发人员带来困扰.在考虑对应用程序的性 ...
- NoSql1 在Linux(CentOS)上安装memcached及使用
前言: 今天是初五,生活基本要从过年的节奏中回归到正常的生活了,所以想想也该想想与工作有关的事情了.我之前在工作中会经常使用memcached和redis,但是自己一直没有时间系统的好好看 ...
- Memcached简介
在Web服务开发中,服务端缓存是服务实现中所常常采用的一种提高服务性能的方法.其通过记录某部分计算结果来尝试避免再次执行得到该结果所需要的复杂计算,从而提高了服务的运行效率. 除了能够提高服务的运行效 ...
- Linux 服务器 安装 memcached
linux centos 一.memcached的安装 1.下载 memcached-1.4.33.tar.gz.libevent-2.0.22-stable.tar.gz 安装 memcached ...
- Memcached和Redis比较
一.存储 Memcached基本只支持简单的key-value存储方式.Redis除key-value之外,还支持list,set,sorted set,hash等数据结构:Redis支持数据的备份, ...
- 搭建LNAMP环境(七)- PHP7源码安装Memcached和Memcache拓展
上一篇:搭建LNAMP环境(六)- PHP7源码安装MongoDB和MongoDB拓展 一.安装Memcached 1.yum安装libevent事件触发管理器 yum -y install libe ...
随机推荐
- android学习视频分享
最近整理了大量的安卓开发学习资料,有书籍有视频有代码,老罗的第一季有点老了, 这里就给大家分享下老罗的第二季的视频教程吧,还有源码,初级到高级程序猿都有用. 下载地址:http://51pansou. ...
- 旋转转盘选择Menu--第三方开源--CircleMenu
CircleMenu在github上的项目主页是:https://github.com/zhangphil/Android-CircleMenu CircleMenu用法简单,JAVA代码: pack ...
- QQl聊天消息
Activity: package com.zzw.qqchat; import java.util.ArrayList; import java.util.HashMap; import andro ...
- 用VBA计算WPS 表格ET EXCEL中的行数和列数的多重方法
用VBA计算WPS 表格ET EXCEL中的行数和列数 每种方法中上面的是Excel的行数,下面的是Excel的列数. 方法1: ActiveSheet.UsedRange.Rows.Count Ac ...
- js验证表单大全
js验证表单大全 1. 长度限制 <script> function test() { if(document.a.b.value.length>50) { alert(" ...
- DevExpress控件开发常用要点(项目总结版)
使用DevExpress控件来做项目开发已经有很长一段时间了,在摸索开发到客户苛刻要求的过程中,其中碰到过很多问题需要解决的,随着一个个问题的解决,也留下很多对DevExpress控件的使用经验及教训 ...
- Python初学者笔记:打印出斐波那契数列的前10项
问题:斐波那契数列(意大利语: Successione di Fibonacci),又称黄金分割数列.费波那西数列.费波拿契数.费氏数列,指的是这样一个数列:0.1.1.2.3.5.8.13.21.- ...
- openerp 常见问题 OpenERP为什么选择了时区后时间还是不对?(转载)
OpenERP为什么选择了时区后时间还是不对? 原文地址:http://cn.openerp.cn/%E4%B8%BA%E4%BB%80%E4%B9%88%E9%80%89%E6%8B%A9%E4%B ...
- python分片
刚刚学习,很新 >>> numbers = [1,2,3,4,5,6,7,8,9,10] >>> numbers[0:10:2] [1,3,5,7,9] >& ...
- 数组(Array),二维数组,三维数组
数组(Array):相同类型数据的集合就叫做数组. (一)定义数组的方法: A) type[] 变量名 = new type[数组中元素的个数] 例如: int[] a = new int[10] ; ...