aku1 发表于 2006-11-1 16:49:29 |
级别: 中级
吉 晓峰 (jixf@cn.ibm.com), 软件工程师, IBM 中国软件开发中心
2006 年 8 月 04 日
本文介绍 C/S 模式下 Domino/Notes 软件的缓存机制,以及为有效利用缓存机制应采用的一些应用程序的设计和开发技巧。
如何提高应用程序的响应时间? 利用“缓存”(Cache)机制是众多主流软件采用的有效办法之一。Domino/Notes 作为业界知名的办公协作软件,同样提供了一套行之有效的缓存机制,本文旨在对 Domino/Notes 的缓存机制进行总括性的介绍,并指导开发人员在程序的开发设计阶段利用 Domino/Notes 的缓存机制更好的进行应用程序的结构设计和代码开发,提高应用程序的性能。
Notes/Domino 缓存机制概述
将常用的应用程序/数据存储在 Server 前端,用户工作机磁盘或者内存里,使用户得到更快的程序响应时间,我们称这一类程序/数据为缓存(Caching)。Domino 服务器(Server)端和 Notes 客户(Client)端均提供了强大的缓存机制。
- Notes 客户端能缓存相关的设计元素在本地工作站
- 服务器端能缓存相关的设计元素,Lookup 结果和 Profile 文档在服务器
合理的使用缓存机制是十分重要的。开发人员需要有效的控制“缓存哪些应用程序/数据”,“何时进行缓存”以及“何时更新缓存”。
本文主要介绍在 C/S 模式下 Notes/Domino 相应的缓存模式。在 B/S 下的缓存机制,笔者将在后续的文章中给予介绍。
Notes 客户端的缓存机制
我们经常会遇见这种情况,如果用 Notes 客户端首次访问某个 Notes 应用程序,并查看其中的一些文档。查看过第一个文档后,再查看其他同类型的文档,Notes 客户端打开文档的速度要明显加快。究其原因,Notes 客户端在打开第一个文档之后,已经将相应的表单缓存在了本地工作机磁盘,所以打开后续文档时客户端只需装载本地的缓存表单,这必然大幅度的提高应用程序的响应时间。
通常情况下,Notes客户端只能缓存某些设计元素,参见表 1。 表1. 设计元素的缓存
能够被缓存的设计元素 |
表单,子表单,页面,祯结构,图象资源,视图,共享操作,脚本库等 |
不能够被缓存的设计元素 |
代理等 |
Notes 客户端将需要缓存的设计元素存储于 Notes 数据目录下的 Cache.ndk 里面。我们通过查看 Workspace 的属性可以看到其相关的设计,参见图 1。 图1. Workspace 属性
默认情况下,Cache.ndk 存放于 Notes 的数据目录并且占有不大于 30Mb 的磁盘空间。同时,我们也可以通过 Notes.ini 里面的相关参数控制 Cache.ndk 的位置和大小。例如:
文件大小:InitialCacheQuota=xxxx
文件位置:CACHE=C:\TEMP\CACHE.NDK
|
事实上,Cache.ndk 是一个标准的 Notes 数据库,可以用 Notes 客户端打开。所有被缓存的设计元素以文档的形式存储在 Cache.ndk 里面, 参见图 2。 图2. 在 Notes 客户端中打开 Cache.ndk
缓存数据以队列顺序存储于 Cache.ndk 中,如果文件大小超过限额,前期最早的数据将被自动删除。
我们在设计应用程序的时候,为了有效利用 Notes 客户端的缓存机制,应遵循以下基本原则,特别是在网络带宽有限的情况下:
有效使用子表单(Subform)
在应用程序包括很多表单的情况下,将其共有的设计存储于子表单,可以有效的提高程序的性能。例如 Form A 和 Form B 都含有 Subform A, 如果 Notes 客户端在缓存了 Form A 之后,再缓存 Form B, 就可以忽略已经缓存的 Subform A。参见图 3。 图3. 运用子表单减少缓存时间
这里要特别提到的是,在数据库只含有少数表单,数据罕有共用的情况下,我们是不提倡使用子表单的。基于 Domino 的顺序处理机制,对于一个含有子表单的表单来说,Notes 客户端先装载表单,再装载子表单,顺序访问同一层次的设计元素,相对于只使用一个表单的情况,这必然增加程序运行的时间。
有效使用脚本库(Script Library)
通常,我们将一些可能被重复用于视图操作、代理和表单等的公用代码写成脚本库。Notes 客户端能够对脚本库进行缓存。这样,Notes 客户端在缓存了一次脚本库后,相关的设计元素均可以对其在本地进行调用,进而有效的提高应用程序的性能。
我们采用 Use “Script Library Name”调用需要的脚本库, 例如,下图显示了如何在表单中使用脚本库. (该表单调用名称为 CSEventNotes 的脚本库)。 同样的脚本库可能在许多设计元素中被重复使用。参见图 4。 图4. 脚本库重用
特别需要指出的是,相对于脚本库, 代理是不能被缓存到本地的。一般情况下,我们将那些不被经常使用的(用于验证或修改文档的)代码写进代理,程序可通过如下方式对代理进行调用:
@Command ([ToolsRunMacro]; “Agent Name”)
|
通过上述公式,Notes 客户端实时的呼叫代理并在服务器端/客户端执行它。我们也同样可以用 Use 的方法在代理中调用 Script Libray。
Domino 服务器端的缓存机制
Domino 服务器能对数据库的设计元素、Profile 文档以及 Lookup 结果进行缓存。另外,Domino 服务器本身也可作为 Web 服务器,对 Web 页面和 Java Servlet 进行缓存。对服务器缓存的一些配置可以通过 Notes.ini 的相关参数。
NSF_Buffer_Pool_Size= value
|
此参数用于指定服务器端数据缓存池的大小,默认情况下,其大小为服务器物理内存的 1/8 到 3/8, 我们也可以根据内存的使用情况自己指定其大小(按字节),Domino 限制其不能超过 2GB. 建议对单服务器采用默认设置。对于分区服务器,可根据内存情况自行设置。
NSF_DbCache_Maxentries=number
|
此参数用于指定服务器缓存池能并发处理的数据库数量。默认情况下,其最小值为 25。结合服务器内存大小,管理员可适当增加其数量,推荐至少 300k 缓存大小用于处理一个数据库。
缓存数据库设计元素
Domino 服务器将用户经常使用的数据库的设计元素缓存到内存里,便于用户的 Notes 客户端快速装载相关的设计元素。Domino 服务器与 Notes 客户端可缓存的设计元素类型基本相同。
需要说明的是,为了使应用程序在缓存区迅速定位数据库,Domino 服务器也将数据库的属性,视图信息等存储在缓存区。
缓存 Lookup 结果
Domino 有两个重要的 Lookup 公式:@dbcolumn和@dblookup.。一般情况下,我们推荐使用 Cache 将结果进行缓存,这样可以大大提高下次进行同样搜索的速度。我们来看一个例子:
@DbLookup( class : cache ; server : database ; view ; key ; fieldName ; keywords )
|
对于 cache 参数,我们有以下三种选择
- “”, Domino 自动缓存相关的 Lookup 结果
- “Recache”, Domino 总是判断数据的更新时间,缓存最新的 Lookup 结果
- “Nochache”, Domino 不缓存相关的 Lookup 结果
用户可以根据应用程序的需要对上述三种参数进行选择。当数据库被关闭时相应的 Lookup 结果缓存将被清空。
缓存 Profile 文档
Profile 文档用来存储一些用户特定信息或数据库特定信息,其功用与定义于 Notes.ini 里面的环境变量类似,但使用环境变量有如下缺点:
- 数目限制,我们只能定义有限的环境变量于 Notes.ini 中
- 迁移限制,当我们将数据库迁移到另外一台服务器上,必须修改相应的 Notes.ini 文件。
所以,相对于环境变量,由于 Profile 文档被保存于数据库中,没有上述限制,使用起来更加灵活有效。在性能上,访问 Profile 文档相当于访问普通的 Notes 文档。
对于一个数据库来说,可能包括多个 Profile 文档,例如,对每个用户使用一个 Profile 文档存储该用户特定信息(注:多用户不能共用一个 Profile 文档),或用单独一个 Profile 文档存储数据库相关信息。
通常,在打开数据库时,我们通过 PostOpen 事件调用 Profile 文档里的值,将 Profile 文挡缓存在服务器内存里,进而在后续应用中更好的使用 Profile 文档。当数据库被关闭或用户与服务器的会话终止后相应缓存将被清除。
关于 Profile 文档的基本介绍和设计开发方法,请读者查阅 Notes/Designer 的帮组文件,本文不再赘述。
了解了 Domino 服务器端的缓存机制后,在应用程序的设计开发阶段,我们应该有如下考虑:
- 配制合理的缓存区大小和可并发处理数据库数目
- 为 LookUp 相关公式选择合适的缓存选项
- 将常用的功能放在可缓存的设计元素中,有效使用子表单和脚本库
- 通过 PostOpen 事件在数据库初始化时缓存相关的 Profile 文档,有效提高程序性能
|