Sun ONE 徽标     上一章      目录      索引      下一章     
Sun ONE Directory Server 5.2 安装和调整指南



第 7 章   调整索引编制

随着 Directory Server 处理的条目越来越多,搜索可能消耗的时间和系统资源也越来越多。索引是提高搜索性能的一个工具。本章介绍 Directory Server 索引的工作方式,以便于您了解在特定部署环境中使用某种索引的利与弊。

关于索引

索引将查找信息和 Directory Server 条目关联起来。索引表现为 Directory Server 数据库中所存储的文件。此处的数据库是后缀的物理表现。对于大多数部署而言,一个后缀对应一个数据库。对于某些部署而言,一个后缀可能对应着多个数据库。默认情况下,Directory Server 将数据库存储在 ServerRoot/slapd-ServerID/db/(nsslapd-directory 的默认值)下。在这里,您可以发现单独的数据库实例,它们的每个已编制索引的属性都对应一个索引文件。例如,数据库 example 有一个 CN 索引文件,其中的条目来自后缀 dc=example,dc=com,那么它将被称为 ServerRoot/slapd-ServerIDdb/example/example_cn.db3

索引内容取决于客户机应用程序访问目录数据的方式。表 7-1 中包括标准索引类型的简要说明。

表 7-1    标准索引类型 

索引类型

回答的问题...

近似

对于此属性,哪些条目的值与搜索值相类似?

浏览

哪些条目适合该虚拟列表视图搜索?

等式

对于此属性,哪些条目的值与搜索值等同?

国际

哪些条目匹配该国际区域?

存在

哪些条目具有此属性?

子字符串

对于此属性,哪些条目的值符合 *搜索值* 的格式?

特定属性(如 CN)的索引文件可能含有多种索引类型。例如,如果在 example 数据库中针对 CN 编制索引来实现等式和子字符串匹配,那么 example_cn.db3 中将同时包含等式和子字符串索引。

请参阅 Sun ONE Directory Server 管理指南,了解以下内容:

  • 各种索引类型的概述
  • 有关创建和删除索引的说明
  • 由 Directory Server 创建的默认索引列表
  • Directory Server 所需的系统索引列表

在许多情况下,默认索引都可提高搜索性能,并且还为其他应用程序(如消息发送)提供了一定的支持。在某些情况下,出于性能考虑,您可以选择禁用甚至删除特定的默认索引。系统索引是 Directory Server 依赖的索引。请不要将其删除或进行修改。

优点:搜索使用索引的方式

索引可提高搜索的速度。索引中包含一系列的值,每个值又关联到与该值对应的条目标识符列表。Directory Server 可以使用索引中的条目标识符列表快速查找条目。如果没有用来管理条目列表的索引,那么 Directory Server 就必须检查后缀中的每个条目,来找出搜索的匹配结果。

编制了索引的搜索比没有编制索引的搜索所需的处理工作量要少得多;我们只需分析一下搜索请求的处理方式,就可以明白其中的原因。Directory Server 处理每个搜索请求的方式如下:

  1. 客户机应用程序将搜索请求发送到 Directory Server。
  2. Directory Server 检查请求,确保搜索基础与它能够处理的某个后缀相对应。如果不对应,那么它将向客户机返回一个错误消息,同时可能会返回一个到其他 Directory Server 实例的引用。
  3. Directory Server 检查它所管理的索引中是否有哪一个适用于此次搜索。
  4. 对于存在的每个此类索引,Directory Server 都会查找其中的候选条目 - 可能与搜索请求相匹配的条目,如图 6-2 中所示。

    请注意,如果没有这样的索引,那么 Directory Server 会以数据库中的所有条目为基础生成候选条目集。对于大型部署,本步骤可能会消耗相当多的时间和系统资源,具体情况因搜索任务而各有不同。

  5. Directory Server 检查每个候选条目,确定它们是否与搜索条件匹配。找到匹配条目后,Directory Server 会将其返回到客户机应用程序。
  6. Directory Server 继续检查候选对象,直至所有候选对象检查完毕,或者达到了某项资源限制(如 nsslapd-lookthroughlimitnsslapd-sizelimit、或 nsslapd-timelimit),具体内容在“限制客户机可用的资源”中有所描述。

第 3 步中可明显看出,索引能够显著地减少 Directory Server 在响应客户机搜索请求时需执行的处理任务。

缺点:更新时索引如何处理

更新不仅更改条目本身,还更改引用这些条目的索引。索引中对某一条目的引用越多,更新期间修改索引的潜在处理成本就越高。特别地,在向客户机应用程序发送更新确认之前,Directory Server 需要修改所有受到影响的索引,如图 6-3 所示

