热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

asp.net结合memcache进行分布式缓存的开发,结合mysql数据库

在介绍memcache之前,先来看看我服务器和本地的开发环境。服务器:windows2003,iis6,mysql+asp.net2.0运行的网站本地开发:win7

在介绍 memcache之前,先来看看我服务器和本地的开发环境。

服务器:windows 2003,iis 6, mysql + asp.net  2.0 运行的网站

本地开发:win7+mysql+asp.net2.0  .之所以不用mssql2005/2008是因为考虑到付费的问题。

一:memcache 简介

在通常的应用中我们都会将数据保存到数据库中,每次需要的时候都会从数据库去查询这些数据,如果应用程序的用户很多就会出现大量并发访问数据库的情况,这样就会增加应用程序的响应时间,使用Memcached就可以有效解决这个问题。memcached是高性能的分布式内存缓存服务器软件。

为了提高性能,Memcached中的数据都保存在Memcached内置的存储空间中。因为当Memcached重启会导致其中的数据全部丢失,所以一般的方案是将数据保存在数据库中,每次请求数据的时候先查看在Memcached有没有缓存,如果有就直接从缓存中取出数据;如果没有,就从数据库中取出数据返回给应用程序并将请求的数据缓存到Memcached中,这样一来下次请求相同的数据就可以直接从Memcached中读取而不用再去查数据库了;一旦对数据有更新,同时更新数据库和Memcached。


Memcached是一个命令行窗口程序,可以在命令行窗口中启动也可以封装在系统服务中启动。在启动Memcached时需要提供一些必须的参数,指定Memcached运行时监听的端口和最大使用的内存大小等。如果缓存的数据大小超过指定内存,那么Memcached就会按照LRU(Least Recently Used/最久未使用)算法自动“删除”不使用的缓存(标记为失效),新增的缓存数据就可以使用这些标记为失效的数据所占用的内存,这样就不用担心Memcached超出所指定内存的问题。此外,为了提高性能,在缓存数据过期后Memcached并不是从物理内存中删除缓存的数据,仅仅在取出改数据的时候检查它是否已经过了有效期。


目前有多种平台的Memcached版本,比如Linux、FreeBSD、Solaris (memcached 1.2.5以上版本)、Mac OS X及Windows平台,在Windows平台上还有32位和64位版本。


Memcached有一套协议,利用这套协议可以对Memcached进行数据存取和查看Memcached的状态,很多程序语言都依据这套协议来操作Memcached,比如PHP、Java、C、C++及C#等。


获取了对应平台的Memcached版本就可以运行Memcached了。在这里仅以Windows平台上的32位Memcached为例。

二:memcache for windows 服务器端的软件下载与安装

由于最近的项目是使用.NET作为开发平台,而且使用的是Windows 作服务器。所以,首先要找到Windows平台下的Memcached版本。

下面,我将下载地址贴出来。

http://download.csdn.net/detail/dinglang_2009/3733784 或者 点击此处直接下载

三:如何用(有部分是转载别人的)

下载好了Memcached之后,解压到任意目录下,例如:

1. 解压缩文件到c:/memcached      进入cmd控制台(该不会有人问我这个cmd要怎么进去吧?)
    2. 命令行输入 'c:/memcached/memcached.exe -d install'       --安装 Memcached
    3. 命令行输入 'c:/memcached/memcached.exe -d start' ,该命令启动 Memcached ,默认监听端口为 11211。

其实可以通过        memcached.exe -p 11211 -m 64    指定它的监听端口是11211(这是它的默认端口,可以指定为其它大于1024的端口,因为小于1024的端口已经有了默认指定),最大使用内存为64m,如果启用了Windows防火墙,切记要在防火墙上打开这个端口。

注:通过 memcached.exe -h 可以查看其帮助     这里不多做介绍了

在客户端还可以通过telnet来查看和操作Memcached,前提是服务器端和客户端都支持Telnet协议,在Windows7和Windows2008中默认都不支持,需要在控制面板中安装和启用。
首先打开控制面板,然后点击“打开或关闭Windows功能”,如下图所示:

image

点击“打开或关闭Windows功能”之后会看到当前系统启用的功能的状态,根据当前机器选择打开Telnet服务器端或者客户端功能,如下图所示:

