Windows Azure Caching - 公有云缓存分析及应用

 在前面PaaS实践3: https://blogs.msdn.com/b/jianwu/archive/2014/08/15/azure-paas-3-azure-caching.aspx 中,使用了Azure提供的缓存服务(Caching)优化云服务的代码逻辑,加快云服务的处理能力。

本文将对现有Windows Azure中的各式缓存服务进行分析和实际应用。

1.认识公有云缓存

Windows Azure Cache是基于内存存储的分布式、易扩展缓存技术,开发者可以使用Windows Azure Cache缓存应用程序依赖的高频率读(写)数据,提高应用程序的响应速度。同时,由于Windows Azure Cache可以提供完全独立于托管服务环境或者本地应用程序的缓存服务,其降低了托管服务规模扩展和缓存部分调整的耦合度,即托管服务的扩容(缩容)操作对其依赖的Windows Azure Cache完全没有影响。对于云端运行的网站项目,使用Windows Azure Cache还可以直接存储网站项目所需要保持的Session、Membership等状态信息。

Windows Azure Cache主要包括两种形式的缓存。

(1)托管式缓存服务(Managed Cache Service)

Managed Cache Service是一种独立于应用程序以外的缓存服务,开发者可以在Managed Cache Service中给自己的应用程序创建一个专用的缓存空间,该缓存空间提供公开的连接地址,开发者可以在托管服务、Azure网站项目甚至本地应用程序中使用创建的缓存空间,使用Managed Cache Service来缓存应用程序经常读写的数据。

 

 

(2)辅助角色缓存(In-Role Cache)

In-Role Cache只能应用在托管服务项目中,开发者可以在托管服务项目中添加一个辅助角色(Cache Worker Role)来保存该托管服务中Web(Worker)Role需要缓存的数据,也可以在已有的角色如Web(Worker)Role中添加Cache组件,将已有角色的内存分配一部分出来,供添加的Cache组件使用。在第一种方式中(Dedicated Cache,独立式缓存),Cache组件运行在辅助角色实例中,其独享该辅助角色实例虚拟机上的所有CPU/Memory资源,该虚拟机的状态不会受到同一个托管服务下的Web(Worker)Role虚拟机的影响。在第二种方式中(Co-located Cache,共存式缓存),添加的Cache组件直接运行在Web(Worker)Role虚拟机中,和Web(Worker)Role应用程序共享虚拟机上的CPU/Memory资源,Cache组件的运行也会受到Web(Worker)Role服务的影响。

 

 

值得提出的是,Windows Azure Cache中还包含另外一种缓存方式:共享式缓存(Shared Cache),其外部运行模式和托管式缓存服务(Managed Cache Service)极为类似,即开发者在云端创建缓存空间,然后在应用程序中使用该缓存空间。但共享式缓存的后端采用的是SQL Azure存储技术,而不是基于内存的存储,故其实时访问速度不甚理想。Microsoft Azure已经明确宣布共享式缓存将很快下线,故本文对共享式缓存不做实践,如果开发者已经在项目中使用共享式缓存,则可以参照Windows Azure Team官方提供的迁移方案迁移到托管式缓存空间。

2.使用公有云缓存

(1)使用托管式缓存服务(Managed Cache Service)

通过Microsoft Azure管理门户创建缓存空间,如下图所示,单击“NEW”→“DATA SERVICES”→“CACHE”→“QUICK CREATE”。Endpoint将是创建的缓存空间对外的公开地址,如mytestcache.cache.windows.net。目前托管式缓存提供三种服务等级。

  • „ Basic:缓存空间大小范围为128MB~1GB,增量单位为128MB,包含一个默认的缓存器。
  • „ Standard:缓存空间大小范围为1 GB~10 GB,增量单位为1GB,除了默认的缓存器之外,开发者还可以添加独立命名的缓存器,最多可有10个缓存器。该级别的缓存提供通知(Notification)功能,开发者可以使用该功能在应用程序中关注所有的缓存操作。
  • „ Premium:缓存空间大小范围为5 GB~150 GB,增量单位为5GB,开发者也可以添加缓存器,最多可有10个缓存器。该级别的缓存提供通知(Notification)功能和高可用性(High Availability)保障。

 

 

