Lotus Domino 附件和对象服务(Domino Attachment and Object Service,DAOS)是 Lotus Domino 8.5 新推出的全新附件存储方式。相比于以前的附件存储,DAOS 极大降低了附件的存储空间,减少了对磁盘 I/O 的读写,从而提高了 Domino 服务器的性能。一般的数据库,附件所占存储比例都在 50% ~ 90% 之间,因此在 Domino 服务器的磁盘上,有数量众多大小不一的附件,其中,有些附件是完全相同的。比如,用户在某个数据库中放入一个附件,又在某个时候将这个附件放入另外一个数据库,此时,Domino 服务器将两份附件分别存储在两个不同的数据库中。这是两份完全相同的附件,能不能在 Domino 服务器上只存储一份呢?如果能,那不是可以节省服务器的存储空间吗?事实上,DAOS 就是这么做的。无论用户在数据库中存入多少份附件,DAOS 所做的就是保证相同的附件在 Domino 服务器上只保存一份,如下图 1 所示。

图 1. DAOS 和非 DAOS 比较
图
当然,DAOS 带来的好处绝非仅仅是节省存储空间,更重要的是使 Domino 服务器减少 I/O 读写操作数和 I/O 读写数据量,从而提高了 Domino 服务器的性能。此外,对于管理员来说,由于数据库空间的减小,使得数据库压缩操作完成得更快,耗时减小,在 IBM 测试中,数据库压缩可以快 2 ~ 7 倍。由于单附件节省了存储空间,对数据库的备份比之前更快。并且,DAOS 对用户和 API 都是透明的。




回页首


需要注意的是,Lotus Domino 8.5 缺省设置并不启用 DAOS。要启用 DAOS,先决条件是 Domino 服务器启用事务日志(事务日志可以在服务器文档里启用),同时,在服务器文档“DAOS”栏设置启用 DAOS。此外,需要在数据库层面上进行设置。首先,数据库 ODS 必须是 8.5 版本或以上(为 51 或以上),然后在“database property”的“advanced”选项选中“Use Domino Attachment and Object Service”,或者使用带 DAOS 参数的 compact 命令对数据库压缩,命令为 load compact – c – daos on,这样数据库就启用了 DAOS。Lotus Domino 允许启用 DAOS 和没有启用 DAOS 的数据库同时存在,给管理员使用 DAOS 很大的灵活性。如果一个数据库没有启用 DAOS,意味着如果有多份相同附件存入这个数据库,仍旧是多份存储,就像以前的附件存储那样。服务器文档“DAOS”栏的设置项如图 2:

图 2. 服务器 DAOS 设置
图
  • “Store file p_w_uploads in DAOS”:服务器是否启用 DAOS,只有在启用的情况下,其余各项才有意义。此设置对应于 notes.ini 参数 DAOSEnable。
  • “Minimum size of object before Domino will store in DAOS”:附件会以 DAOS 方式存储的最低尺寸要求。如果一个附件的大小小于此设置值,即使所在的数据库启用了 DAOS,也不会以 DAOS 方式存储。此设置对应于 notes.ini 参数 DAOSMinObjSize。
  • “DAOS base path”:存储附件的路径,相对于 Domino 数据目录。以 DAOS 存储的附件都会存放在此路径下。事实上,即使附件只出现一个文档中,并没有被多个文档引用,也会存储在这里。服务器会在此路径下创建子路径 0001、0002,…… . 最多能够创建 10000 这样的子目录,每个子目录最多能存储 4000 个附件,附件都存储在子目录中。此设置对应于 notes.ini 参数 DAOSBasepath。
  • “Defer object deletion for”:如果文档中都已删除了某个附件,也就是说,服务器上已经没有文档还引用这个附件,那么,服务器就可以在附件目录下将此附件删除。这个删除工作什么时候做,取决于此项设置。如果设置为“0”,是让服务器在没有任何文档引用这个附件时立刻把附件删除。既然对附件没有任何引用了,还有必要让附件在服务器上保留一段时间吗?考虑这样的情况,在将来的操作中,还会把此附件存入数据库,如果此附件服务器上已经存在,那么就会节省上传附件的时间。此设置对应的 notes.ini 参数为 DAOSDeferredDeleteInterval。