image

经过上面的操作之后就可以在客服端远程查看Memcached的状态或者操作Memcached了。下面的命令就是连接到Memcached:

在dos窗口界面下   输入   telnet localhost 11211
连接之后会出现一个命令行窗口,在这个命令行窗口中输入"stats"就可以看到当前Memcached的状态,如下图所示:

image

输入quit 指令,并按下Enter 退出

通过这个数据我们就可以了解Memcached的状态了。
这些数据所代表的意义如下:
pid:32u,服务器进程ID。
uptime:32u, 服务器运行时间,单位秒。
time :32u, 服务器当前的UNIX时间。
version :string, 服务器的版本号。
curr_items :32u, 服务器当前存储的内容数量 Current number of items stored by the server
total_items :32u, 服务器启动以来存储过的内容总数。
bytes :64u, 服务器当前存储内容所占用的字节数。
curr_connections :32u, 连接数量。
total_connections :32u, 服务器运行以来接受的连接总数。
connection_structures:32u, 服务器分配的连接结构的数量。
cmd_get :32u, 取回请求总数。
cmd_set :32u, 存储请求总数。
get_hits :32u, 请求成功的总次数。
get_misses :32u, 请求失败的总次数。
bytes_read :64u, 服务器从网络读取到的总字节数。
bytes_written :64u, 服务器向网络发送的总字节数。
limit_maxbytes :32u, 服务器在存储时被允许使用的字节总数。

上面的描述中32u和64u表示32位和64位无符号整数,string表示是string类型数据。

四:memcache客户端的安装(.net版本)

启动并配置好Memcached的服务端之后呢?我们下面该准备基于.NET平台的客户端了:

据我总结,大概常见的有三四种吧。必要的类库或者源码,我都将提供给大家下载。

1).NET memcached client library

Memcached .NET客户端的类库,目前大概只支持.NET1.0和.NET2.0,笔者没仔细研究这个,估计这个已经过时啦。

2)enyim.com Memcached Client

源码地址:点击下载源码        (开源项目,可提供研究学习)

Enyim也是应用比较广泛的Memcached .net客户端,和之前的Memchachedonet 客户端相比,分布式算法应该做了相应优化

 

3)Memcached Providers

下载地址:点击下载

Memcached Providers的官网上有一份PDF的文档,是教你怎么配置的。英语不好的童鞋,可以直接参考我的配置(稍后会讲解)。

4) BeIT Memcached

这个笔者没用过,不做讲解了

 

下载enyim.com Memcached Client 和 Memcached Providers,解压后会发现,enyim.com Memcached Client中,还包含了著名的Log4net日志框架。

而Memcached Providers中其实包含了Enyim.Caching.dll,也包含了Log4netDLL

Memcached Providers更强大,MemcachedProviders是对Enyim.Caching的再次封装,并加入了客户端计数器功能以及Session数据库管理功能

当然,使用和配置起来也同样简单,方便,只是对于一些负责的操作和处理方面,功能更强大一些。

如果只是简单的应用,推荐直接使用enyim.com Memcached Client。除了添加必要的Enyim.Caching.dll引用,还需要修改应用程序的配置文件。

下面的代码贴出这两种方式的配置文件和测试代码:(放心,有详细的注释)

image

测试代码(实现最简单的功能)

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using Enyim.Caching;
using MemcachedProviders.Cache;
using System.Threading;

namespace MemcachedProject
{
    public partial class _Default : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {
            testMemcachedProviders();
        }

