系列回顾
本文将基于系统架构与程序设计两方面入手,介绍系统架构与性能优化方向一种技术实践:缓存技术与ORM缓存查询。
缓存介绍
那么缓存技术又是一种怎么样的技术呢?简单的来说,是理于局部性理论指导下的一种低成本的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
}
本文今天就到此为止,我将在下面的文章之中就一个应用场景演示缓存技术与缓存查询的应用。
文末我附上我相关系列文章的链接和QQ群,欢迎大家。
链接
QQ群:116773358
本文转自 agilelab 51CTO博客,原文链接:http://blog.51cto.com/agilelab/603052