除了索引维护的处理成本之外,其他成本还包括磁盘空间和可能的内存空间成本。如“为搜索进行优化” 中所述,在优化用于搜索的数据库缓存大小时,您可能倾向于提供足够容量的内存,以便在数据库缓存中同时容纳条目和索引。索引越大,所需的空间也就越大。而且 64 位索引需要的空间要比 32 位索引大。

一般来说,对某个 Directory Server 实例的索引进行调整,就是要对索引进行筛选,确保它们在实现更快搜索方面的优点能够抵消更新开销和空间占用方面的不足。维护有用的索引是一种很好的做法;而维护客户机很少搜索的闲置属性索引则是一种浪费。

存在索引

图 7-1 显示了 nsRoleDN 属性的存在索引;可以看到此索引与属性值无关,而只是包括了数据库中具有 nsRoleDN 属性的所有条目。属性的每个值都匹配 *

图 7-1    存在索引的例子
若有足够的缓存,命中率会很高。

如上所示,内部 entryid 属性值允许 Directory Server 存储条目的引用,以便进行快速检索。事实上,Directory Server 使用 dbinstance_id2entry.db3 索引文件来检索条目,其中的 dbinstance 取决于“关于索引”中介绍的数据库标识符。

当 Directory Server 接收到请求,要更新具有存在索引属性的条目时,它必须确定该条目是否必须从索引中删除,并且必须执行所有必要的修改,然后才能向客户机应用程序返回更新确认。

存在索引的成本一般要比其他索引类型低,但它要维护的条目列表可能很长。

等式索引

图 7-2 显示了 SN(姓氏)属性的等式索引。可以看到对于此索引中的每一个属性值,都有一个以此值为 SN 属性值的项目的列表与之对应。

图 7-2    等式索引的例子
若有足够的缓存,命中率会很高。

当 Directory Server 接收到请求,要对具有等式索引属性的条目进行更新时,它必须确定是否必须将该条目从索引中删除,是否必须向索引中添加一个列表或从索引中删除某个列表,并且在将更新确认返回给客户机应用程序之前,必须完成所有必要的修改。

等式索引的成本一般比子字符串索引低,但在空间方面的要求要比存在索引高。不过,某些客户机应用程序(如消息服务器)可能会依靠等式索引来获得顶级的搜索性能。请不要对照片和加密口令这样的大型二进制属性使用等式索引。

子字符串索引

图 7-3 显示了 SN(姓氏)属性的子字符串索引。它通过摘要说明了此索引如何根据属性值维护一系列列表。

Directory Server 编制的子字符串索引使您能够在索引中查找双字符的子字符串。例如,使用索引可加快搜索 (sn=*ab*) 的速度,但不能加快搜索 (sn=*a*) 的速度。

图 7-3    子字符串索引的例子
若有足够的缓存,命中率会很高。

Directory Server 还提供了进一步的优化,允许您对字符串首字母加通配符的子字符串进行搜索。例如,当子字符串索引可用时,可以加快 (sn=a*) 搜索的速度,但 (sn=*a*) (sn=*a) 则不行。

请注意,Directory Server 根据其内置的规则构建子字符串的索引。这些子字符串不可以通过系统管理员配置。

当 Directory Server 接收到请求,要对具有子字符串索引属性的条目进行更新时,它必须确定该条目是否必须从索引中删除、条目的更改是否以及如何影响索引、是否必须向索引中添加条目 ID 或从索引中删除条目 ID 列表;并且在将更新确认返回给客户机应用程序之前,它必须执行所有必要的修改。更新的数目取决于属性值字符串的长度。

一般而言,维护子字符串索引的成本相当高。因为该成本是编制索引的字符串长度的函数,所以应避免使用不必要的子字符串索引;对于可能具有长字符串值的属性(如 description)更是如此。子字符串索引不能应用于二进制属性,如照片。

浏览(虚拟列表视图)索引

图 7-4 显示了虚拟列表视图的浏览索引。它说明了此索引如何利用虚拟列表视图的信息。具体讲,就是用于实现浏览索引的 vlvBasevlvScopevlvFiltervlvSort 属性值。此类索引中的条目 ID 根据 vlvSort 标准进行排序。

图 7-4    浏览索引的例子
若有足够的缓存,命中率会很高。

当 Directory Server 接到请求,要对与某个 vlvFilter 值相匹配的条目进行更新时,它必须确定该条目是否一定要从索引中删除,必须找出条目在列表中的正确位置,并且必须在将更新确认返回给客户机应用程序之前执行所有必要的修改。

近似索引

Directory Server 使用变音位语音算法的一种变体来维护近似索引。此算法将属性字符串的值分解成与其大致近似的英语语音发音。传入的搜索请求中要匹配的值也使用同一算法进行处理。因为此算法不严格地基于音节,所以对于含有电话号码等数字的属性无效。