        ///   
        /// 测试Enyim.Caching(注意:Enyim.Caching只具有MemcachedProviders的一部分功能,后者更强大。还可以集成Log4Net日志框架)  
        ///   
        public void testEnyimCaching()
        {
            MemcachedClient client = new MemcachedClient("enyim.com/memcached");
            //存值  --不带过期时间的存储,Memcached将根据LRU来决定过期策略
            bool result = client.Store(Enyim.Caching.Memcached.StoreMode.Add, "name", "dinglang");
            //带过期时间的缓存  
            //bool success = client.Store(StoreMode.Add, person.UserName, person, DateTime.Now.AddMinutes(10)); 
            if (result)
            {
                Response.Write("成功存入缓存");

                //取值  
                object name = client.Get("name");
                if (name != null)
                {
                    Response.Write("取出的值为:" + name);
                }
                else
                {
                    Response.Write("取值失败");
                }
            }
            else
            {
                Response.Write("存入缓存失败");
            }
        }
        /// 
        /// 使用MemcachedProviders客户端
        /// 
        public void testMemcachedProviders()
        {
            string key = "myName";
            string value = "Dylan";
            bool result = false;
            string val = string.Empty;
            #region 存/取最简单的数据类型
            //如果缓存中没有,就尝试着去存入缓存
            if (DistCache.Get(key) == null)
            {
                //DistCache.DefaultExpireTime = 1200;//缓存时间
                result = DistCache.Add(key, value);           //存数据  
                if (result)
                {
                    //如果存入成功,就试着去取
                    Thread.Sleep(500);
                    string ret = (string)DistCache.Get(key);            //读数据  
                    //Assert.AreEqual(value, ret);                     //验证  
                    if (ret != null)
                    {
                        Response.Write(ret);
                        Response.Write("
"
); } else { //取出来的值为null,直接移除该缓存对象 DistCache.Remove(key);//移除 // DistCache.RemoveAll();//移除所有 } } } else { //缓存中有,直接拿数据 string ret = (string)DistCache.Get(key); if (ret != null) { Response.Write(ret); Response.Write("
"
); } else { DistCache.Remove(key); } } #endregion #region 存/取一个Person对象 Person person = new Person() { Id = 007, Name = "Dylan" };//new 一个Person对象的实例 //如果缓存中没有,则尝试着放入缓存 if (DistCache.Get("myObj") == null) { result = DistCache.Add("myObj", person); if (result) { Thread.Sleep(500); val = DistCache.Get("myObj").ToString(); if (val != null) { Response.Write(val); Response.Write("
"
); } else { DistCache.Remove("myObj"); } } } else { //缓存中已经有该对象,就直接从缓存取 Person p = DistCache.Get("myObj"); val = person.ToString(); //也可以直接这样取 // val = DistCache.Get("myObj").ToString(); if (val != null) { Response.Write(val); Response.Write("
"
); } else { DistCache.Remove("myObj"); } } #endregion } } }
Person类的定义代码:
这里需要说明的是如果我们需要向Memcached中添加自定义数据类型时,我们需要将该数据类型添加上[Serializable]标记。

