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


    系列回顾

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

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

    缓存介绍

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

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

    image

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

    image

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

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

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

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

    简单的缓存系统/组件

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

     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访问器两篇文章。

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

          文末我附上我相关系列文章的链接和QQ群,欢迎大家。

    链接

    DotNET企业架构应用实践-系列目录

    一步一步教你使用AgileEAS.NET基础类库进行应用开发-系列目录

    AgileEAS.NET平台开发指南-系列目录

    AgileEAS.NET应用开发平台介绍-文章索引

    QQ群:116773358

  • 相关阅读:
    持续集成
    Centos7配置安装及优化
    vi/vim如何添加或删除多行注释.
    [Ansible实战]-批量配置初始化主机环境.
    VW模板机准备
    一次CPU过载报警处理
    [Ansible实战]-免交互批量管理Zabbix
    [Ansible实战]-ansible初始化mysql数据库
    [Ansible实战]-ansible部署Redis-5.x集群
    远程管理服务(SSH).
  • 原文地址:https://www.cnblogs.com/eastjade/p/1856003.html
Copyright © 2020-2023  润新知