本实践选择“Basic”缓存级别,单击“CREATE A NEW CACHE”完成托管式缓存的创建。稍等片刻,即可在Cache主视图中看到刚刚创建的缓存空间,其状态为“Running”。

 

 

点击进入所创建的缓存空间,在Dashboard页,可以查看到该缓存空间对外的访问地址,如mytestcache.cache.windows.net,单击底部的“MANAGE KEYS”按钮可以得到使用该缓存空间所需要的密钥。在Monitor页,开发者可以查看该缓存空间在实际工作中的表现和重点性能统计,如缓存空间使用率等。在Scale页,开发者可以调整当前缓存空间的级别(Basic、Standard、Premium)和缓存空间的大小。

 

 

在Configure页,开发者可以看到默认的缓存器“default”,如果调整缓存空间的等级至Standard或者Premium,则可以在此处添加更多的自己命名的缓存器。对于每一个缓存器,开发者可以自定义该缓存器的性能指标。

  • „ Expiry Policy:有效期。Absolute配合Time(MIN)是指缓存对象在初次写入之后,指定时间Time(MIN)后被清除。Sliding配合Time(MIN)是指缓存对象在最后一次被访问之后,指定时间Time(MIN)后被清除。Never配合Time(MIN)= 0是指缓存对象永远不会被自动清除。
  • „ Eviction:自动清理。打开该选项后,当缓存空间的容积被用完之后,如果还有新的缓存对象进来,缓存空间优先清理已缓存内容中最少被访问(Least Recently Used,LRU)的缓存对象,保证新进来的对象被成功缓存。如果该选项没有打开,则缓存空间的容积被使用完之后,新的写入操作就不会成功。
  • „ Notifications:该选项仅针对Standard和Premium的缓存空间,打开该选项后,开发者可以在代码中接收缓存空间发回来的通知信息。通知消息由开发者自己定义,包括缓存空间中的添加、更新、删除操作。
  • „ High Availability:该选项仅针对Premium缓存空间,打开该选项后,Azure后端会给该缓存空间创建备份,保证在主缓存空间发生异常时,继续对外提供服务。

 

 

缓存空间创建完毕以后,在本地Visual Studio中创建一个空的ASP.NET Web Role项目,右击网站项目,选择“Manage NuGet Packages…”,如下图所示。

在弹出的NuGet向导中,选择“Online”,搜索Cache,找到Windows Azure Caching安装包后,单击“Install”按钮安装该引用库,如下图所示。 

 

安装完成后,在网站项目中可以看到很多被添加进来的引用和配置更改,点击Web.config,修改dataCacheClients配置节,使用前面创建的缓存空间服务地址和管理密码(均可以从管理门户中得到)。

<dataCacheClients>

  <dataCacheClient name="default">

    <!--To use the in-role flavor of Windows Azure Caching, set identifier to be the cache cluster role name -->

    <!--To use the Windows Azure Caching Service, set identifier to be the endpoint of the cache cluster -->

    <autoDiscover isEnabled="true" identifier="[cachename].cache.windows. net" />

    <!--<localCache isEnabled="true" sync="TimeoutBased" objectCount= "100000" ttlValue="300" />-->

    <!--Use this section to specify security settings for connecting to your cache. This section is not required if your cache is hosted on a role that is a part of your cloud service. -->

    <securityProperties mode="Message" sslEnabled="false">

      <messageSecurity authorizationInfo="YWNzOmh0d************luZG93cy5uZXQv" />

    </securityProperties>

  </dataCacheClient>

</dataCacheClients>

修改完成以后保存Web.config文件,双击网站项目中的Default.aspx页面,添加两个按钮和一个文本框(Multiline),并分别双击两个按钮添加两个响应事件。

 

 

在“Write into Cache”按钮对应的响应事件中,添加以下代码。