该算法为每个属性值字符串生成一个目标字符串。因此,这种英语字符串的“音似”索引编制方法,其成本与等式索引类似。

国际索引

国际索引使用特定区域设置的匹配规则来维护索引。因此,这种索引的成本近似于子字符串和等式索引的成本。

通过使用自定义的匹配规则服务器插件,可以对国际索引其他类型索引的标准支持进行扩展。有关自定义匹配规则插件的详细信息,请参阅 Sun ONE Directory Server Plug-In API 编程指南

示例:编制条目索引

假设有一个后缀,其多项属性已编有索引,其中包括:对 uid 编制了等式索引;对通用名称 (cn) 和姓氏 (sn) 属性编制了等式、子字符串和近似索引;对 mail 属性编制了等式索引;对 telephoneNumber 属性编制了等式和子字符串索引;以及对 description 属性编制了子字符串索引。现在要将如下所示的用户条目加入其中。



代码示例 7-1    用户条目样例


dn:uid=yyorgens,ou=People,dc=example,dc=com
objectclass:top
objectclass:person
objectclass:organizationalPerson
objectclass:inetOrgPerson
uid:yyorgens
givenName:Yolanda
sn:Yorgenson
cn:Yolanda Yorgenson
mail:yolanda.yorgenson@example.com
telephoneNumber: 1-650-960-1300
description:Business Development Manager, Platinum Partners


添加此条目时,Directory Server 必须修改 cnsnmailtelephoneNumberdescription 的索引。表 7-2 中列出了预计的条目数。

表 7-2    用户条目样例的索引更新 

属性

近似

等式

子字符串1

总索引更新

uid

 

1

 

1

cn

1

1

17

19

sn

1

1

9

11

mail

 

1

 

1

telephoneNumber

 

1

11

12

description

 

 

47

47

1

对于像此处的 description 字符串这样的长字符串来说,在大多数部署中,不推荐使用子字符串索引。

可以看到,description 字符串的子字符串索引更新数 (47) 大于所有其他属性更新数目的总和 (44)。并且,如果对 description 字符串作进一步的修改,那么将再次使更新数目达到最大值甚至更多;具体数目还取决于新的字符串。在大多数情况下,对于像 description 这样的长字符串值,不要使用子字符串索引。

调整索引编制来改善性能

在很多情况下,为改善性能而调整索引编制意味着激活常用搜索的索引以提高速度,同时停用那些维护成本高但却不常用的索引。



注意

数据库备份中包括索引,所以应该与 Directory Server 的配置相匹配。

在更改了索引的配置方式后,应同时备份配置和数据。



对于那些包含专门应用于特定应用程序的复制副本的大型部署而言,可以选择为不同的 Directory Server 实例配置不同的索引。例如,可考虑如下拓扑:

  • 主机只负责处理写入任务
  • 集线器负责处理到使用者的复制任务
  • 某些使用者专门用于特定应用程序(如消息发送)

在这种情况下,主机并不处理搜索,因此可选择不在主机上维护高成本的子字符串索引。您也可以确定还有哪些索引很少使用,并将其停用。

实际上,除了管理请求外,集线器不会接到其他客户机请求,因而在这种情况下可以停用除 Directory Server 本身所需的系统索引外的所有其他索引。

在专门用于个别应用程序的特定使用者上,您可以停用所有该应用程序不使用的索引。具体停用哪些索引取决于特定应用程序所执行的搜索。

只允许执行编制了索引的搜索

Directory Server 能够防止执行成本很高的未编制索引的搜索;它将向那些请求执行未编制索引的搜索的客户机返回 LDAP_UNWILLING_TO_PERFORM

要防止对特定数据库执行未编制索引的搜索,可将该数据库的 nsslapd-require-index 属性值设置为 on

$ ldapmodify -h host -p port -D "cn=directory manager" -w password
dn:cn=example,cn=ldbm database, cn=plugins, cn=config
changetype:modify
replace:nsslapd-require-index
nsslapd-require-index:on
^D (^Z on Windows systems)

更改会立即生效。无需重新启动 Directory Server。

限制索引表的长度

在规模较大、增长迅速的目录部署中,特定索引关键字的索引可能会到达一个效率递减点。在效率递减点,与特定关键字相关联的列表会变得很长,以致于维护该列表的成本超过了偶尔对该关键字执行未编制索引的搜索来查找候选条目的成本。例如,有一个对姓氏进行了等式索引编制的超大型电话簿应用程序。假设该电话簿中有很多个 Smith,以致于维护 Smith 索引耗用的成本超过了它在加速查找方面的益处。此时,Directory Server 应停止编制 Smith 姓氏的索引,但应继续编制其他姓氏的索引。

