DotNET企业架构应用实践-系统架构与性能-缓存技术与ORM中的缓存查询技术

系列回顾

      在前面的文章DotNET企业架构应用实践-系统架构与性能-理论依据及相关做法一文中我介绍了系统性能优化的理论做了一个概括的介绍,也简单的介绍了性能优化的过程及相关的技术关注点或者说是做法。

      本文将基于系统架构与程序设计两方面入手,介绍系统架构与性能优化方向一种技术实践:缓存技术与ORM缓存查询。

缓存介绍

      前面的文章DotNET企业架构应用实践-系统架构与性能-理论依据及相关做法我在系统优化的理论依据中简单的提到了CPU中的调整缓存操作系统中内存管理的分页和分段技术。

      那么缓存技术又是一种怎么样的技术呢?简单的来说,是理于局部性理论指导下的一种低成本的IO性能提升技术,或者说是一种”以一组小量高速但成本较高的IO设备和一组低速但成本很低的IO设备配合提供接近于高速IO速度”的一种技术,下面我简单的画出了计算机系统中(单机)常见IO设备的Cache结构:

      我们大家都知道,计算机结构中的高速缓存是一项非常成熟的技术,那么我们是否可以说把这样的技术应用于我们的应用软件之上呢,或者说在应用软件之中应用类似这样的技术呢?这个当然是可以的,假定我们的系统结构是如下图的结构:

      上图列出了我们常的应用部署结构,左边的结构是典型的结构,即应用由数据库服务器和应用程序两部分组成,数据库与应用程序运行在各自的计算机设备上,而右边的结构刚是一种扩展,在数据库服务器和应用程序之间增加是了一个应用程序服务器,即业务逻辑由应用程序承载,客户端应用只负责数据结果我的呈现,对于客户端来说,可以不知道数据库服务的存在。

      我们大家都知道,访问内存的速度要快速访问IO,访问本机的内存要快于访问远程机器的内存,数据库是基于数据库服务器CPU、内存、存储IO的一个复杂体,我们可以这样简单的理解,访问内存的速度要优于访问数据库,那么我们是否可以构建一种这样的机制或者应用组件/软件,能大大的减少对数据库的访问,以提高性能的目的呢?

      答案是肯定的,并且在目前的应用开发中,这样的东西是存在的,并且能大大的提升系统性能,假设我们在上图的结构中承载业务的方即左图的客户端应用与AppServer中的业务逻辑上做一些技术改进,即把访问频度很高的数据放在内存之中,而不是每次都从数据库服务器读取,即形成下图的结构:

      通过这种改造和应用,那么我们业务处理中需要的一些数据,就不必每次都从数据库重复读取,而是可以把很大一部的数据经由缓存系统(组件读取)处理,这样就可以为我们减少数据库的压力。

简单的缓存系统/组件

      既然我们已经知道了缓存是什么东西,并且是如何提高性能的,那么我们是不是可以自己搞出这样的缓存系统呢,当然是可以的,一个简单的缓存系统(组件)可以由以下接口定义: 

 1  /// <summary>
 2  /// 缓存管理器接口。
 3  /// </summary>
 4  public interface ICacheManager
 5     {
 6  /// <summary>
 7  /// 添加缓存。
 8  /// </summary>
 9  /// <param name="key">键。</param>
10  /// <param name="value">值。</param>
11  void Set<T>(string key, T value);
12 
13  /// <summary>
14  /// 获取缓存。
15  /// </summary>
16  /// <param name="key">键。</param>
17  /// <returns>返回值</returns>
18         T Get<T>(string key);
19 
20  /// <summary>
21  /// 添加缓存。
22  /// </summary>
23  /// <param name="key">键。</param>
24  /// <param name="value">值。</param>
25  void Set(string key, byte[] value);
26 
27  /// <summary>
28  /// 获取缓存。
29  /// </summary>
30  /// <param name="key">键。</param>
31  /// <returns>返回值</returns>
32  byte[] Get(string key);
33 
34  /// <summary>
35  /// 是否存在。
36  /// </summary>
37  /// <param name="key">键。</param>
38  /// <returns>存在返回true,否则返回false。</returns>
39  bool Exist(string key);
40 
41  /// <summary>
42  /// 删除对象。
43  /// </summary>
44  /// <param name="key">键。</param>
45  void Remove(string key);
46 
47  /// <summary>
48  /// 清空缓存。
49  /// </summary>
50  void Clear();
51     }

       上面代码定义了一个非常简单的缓存系统接口定义,满足了一个最基本的缓存的要求,其最主要的是Get与Set方法,缓存数据取取出数据并使用,大家可以自行实现这样的东西,一个最简单的实现就是一个键值对的目录表,运行时和应用在同一进程,如果再扩展一些的实现刚可以把缓存管理放在不同的进程或者不同服务器,应用与缓存之间使用进程或者RPC、Socket通信。

      大家可以基于这个简单的接口或者思想去实现一个简单的缓存系统,我相信它是可行的。

