一、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使用的更多相关文章

  1. 支持 .NET Core 的 Memcached 客户端 EnyimMemcachedCore

    1. 介绍 EnyimMemcachedCore 是一个支持 .NET Core 的 Memcached 客户端,是从 EnyimMemcached 迁移至 .NET Core的,源代码托管在 Git ...

  2. Key/Value之王Memcached初探:二、Memcached在.Net中的基本操作

    一.Memcached ClientLib For .Net 首先,不得不说,许多语言都实现了连接Memcached的客户端,其中以Perl.PHP为主. 仅仅memcached网站上列出的语言就有: ...

  3. ASP.Net MVC4+Memcached+CodeFirst实现分布式缓存

    ASP.Net MVC4+Memcached+CodeFirst实现分布式缓存 part 1:给我点时间,允许我感慨一下2016年 正好有时间,总结一下最近使用的一些技术,也算是为2016年画上一个完 ...

  4. 缓存、队列(Memcached、redis、RabbitMQ)

    本章内容: Memcached 简介.安装.使用 Python 操作 Memcached 天生支持集群 redis 简介.安装.使用.实例 Python 操作 Redis String.Hash.Li ...

  5. 企业做数据缓存是使用Memcached还是选Redis?

    企业是使用Memcached还是选Redis? 在构建一款现代且由数据库驱动的Web应用程序并希望使其拥有更为出色的性能表现时,这个问题总会时不时出现.并给每一位开发人员带来困扰.在考虑对应用程序的性 ...

  6. NoSql1 在Linux(CentOS)上安装memcached及使用

    前言:       今天是初五,生活基本要从过年的节奏中回归到正常的生活了,所以想想也该想想与工作有关的事情了.我之前在工作中会经常使用memcached和redis,但是自己一直没有时间系统的好好看 ...

  7. Memcached简介

    在Web服务开发中,服务端缓存是服务实现中所常常采用的一种提高服务性能的方法.其通过记录某部分计算结果来尝试避免再次执行得到该结果所需要的复杂计算,从而提高了服务的运行效率. 除了能够提高服务的运行效 ...

  8. Linux 服务器 安装 memcached

    linux centos 一.memcached的安装 1.下载 memcached-1.4.33.tar.gz.libevent-2.0.22-stable.tar.gz 安装 memcached ...

  9. Memcached和Redis比较

    一.存储 Memcached基本只支持简单的key-value存储方式.Redis除key-value之外,还支持list,set,sorted set,hash等数据结构:Redis支持数据的备份, ...

  10. 搭建LNAMP环境(七)- PHP7源码安装Memcached和Memcache拓展

    上一篇:搭建LNAMP环境(六)- PHP7源码安装MongoDB和MongoDB拓展 一.安装Memcached 1.yum安装libevent事件触发管理器 yum -y install libe ...

随机推荐

  1. winfrom之动态控件生成以及保存动态空间的数据

    前些天要完成一个winform程序,里面涉及到动态控件的添加以及保存动态空间中数据的保存,效果如下 初始化时: 点击添加阶梯价后:(点击一下,动态添加一行) 那么接下来,我们就具体的讲下代码实现: 首 ...

  2. js 实现栈

    function Stack() { this.dataStore = []; this.top = 0; this.push=push; this.pop=pop; this.peek=peek; ...

  3. 【PHP】文件上传限制

    上传文件,只判断后缀,貌似还不是很严谨; /** * 判断文件是否合法 * @param $files * @param $arrCode * @return number|boolean */ fu ...

  4. setTimeOut(),和setInterVal()调用函数加不加括号!!!

    直接在ready中调用其他方法,会提示缺少对象的错误,解决方法如下: 方法1. 应用jQuery的扩展可以解决这个问题. $(document).ready(function(){ $.extend( ...

  5. c#反射机制学习和利用反射获取类型信息

    反射(Reflection)是.NET中的重要机制,通过放射,可以在运行时获得.NET中每一个类型(包括类.结构.委托.接口和枚举等)的成员,包括方法.属性.事件,以及构造函数等.还可以获得每个成员的 ...

  6. web开发中,前端javascript代码的组织结构

    网页包含三个层次: 结构(HTML) 表现(CSS) 行为(javascript) web标准中,三者要分离,网页源代码由三部分组成:.html文件..css文件和.js文件.就是说html文件中不应 ...

  7. 安装boost1.57.0__注意之前mgiza似乎因为boost没有安装也没有完全编译成功

    首先下载(废话) 解压, ./bootstrap.sh 之后在运行b2 ./b2 -j8 --prefix=$PWD --libdir=$PWD/lib64 --layout=system link= ...

  8. 《Prism 5.0源码走读》ModuleCatalog

    概念 ModuleCatalog 是Prism中主要概念之一,主要用来保存应用程序可用的modules(模块),每个module都是用ModuleInfo来定义(包含module的名称.类型和位置). ...

  9. EMVTag系列1《数据分组》

    数据分组的设计在个人化过程中承担着重要的作用.数据分组标识符(DGI)是两字节十六进制数.数据分组标识的第一个字节等于'01'到'1E',表明数据存储的SFI.第二个字节表明SFI记录的记录编号.其他 ...

  10. hdu 3549 Flow Problem

    题目连接 http://acm.hdu.edu.cn/showproblem.php?pid=3549 Flow Problem Description Network flow is a well- ...