前面提到,DAOS 会将附件都存放在设定的路径下,每个附件都会以 .NLO(Notes Large Object)后缀名文件存在。.NLO 文件的文件名是附件内容的校验和码。当用户往数据库存入一个附件时,DAOS 首先对附件的内容做校验和,然后和目录下的 .NLO 文件做比较(把计算得出的校验码和文件名比较),如果没有找到相同的,说明此附件对服务器来说是“第一份”和“全新”的,将附件加密后,以 .NLO 文件的形式放入目录下。如果已经存在相同的附件,就不会再将附件放入目录。服务器上有一个重要的数据库 DAOS Catalog(daoscat.nsf)来维护 DAOS 附件和其引用的维护,它记录了文档与附件之间的对应关系。对每个 .NLO 文件,DAOS Catalog 维护一个计数器,来记录附件被服务器上文档引用的次数。图 3 描述了 DAOS 存储过程。

图 3. DAOS 工作过程
图
需要注意的是,服务器在缺省情况下都会用自己的密钥对 .NLO 文件加密,这样,在操作系统层面,无法直接打开 .NLO 文件,保证附件安全性。因为使用服务器的密钥进行加密,因此除了附件所在的服务器外,其他 Domino 服务器都也都无法解密附件。Domino 也提供不对 .NLO 文件加密的设置,虽然这是强烈不推荐的。在 notes.ini 中设置 DAOS_ENCRYPT_NLO=0,Domino 服务器就不会对 .NLO 文件加密。另外,只是对附件的内容计算校验和,这就是说,只要内容相同,不同名称、修改时间的附件对 DAOS 来说都是相同的。
如果用户修改了附件内容并保存,对 Domino 服务器而言,就是新产生了和原附件不同的附件,DAOS 的处理过程和图 3 类似。
当用户删除附件时,一般服务器都不会真正的把 .NLO 文件删除,它首先更新 daoscat.nsf 中对相应 .NLO 文件的计数器,如果计数器不为 0,则不用再做任何操作,删除过程已经完成。如果计数器为 0,意味着服务器上已经没有对此附件的引用,可以将 .NLO 文件删除。删除操作何时进行,取决于上文提到的“Defer object deletion for”设置。
daoscat.nsf 在 DAOS 中扮演了十分重要的角色,它存储附件和对其引用的重要信息,是 DAOS 技术的基础。因此,daoscat.nsf 被设计成只对服务器可见,只有服务器能够读写信息,任何用户,包括服务器管理员,都没有权限访问此数据库的权限,这样能够保证 daoscat.nsf 中的信息不会因为人为操作而出现不一致的情况。并且,daoscat.nsf 是独立的,不和其他服务器上的 daoscat.nsf 复制同步。
Notes 文档并不存储附件本身。文档存储的只是对附件的引用(ticket),引用包含了附件的相对地址,因此用户在打开附件时,Domino 服务器可以根据这个引用找到附件并打开,DAOS 对用户来说是完全透明的,用户并不需要知道附件实际是怎么存储的。图 4 是附件在 Notes 文档存储的示意图。

图 4. DAOS 和引用
图
需要注意的是,DAOS 是以服务器为范围的,就是说,只有同一服务器上的数据库,才能实现对同一附件的共享。




回页首


DAOS 使邮件路由的性能大大提高。MAIL.BOX 是特殊的数据库,它也能启用 DAOS(但必须选择 LZ1 作为附件压缩方式)。未启用 DAOS 时,发送邮件中的附件会和邮件一起放入 Domino 服务器的 MAIL.BOX 数据库,邮件路由器会把它们转发到收件人的数据库,在这个过程中附件在多个数据库之间复制,造成很大的 I/O 开销,对 MAIL.BOX 的大量读写也会影响邮件转发的性能。图 5 是两种情况下的邮件路由示意图。