[Serializable] public class Person { private int id; public int Id { get { return id; } set { id = value; } } private string name; public string Name { get { return name; } set { name = value; } } /// /// 重写Tostring(),方便输出验证 /// /// public override string ToString() { return "Person:" + "{name:" + Name + ",id:" + Id + "}"; } }
web.config 配置信息:
xml version="1.0"?>



<configuration>

    

    

    

    
    <configSections>
        <section name="cacheProvider" type="MemcachedProviders.Cache.CacheProviderSection, MemcachedProviders"
              allowDefinition="MachineToApplication" restartOnExternalChanges="true"/>
        <sectionGroup name="enyim.com">
            <section name="memcached" type="Enyim.Caching.Configuration.MemcachedClientSection, Enyim.Caching" />
        sectionGroup>
        <section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler,log4net"/>
    configSections>
    <cacheProvider defaultProvider="MemcachedCacheProvider">
        <providers>
            <add name="MemcachedCacheProvider"
           type="MemcachedProviders.Cache.MemcachedCacheProvider, MemcachedProviders"  keySuffix="_MySuffix_" defaultExpireTime="2000"/>
        providers>
    cacheProvider>
    <enyim.com>
        <memcached>
            <servers>
                
                <add address="127.0.0.1" port="11121" />
            servers>
            <socketPool minPoolSize="10" maxPoolSize="100" connectionTimeout="00:00:10" deadTimeout="00:02:00" />
        memcached>
    enyim.com>

    <log4net>
        <appender name="ConsoleAppender" type="log4net.Appender.ConsoleAppender">
            <layout type="log4net.Layout.PatternLayout">
                <conversionPattern value="%date [%thread] %-5level %logger [%property{NDC}]- %message%newline" />
            layout>
        appender>
        <root>
            <priority value="WARN"/>
            <appender-ref ref="ConsoleAppender">
                <filter type="log4net.Filter.LevelRangeFilter">
                    <levelMin value="WARN"/>
                    <levelMax value="FATAL"/>
                filter>
            appender-ref>
        root>
    log4net>

    

    <connectionStrings>
        <add name="ApplicationServices"
             connectionString="data source=.\SQLEXPRESS;Integrated Security=SSPI;AttachDBFilename=|DataDirectory|\aspnetdb.mdf;User Instance=true"
             providerName="System.Data.SqlClient" />
    connectionStrings>


    <system.web>
        <compilation debug="true" targetFramework="4.0" />

        <authentication mode="Forms">
            <forms loginUrl="~/Account/Login.aspx" timeout="2880" />
        authentication>

        <membership>
            <providers>
                <clear/>
                <add name="AspNetSqlMembershipProvider" type="System.Web.Security.SqlMembershipProvider" connectionStringName="ApplicationServices"
                     enablePasswordRetrieval="false" enablePasswordReset="true" requiresQuestionAndAnswer="false" requiresUniqueEmail="false"
                     maxInvalidPasswordAttempts="5" minRequiredPasswordLength="6" minRequiredNonalphanumericCharacters="0" passwordAttemptWindow="10"
                     applicationName="/" />
            providers>
        membership>

        <profile>
            <providers>
                <clear/>
                <add name="AspNetSqlProfileProvider" type="System.Web.Profile.SqlProfileProvider" connectionStringName="ApplicationServices" applicationName="/"/>
            providers>
        profile>

        <roleManager enabled="false">
            <providers>
                <clear/>
                <add name="AspNetSqlRoleProvider" type="System.Web.Security.SqlRoleProvider" connectionStringName="ApplicationServices" applicationName="/" />
                <add name="AspNetWindowsTokenRoleProvider" type="System.Web.Security.WindowsTokenRoleProvider" applicationName="/" />
            providers>
        roleManager>

    system.web>




    <system.webServer>
        <modules runAllManagedModulesForAllRequests="true"/>
    system.webServer>
configuration>

关于Memcached的基础部分,就先讲到这里。后续,我将会整理一些关于Memcached的高级技术,包括:复杂的存储(缓存/更新)控制模型,缓存策略,在分布式、集群、负载均衡的环境下的使用和管理技巧,性能监控,日志记录等.敬请期待。

本文出自blog.csdn.net/dinglang_2009,转载请注明出处。未经本人允许,任何人不得借此牟利。

Memcached系列文章汇总:

memcached单点故障与负载均衡

memcached性能监控

在Windows .NET平台上使用memcached

五:其他的一些问题的解答

1:Memcached 集群架构方面的问题

  • memcached是怎么工作的?
  • memcached最大的优势是什么?
  • memcached和MySQL的query cache相比,有什么优缺点?
  • memcached和服务器的local cache(比如PHP的APC、mmap文件等)相比,有什么优缺点?
  • memcached的cache机制是怎样的?
  • memcached如何实现冗余机制?
  • memcached如何处理容错的?
  • 如何将memcached中item批量导入导出?
  • 但是我确实需要把memcached中的item都dump出来,确实需要把数据load到memcached中,怎么办?
  • memcached是如何做身份验证的?
  • 如何使用memcached的多线程是什么?如何使用它们?
  • memcached能接受的key的最大长度是多少?(250bytes)
  • memcached对item的过期时间有什么限制?(为什么有30天的限制?)
  • memcached最大能存储多大的单个item?(1M byte)
  • 为什么单个item的大小被限制在1M byte之内?
  • 为了让memcached更有效地使用服务器的内存,可以在各个服务器上配置大小不等的缓存空间吗?
  • 什么是binary协议?它值得关注吗?
  • memcached是如何分配内存的?为什么不用malloc/free!?究竟为什么使用slab呢?
  • memcached能保证数据存储的原子性吗?

推荐阅读
  • 本文介绍了操作系统的定义和功能,包括操作系统的本质、用户界面以及系统调用的分类。同时还介绍了进程和线程的区别,包括进程和线程的定义和作用。 ... [详细]
  • yii框架目录结构详细分析说明
    php教程|php手册yii,目录结构php教程-php手册yii框架目录结构详细分析说明猫狗大战源码,华为云电脑ubuntu,梦见放走很多爬虫,parttmpphp,seo页面描 ... [详细]
  • Android中高级面试必知必会,积累总结
    本文介绍了Android中高级面试的必知必会内容,并总结了相关经验。文章指出,如今的Android市场对开发人员的要求更高,需要更专业的人才。同时,文章还给出了针对Android岗位的职责和要求,并提供了简历突出的建议。 ... [详细]
  • 本文介绍了Java工具类库Hutool,该工具包封装了对文件、流、加密解密、转码、正则、线程、XML等JDK方法的封装,并提供了各种Util工具类。同时,还介绍了Hutool的组件,包括动态代理、布隆过滤、缓存、定时任务等功能。该工具包可以简化Java代码,提高开发效率。 ... [详细]
  • 本文介绍了在Oracle数据库中创建序列时如何选择cache或nocache参数。cache参数可以提高序列的存取速度,但可能会导致序列丢失;nocache参数可以避免序列丢失,但在高并发访问时可能导致性能问题。文章详细解释了两者的区别和使用场景。 ... [详细]
  • 一句话解决高并发的核心原则
    本文介绍了解决高并发的核心原则,即将用户访问请求尽量往前推,避免访问CDN、静态服务器、动态服务器、数据库和存储,从而实现高性能、高并发、高可扩展的网站架构。同时提到了Google的成功案例,以及适用于千万级别PV站和亿级PV网站的架构层次。 ... [详细]
  • LVS实现负载均衡的原理LVS负载均衡负载均衡集群是LoadBalance集群。是一种将网络上的访问流量分布于各个节点,以降低服务器压力,更好的向客户端 ... [详细]
  • 深入理解Java虚拟机的并发编程与性能优化
    本文主要介绍了Java内存模型与线程的相关概念,探讨了并发编程在服务端应用中的重要性。同时,介绍了Java语言和虚拟机提供的工具,帮助开发人员处理并发方面的问题,提高程序的并发能力和性能优化。文章指出,充分利用计算机处理器的能力和协调线程之间的并发操作是提高服务端程序性能的关键。 ... [详细]
  • 2021最新总结网易/腾讯/CVTE/字节面经分享(附答案解析)
    本文分享作者在2021年面试网易、腾讯、CVTE和字节等大型互联网企业的经历和问题,包括稳定性设计、数据库优化、分布式锁的设计等内容。同时提供了大厂最新面试真题笔记,并附带答案解析。 ... [详细]
  • 一,织梦后台后台设置进入系统后台,在[系统基本参数]下面的性能选项卡当中,关于memcache进行如下配置:cfg_memcache_enable:是否启用memcache缓存,如果为否(N) ... [详细]
  • php yac缓存如何清理,yac和memcache性能对比测试
    yac是Laruence开发的一个php进程共享内存的开源项目。详情可以查看。http:www.laruence.com201303182846.htmlmemcache就不用多说 ... [详细]
  • http:simple-is-better.comnews1047Firefly是免费、开源、稳定、快速扩展、能“热更新”的分布式游戏服务器端框架,采用Python编 ... [详细]
  • nosql数据库的基本要求Nosql全称是NotOnlySQL,是一种不同于关系型数据库的数据库管理系统设计方式。对NoSQL最普遍的解释是“非关系型的”,强调Key-ValueS ... [详细]
  • 本文介绍了Redis的基础数据结构string的应用场景,并以面试的形式进行问答讲解,帮助读者更好地理解和应用Redis。同时,描述了一位面试者的心理状态和面试官的行为。 ... [详细]
  • 本文介绍了OkHttp3的基本使用和特性,包括支持HTTP/2、连接池、GZIP压缩、缓存等功能。同时还提到了OkHttp3的适用平台和源码阅读计划。文章还介绍了OkHttp3的请求/响应API的设计和使用方式,包括阻塞式的同步请求和带回调的异步请求。 ... [详细]
author-avatar
蔡晓楠
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有