成熟的产品

      目前在.NET开发应用中,有很多成熟的缓存技术,在ASP.NET WebForm开发之中,ASP.NET就自带了一套缓存技术,我相信很多程序员应该熟悉,我就不在此多说了,在分布式缓存这一应用领域memcached是一个非常不错的产品,大家有关可以关注一下。

      另外,我在AgileEAS.NET平台中集成了一个简单的分布式缓存系统,大家有空也可以了解一下。

关于缓存查询

      我相信博客园很多的开发人员都是从事“基于数据库支撑的管理信息系统”开发的,也就是说开发任务中的90%都是与数据库打交道,我们知道在数据库中是可以执行“Select * from table” 这样的查询的,或者说是ORM会转化这种查询,但是当我们实现了数据对象的缓存、即ORM实体或者数据库表行集后,也可以采用与查询数据库一样的方式在缓存数据中执行类似的查询。

      也就是说我们要在缓存技术的基础上提供一种新的技术,以实现这种需求,我们权且称之为“缓存查询”,目前我在AgileEAS.NET平台的ORM组件中实现了这种技术,在ORM组件中提供了一个缓存查询接口ICacheAccessor:

 1  /// <summary>
 2  /// 缓存访问器接口。
 3  /// </summary>
 4  /// <remarks>
 5  /// 为ORM对象提供缓存查询能力。
 6  /// </remarks>
 7  public interface ICacheAccessor : IOrmEnvironment
 8     {
 9  /// <summary>
10  /// 缓存刷新实体。
11  /// </summary>
12  /// <param name="entity">实体。</param>
13  bool CacheRefresh(IEntity entity);
14 
15  /// <summary>
16  /// 表缓存查询。
17  /// </summary>
18  /// <param name="table">表。</param>
19         ITable CacheQuery(ITable table);
20 
21  /// <summary>
22  /// 表缓存查询。
23  /// </summary>
24  /// <param name="table">表。</param>
25  /// <param name="condition">数据查询条件。</param>
26         ITable CacheQuery(ITable table, Condition condition);
27     }

       由接口定义我们可以看出,ICacheAccessor定义了缓存查询方法CacheQuery类,其声明与IORMAccessor接口中数据库查询方法Query相同,也不是说,其提供了与数据加查询相类似的缓存查询技术,有关于AgileEAS.NET平台ORM介绍请参考AgileEAS.NET之数据关系映射ORMAgileEAS.NET之ORM访问器两篇文章。

      本文今天就到此为止,我将在下面的文章之中就一个应用场景演示缓存技术与缓存查询的应用。

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏Android 开发者

Android 开发者 | 应用兼容性注意事项

2853
来自专栏魏琼东

基于DotNet构件技术的企业级敏捷软件开发平台 - AgileEAS.NET平台开发指南 - 实现业务

业务分层         依据行业经验来看,分层是解决复杂问题的简单方法,通过分层,可以把一个复杂问题分解为不同层次应用的小问题,解决各层小问题的难度小于总的问...

19510
来自专栏FreeBuf

利用HTTP参数污染方式绕过谷歌reCAPTCHA验证机制

今年初,我上报了一个谷歌reCAPTCHA验证码绕过漏洞,该漏洞在于能用一种HTTP参数污染的不安全方式,让Web页面上的reCAPTCHA构造一个针对 /re...

3963
来自专栏子勰随笔

SDK设计心得之架构和资源

5894
来自专栏Linyb极客之路

理解分布式系统中的缓存架构(下)

承接上一篇《理解分布式系统中的缓存架构(上)》,介绍了大型分布式系统中缓存的相关理论,常见的缓存组件以及应用场景,本文主要介绍缓存架构设计常见问题以及解决方案,...

1111
来自专栏F_Alex

SpringCloud-初识微服务(一)

1633

使用Node.js构建API网关

当微服务架构中的服务被外部的客户端访问时,可以共享有关身份验证和传输的一些常见请求。API网关提供了一个共享层去处理服务协议之间的差异,同时满足特定客户端(像P...

4239
来自专栏CSDN技术头条

微博宕机背后,高并发有哪些常见问题?

上周,赵丽颖、冯绍峰结婚官宣造成微博宕机,那么回归技术,面对如此大的高并发流量和屡次崩溃的系统,作为程序员是否有较好的方法来应对及解决?在此,技术专家丁浪为我们...

3781
来自专栏北京马哥教育

大型网站的灵魂——性能

Via: http://blog.jobbole.com/84433/ 前言 在前一篇随笔《大型网站系统架构的演化》中,介绍了大型网站的演化过程,期间穿插了一...

3406
来自专栏java工会

15个顶级Java多线程面试题及答案,快来看看吧

1765

扫码关注云+社区

领取腾讯云代金券