图 5. DAOS 和邮件路由
图
在 DAOS 启用的情况下,邮件内的附件被直接放入 DAOS 附件路径下,不会经过 MAIL.BOX。从 MAIL.BOX 内转发的仅仅是对附件的引用(ticket),这大大提高了邮件转发性能。图 5 所描述的是多个收件人的情况,实际上对于单个收件人,DAOS 也是这样做的。
对于邮件系统来说,共享邮件(shared mail)和 DAOS 有共同之处,在多个收件人的情况下,它们都能减少磁盘存储,减少 I/O 读写操作,并且对用户都是透明的。主要不同点为:
  1. 共享邮件只能使用在邮件数据库中,而 DAOS 还可以适用其他数据库。
  2. 共享邮件共享的是邮件正文,可以包含附件,也可以包含文字等其他内容,而 DAOS 共享的只是附件。
  3. 对于含有附件的邮件,DAOS 的转发效率比共享邮件高。共享邮件的方式下,邮件正文(包含附件)会进入 MAIL.BOX,而在 DAOS 方式下,附件不会进入 MAIL.BOX,而是直接放入附件存储目录,邮件路由器的转发效率更高。
Domino 8.5 及以后的版本建议使用 DAOS 与数据库设计压缩,文档压缩来代替共享邮件,共享邮件将逐渐退出历史舞台。




回页首


作为 Domino 管理员,需要对 DAOS 附件存储进行管理。下面列出了管理 DAOS 的主要命令。
Tell DAOSMgr Status:列举 DAOS 操作的状态以及 DAOS 全局信息,比如附件存储路径,删除没有文档引用附件的间隔等。
Tell DAOSMgr Status Dbsummary:列举服务器上所有启用 DAOS 的数据库状态,对附件的引用数目,如图 6 所示。

图 6. DAOS 命令显示
图
Tell DAOSMgr Status Catalog:列举 DAOS 中 catalog 的状态,版本等信息。
Tell DAOSMgr Status Databases:列举服务器上所有启动 DAOS 的数据库的详细信息,包括状态,上次引用与附件同步的时间,引用数目等,如图 7 所示。

图 7. DAOS 命令显示
图
Tell DAOSMgr Status database_name:列举某个数据库的 DAOS 信息和状态。
Tell DAOSMgr ListNLO – o outputfile_name ALL/MISSING database_name:列举指定数据库中所有(ALL)或者丢失(MISSING)的 NLO 引用,并将结果重定向到文件 outputfile_name 中。如果 NLO 文件损坏、删除或丢失,用此命令可以迅速定位,用备份的 NLO 文件进行恢复。
Tell DAOSMgr Prune day_number:删除没有文档引用的 NLO 文件。day_number 指定 NLO 已经没有任何引用但还存在服务器上的天数。如果此参数为 0,就表示立即清除所有没有引用的 NLO 文件。如果为非零,比如说 3,就是清除所有失去任何引用超过 3 天的 NLO 文件。值得注意的是,执行这个命令时,会覆盖前文提到的服务器文档“Defer object deletion for”的设置。
Tell DAOSMgr Resync:同步启用了 DAOS 数据库和 NLO 之间的引用关系。当从操作系统删除数据库,数据库恢复等操作发生后,需要同步 DAOS 引用关系,并在 daoscat.nsf 中更新。
在 Domino 服务器工作过程中,可能会出现 NLO 文件丢失,损坏而无法访问,也可能会因为 NSF 数据库损坏而致使 NLO 文件成为“孤立”文件。如果所引用的 NLO 文件丢失或者无法访问,在 NSF 文档中打开这个附件时,会遇到如图 8 这样的错误。