// Cache client configured by settings in application configuration file

DataCacheFactory cacheFactory = new DataCacheFactory();

DataCache cache = cacheFactory.GetDefaultCache();

// Or DataCache cache = cacheFactory.GetCache("MyCache");

// cache can now be used to add and retrieve items

 

// Add the string "value" to the cache, keyed by "item"

cache.Put("item", DateTime.Now.ToString());

 

TextBox1.Text = "Successfully add cache object at " + DateTime.Now. ToString();

在“Read Cache”按钮对应的响应事件中,添加以下代码。

DataCache cache = new DataCache("default");

 

object result = cache.Get("item");

 

TextBox1.Text += "\r\nRead content from Cache: [" + result.ToString() + "] at " + DateTime.Now.ToString();

并在Default.aspx.cs文件中加入引用的库。

using Microsoft.ApplicationServer.Caching;

完成以后,按F5键调试运行,依次单击“Write into Cache”和“Read Cache”按钮,可以得到如图的效果。

 

 

上述代码中用到了Cache API提供的Put、Get函数,除此之外,API还提供了其他函数和有效期控制,如Add、Delete等,开发者可以根据实际需要在线查阅MDSN来准确调用。

托管式缓存除了可以给本地应用程序和云端托管服务提供“高频读写数据”存储支持之外,还有一个很好的用法就是支持存储网站项目的Session信息,如5.1.1节中所讨论的,使用外部存储技术处理网站项目的状态信息可以确保托管服务的“无状态”特性,保障托管服务的服务质量。

同样在上述实践中,仔细观察Web.config,会发现默认的sessionState设置为默认的本地Session Provider,但在添加Caching库安装包后,Web.config中被添加了另外一个被注释的sessionState设置,开发者若希望使用托管式缓存来保存网站的Session信息,只需要注释掉本地的sessionState设置,然后打开添加的sessionState设置即可。

<!--

<sessionState mode="InProc" customProvider="DefaultSessionProvider">

  <providers>

    <add name="DefaultSessionProvider" type="System.Web.Providers. DefaultSessionStateProvider, System.Web.Providers, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" connectionStringName="DefaultConnection" />

  </providers>

</sessionState>-->

<!-- Windows Azure Caching session state provider -->

 

<sessionState mode="Custom" customProvider="AFCacheSessionStateProvider">

  <providers>

    <add name="AFCacheSessionStateProvider"

type="Microsoft.Web.DistributedCache.DistributedCacheSessionStateStoreProvider, Microsoft.Web.DistributedCache"

         cacheName="default"

         dataCacheClientName="default"

         applicationName="AFCacheSessionState"/>

  </providers>

</sessionState>

如此改动对于代码中的Session调用没有任何影响,可以在Default.aspx.cs文件的Page_Load函数中加入Session调用代码进行测试。

protected void Page_Load(object sender, EventArgs e)

{

    Session["test"] = DateTime.Now.ToString();

    TextBox1.Text = Session["test"].ToString();

}

(2)使用辅助角色缓存(In-Role Cache)

现在,实践在托管服务中使用辅助角色缓存。

以Admin身份运行Visual Studio,通过单击菜单栏中的“New”→“Project”新建一个Cloud项目。在创建过程中,添加一个ASP.NET Web Role角色和一个Cache Worker Role角色,如图。

 

 

项目创建完成后,单击Roles下面的“Cache Worker Role”角色,在“Caching”配置栏可以看到,该角色默认被配置为独立式缓存(Dedicated Cache),即运行起来后,该角色实例中仅存在Cache相关的进程,共同一个托管服务下的其他角色调用。并且在默认情况下,Cache Role中只包含一个默认的缓存器“default”,开发者如果需要使用多个缓存器(如同一个托管服务中的网站项目使用缓存器default,同一个托管服务中的Worker Role项目使用自定义缓存器mycache),则可以在此处单击“Add Named Cache”按钮添加,如图所示。

 

 