Directory Server 具备一种处理此类问题的机制。可为配置属性设置临界值。如果特定关键字列表中的条目数达到了所设置的值,那么 Directory Server 将把该关键字列表替换为一个令牌,指明在查找该关键字的候选条目时应执行未编制索引的搜索。该值应当接近但小于此次搜索候选条目的最大个数;请使用 nsslapd-lookthroughlimit 来进行设置,具体内容见于表 9-1

该机制被称为全部 ID 临界值,其由来是设置全局临界值所使用的配置属性的名称,cn=config,cn=ldbm database,cn=plugins,cn=config 上的 nsslapd-allidsthreshold。注意该值当前对于 Directory Server 实例是全局的。它不可以为不同索引设置不同值。

图 7-5 显示了为姓氏编制索引时,Smith 的个数超出 nsslapd-allidsthreshold 的情况。

图 7-5    达到某个索引关键字的全部 ID 临界值
若有足够的缓存,命中率会很高。

请注意,临界值只影响索引表中的一个列表。其他关键字列表不受影响。

索引表大小不当的症状

如果客户机主要执行编制了索引的搜索,并且缓存大小也按照第 6 章“调整缓存大小”中所述进行了正确的调整,但是搜索性能仍然不理想,则可能是由于临界值设置的不合适导致的。当发现已编制索引的搜索性能不佳时,请首先确认缓存大小是否已进行了适当的调整。接下来,检查 access 日志,看 Directory Server 是否经常达到全部 ID 临界值。

access 日志 RESULT 消息末尾的 notes=U 标记指明,Directory Server 执行了未编制索引的搜索。其前面属于同一连接与操作的 SRCH 消息中指出了所使用的搜索过滤器。以下两行示例记录了对 (cn=Smith) 的未编制索引搜索,该搜索返回了 10000 个条目。消息中的时间戳已经被删除。

conn=2 op=1 SRCH base="o=example.com" scope=0 filter="(cn=Smith)"
conn=2 op=1 RESULT err=0 tag=101 nentries=10000 notes=U

如果发现许多应为已编制索引的搜索中存在这样的记录对,那么就表明增大临界值可能会提高搜索性能。

更改索引表临界值的大小

比较理想的 nsslapd-allidsthreshold 值通常处于目录条目总数 5% 的范围内。例如,默认值 4000 一般适用于处理 80,000 或更少条目的 Directory Server 实例。如果预计近期将把大量条目添加到目录中,或者预计目录将会显著增加,那么可以将该值设置为远远高于 5%。也可以将支持许多搜索的使用者副本上的临界值设置为其他值,使之不同于仅支持写入的主机上的临界值。如果计划近期将从 LDIF 中重新初始化一个大型的目录,那么您可以选择在重新初始化之前调整 nsslapd-allidsthreshold 的值,因为对此属性值的每次更改都要求重建全部索引。在任何情况下都不要将全部 ID 临界值设置得很高(50,000 以上),即使对于大型部署也是如此,除非您有极其充分和具体的理由。

全部 ID 临界值的更改方法如下。请注意,接受更改的 Directory Server 实例上的服务将发生中断。

  1. 将需要做更改的 Directory Server 实例停止。
  2. 将所有的目录数据库导出到 LDIF。
  3. 详细信息,请参阅 Sun ONE Directory Server 管理指南

  4. 仔细调整 nsslapd-allidsthreshold 属性的值,该值位于 ServerRoot/slapd-ServerID/config/dse.ldif 中。
  5. 从 LDIF 重新初始化所有目录数据库。
  6. 详细信息,请参阅 Sun ONE Directory Server 管理指南

  7. 如果您曾为旧的全部 ID 临界值调整过数据库缓存大小,并且服务器也有充足的物理内存,那么可以考虑提高数据库的缓存大小,增幅比例为临界值增幅比例的 25%。
  8. 换句话说,如果将全部 ID 临界值从 4000 增加到 6000,那么可以将数据库缓存大小增加 12.5%,以适应索引表大小的增加。在将更改应用到生产服务器之前,请根据经验找到最佳大小。有关数据库缓存调整的详细信息,请参阅第 6 章“调整缓存大小”

  9. 重新启动 Directory Server 实例。

解决索引碎片问题

支持大型索引和高更新率的 Directory Server 实例可能会产生大量的索引关键字碎片。大量的索引关键字碎片会降低性能,即使数据库大小稳定也是如此。如果您认为大量的索引关键字碎片显著影响了服务器的性能,那么可以考虑重新生成受影响的索引以减少碎片。

有关创建索引的详细信息,请参阅 Sun ONE Directory Server 管理指南


上一章      目录      索引      下一章     
版权所有 2003 Sun Microsystems, Inc. 保留所有权利。