图 8. 错误提示
图
在服务器控制台,输入上文提到过的“Tell DAOSMgr ListNLO – o outputfile_name MISSING database_name”命令,可以得到数据库中哪个 NLO 文件丢失,以便进行备份。“fixup – J – D database_name”用来修复或删除损坏的有附件引用的文档。
如果 NSF 文件损坏,以致在同步时,无法进行扫描,导致某些 NLO 的计数为 0,这样那些 NLO 文件就成为“孤立”文件,需要及时用备份 NSF 数据库来恢复损坏的文件。




回页首


数据库在多个服务器上有副本,这些副本中,有些是启用 DAOS 的,有些是不启用的,它们之间相互复制,对附件的处理是怎样的呢?事实上,在 Domino 8.5 中,无论是启用 DAOS 和没启用 DAOS 之间的复制,还是两个都启用 DAOS 副本之间的复制,都和“普通”的复制一样,对附件进行全复制,即如果数据库中有多个对同一附件的引用,该附件会被复制多次,并不会只复制一次。但如果复制的目标副本启用 DAOS,则此副本的附件在服务器上就会以 DAOS 方式存储,也就是说,复制过程中,在目标副本启用 DAOS 的情况下,一个附件可能被复制多次,但在目标服务器上仍旧只存储一份。可以说,Domino 8.5 中的复制过程并没有充分利用 DAOS 的特点,理想的情况是,在源和目标副本都启用 DAOS 时,只复制文档中的引用(ticket)和对应的 NLO 文件,就完成副本间附件的复制。这里面涉及到一些问题,比如,NLO 文件都是以服务器的密钥加密的,简单的复制到其他服务器上并不能使用,需要一个解密再加密的过程等。总之,无论是否启用 DAOS,附件的复制都是全复制的方式,但或许在以后的版本中或有所改变。
因为启用了 DAOS,数据库的备份较以前也有所不同,除了 NSF 外,还需要备份 NLO 文件。大致的备份步骤为:
  1. 将 NSF 文件备份在单独的磁盘。
  2. 同步 NSF 数据库和 NLO 文件的引用关系,执行“Tell DAOSMgr Resync”。
  3. 备份 daoscat.nsf 和 daos.cfg,这两个文件都在 Domino 数据目录下。daos.cfg 记录了附件子目录结构等信息。
  4. 将 DAOS 附件目录下的 NLO 文件备份在另一个磁盘,注意保持子目录结构不变。这个过程可以使用数据备份工具,例如 Tivoli Storage Manager)。对于在线备份而言,NLO 文件的备份应该在 NSF 文件备份之后,因为在两种文件备份之间,服务器正常工作,可能会产生新的 NLO 文件和引用,如果先备份 NLO 文件,可能会导致备份的 NSF 文件中的一下引用没法找到 NLO 文件。
需要注意的是,在首次备份以后,可以对 NSF 和 NLO 文件采取增量备份,并且,设置服务器文档中“Defer object deletion for”的时间大于增量备份的间隔时间。
若要移动服务器上的附件存储路径,将原有路径下的所有子目录和 NLO 文件移至新的目录,注意保持所有子目录结构不变,然后对服务器文档“DAOS base path”设置做相应修改,重启服务器。




回页首


DAOS 存储下,附件仍旧占据数据库的配额(quota),虽然实际上只是以引用的方式存在。使用 DAOS 后,访问或打开附件的时间相比之前稍长,但这种增加是微乎其微的。因为在用户打开附件时,服务器必须先定位到附件,然后解密 NLO 文件,这些开销就是 DAOS 所付出的代价。
在这样的环境中使用 DAOS 将带来很大好处:
  1. 数据库中的附件数量比较多,而且重复性较高。
  2. 访问附件相对不频繁。
  3. 需要经常做数据库压缩和备份。
相对来说,下面的环境使用 DAOS 带来的好处较小:
  1. 附件数量较少。
  2. 文件内嵌在文档中,而非以附件的方式存在。
  3. 有很多附件是加密的。(加密的附件不能以 DAOS 存储)