点击网站项目中的Web.config文件,找到dataCacheClients配置节,然后修改identifier的值为Cache Worker Role角色名,如“CacheWorkerRole1”。此配置的作用是让网站项目指定使用Cache Worker Role角色作为缓存。

<dataCacheClients>

  <dataCacheClient name="default">

    <autoDiscover isEnabled="true" identifier="CacheWorkerRole1" />

    <!--<localCache isEnabled="true" sync="TimeoutBased" objectCount="100000" ttlValue="300" />-->

  </dataCacheClient>

</dataCacheClients>

接下来,需要在网站项目中加入使用Azure Caching服务所需要的库引用,同前面的操作一样,右键单击网站项目(如“WebRole1”),从弹出的快捷菜单中选择“Manage NuGet Packages…”,在弹出的NuGet向导中,选择“Online”,搜索Cache,找到Windows Azure Caching安装包后,单击“Install”按钮安装该引用库,如图。

需要注意的是,如果当前计算机环境使用的Azure SDK与该Caching库版本不一致,如SDK为2.0,Caching为2.1,则需要选择安装与SDK版本一致的Caching库引用:单击Visual Studio菜单栏中的“Tools”→“Library Package Manager”→“Package Manager Console”,在弹出的窗口中选择Web Role项目,然后执行Install-Package Microsoft.WindowsAzure.Caching -Version 2.0.0.0命令,如图。

 

 

Caching库引用安装完成以后,点击网站项目中的Default.aspx页面,拖入一个Button和一个TextBox,并修改Button上的文本为“Test InRoleCache”,从TextBox的属性中设置其为多行(Multiline),如图所示。

 

 

双击“Test InRoleCache”按钮,添加以下代码,该代码中包含两种调用Cache服务的方法,如果自定义了多个缓存器,则在初始化Cache客户端时指定所需要链接的缓存器,如new DataCache("mycache")。

DataCache cache0 = new DataCache("default");

cache0.Add("test", DateTime.Now.ToString());

 

var factory = new DataCacheFactory();

var cache = factory.GetDefaultCache();

try

{

    cache.Remove("testcache");

}

catch (Exception ex)

{

 

}

cache.Add("testcache", " from " + DateTime.Now.ToString());

this.TextBox1.Text = "Success in adding a cache. " + DateTime.Now.ToString();

this.TextBox1.Text += "\r\nCache data: " + (string)cache.Get("testcache");

并在Default.aspx.cs中加入Caching服务的引用。

using Microsoft.ApplicationServer.Caching;

按F5键调试运行,测试效果如图所示。

 

 

使用共存式缓存(Co-located Cache)的方法与独立式缓存非常类似:不需要添加Cache Worker Role角色,只需要含有用户项目的Web Role或者Worker Role即可,选择Roles下面的Web Role或者Worker Role,然后在Caching配置中选择“Co-located Role”,并指定一定的内存给Caching服务使用。此处配置完成之后,Caching库引用的加入、Web.config的修改以及代码的调用与上面介绍的独立式缓存实践完全一样。

 

 

 

3.更多公有云缓存

除了上述实践的托管式缓存和辅助角色缓存之外,Windows Azure目前正在集成第三方的缓存服务,即将推出另一种新式的缓存:Redis Cache,该缓存目前在Azure中国还没有落地,但在Global Windows Azure中已经开始测试使用(Preview),该缓存的最大特性是集成现有第三方缓存服务open source Redis Cache,充分利用Microsoft云平台的优势和第三方缓存服务的专业性,为不同场景下的应用方案提供更安全、高效、稳定的缓存服务。

针对Redis Cache服务,待Redis Cache正式公开适用(GA)时,后续再行分析和讨论。

Redis Cache介绍:https://msdn.microsoft.com/en-us/library/azure/dn690523.aspx

迁移已有的缓存服务到Redis Cache:https://msdn.microsoft.com/en-us/library/azure/dn690524.aspx

 

关于Azure公有云缓存,更多请参考:https://msdn.microsoft.com/en-us/library/azure/gg278356.aspx