「LDAPが遅い」と言われたら、まずはログの “notes=U” を探せ。
こんにちは!「LINUX工房」管理人の「リナックス先生」です。
前回は、SSL/TLS化によるセキュリティ強化について学びました。
セキュアで可用性の高い認証基盤ができあがりましたが、ユーザー数が増えてくると、新たな敵が現れます。
それは「遅延(Latency)」です。
朝の始業時、全社員が一斉にログインしようとして認証がタイムアウトする。
住所録の検索がいつまで経っても終わらない。
これらはサーバーのスペック不足ではなく、多くの場合「設定(チューニング)不足」が原因です。
先生、まさに今その状態です!
ユーザー数が3,000人を超えたあたりから、特定のアプリで検索がすごく重いんです。top コマンドを見てもCPUは余裕があるし、メモリも余ってるのに、なぜか遅い。
「LDAPサーバーなんてこんなもん」って諦めるしかないんですか?
RDBMSみたいにインデックスとか貼れないんですか?
コウ君、諦めるのはまだ早いわ。
LDAPサーバーは、適切なインデックスとキャッシュ設定を行えば、数万、数十万ユーザーでもミリ秒単位で応答できるポテンシャルを持っているの。
逆に言えば、デフォルト設定のまま大規模運用するのは「ギアを1速に入れたまま高速道路を走る」ようなものよ。
今回は、389 DSのエンジンルームを開けて、パフォーマンスを極限まで引き出すチューニング術を伝授するわ!
はい、ウィンドウズ先生です。
Active Directoryの世界でも、インデックスのない属性でクエリを投げるとドメインコントローラーが高負荷に陥ります。
389 DSも仕組みは同じです。
特に「部分一致検索(*taro*)」と「キャッシュのメモリ割り当て」は、エンジニアの腕の見せ所です。
ログ解析からボトルネックを見つけ出し、外科手術のように設定を修正するプロの技をお見せしましょう。
本記事では、LDAP検索の仕組み、インデックスの種類と作成手順、Berkeley DBのキャッシュチューニング、そしてアクセスログ解析による「遅いクエリ」の特定方法までを徹底解説します。
🐧 389 Directory Server 完全攻略講座 カリキュラム
- 【第1回】OpenLDAP vs 389 DS。アーキテクチャの違いから学ぶ、次世代LDAPの選定基準
- 【第2回】爆速インストール。構成ファイルによるIaC化とCockpit Web GUIの構築
- 【第3回】CLI管理の革命。dsidmコマンドとJSON出力の活用
- 【第4回】アクセス制御 (ACI) の設計論。ACLとの決定的な違い
- 【第5回】マルチマスターレプリケーション構築。可用性99.999%への道
- 【第6回】セキュリティ強化。自己署名証明書の撤廃とTLS完全化
- 【第7回】パフォーマンスチューニング。インデックス設計とキャッシュ戦略
- 【第8回】クライアント連携。SSSDによるオフライン認証と統合管理
目次
第1章:なぜLDAPは遅くなるのか? 全件検索の恐怖
まず、データベースがデータを検索する仕組みを理解しましょう。
例えば、「社員番号(employeeNumber)が12345の人を探す」というクエリが来たとします。
インデックスがない場合 (Unindexed Search)
LDAPサーバーは、データベース内のすべてのエントリを1つずつ読み込み、「employeeNumberは12345か?」と確認します。
これを「全件走査(Full Table Scan)」と呼びます。
ユーザーが100人なら一瞬ですが、10万人いたら? ディスクI/Oが爆発し、CPUリソースを食いつぶし、結果が返ってくるまで数秒〜数十秒かかります。
インデックスがある場合
サーバーは「インデックスファイル(索引)」を参照します。
そこには「12345番のエントリは、データベースの〇〇番地にあります」と書かれています。
サーバーはピンポイントでそのデータだけを読みに行きます。
計算量は O(N) から O(1) (または O(log N)) に激減し、一瞬で応答します。
💡 389 DSの安全装置:nsslapd-allidsthreshold
389 DSには、「インデックスを使わない検索結果が4000件(デフォルト)を超えたら、検索を中断する」という安全装置があります。
「検索結果が見つかりません」ではなく「管理者制限を超えました」というエラーが出た場合、それはインデックスが効いていない証拠です。
第2章:インデックスの種類と設計戦略
「じゃあ全部の属性にインデックスを貼ればいいじゃん!」と思うかもしれませんが、それは間違いです。
インデックスを作成すると、書き込み(更新)時のオーバーヘッドが増え、ディスク容量も消費します。
必要な属性に、必要な種類のインデックスだけを設定するのがプロの仕事です。
主なインデックスタイプ
| タイプ | 略称 | 説明 | 用途例 |
|---|---|---|---|
| Equality | eq | 完全一致検索。最も基本的かつ重要。 | uid=taro, employeeNumber=1001 |
| Substring | sub | 部分一致検索。検索窓での入力補完などで使用。 | uid=ta*, sn=*yamada* |
| Presence | pres | その属性を持っているか(存在確認)。 | mail=* (メアド持ちを全員検索) |
| Approximate | approx | あいまい検索(発音が似ている等)。英語圏向け。 | あまり使われない。 |
デフォルトでインデックスがある属性
389 DSは、標準的な属性(cn, sn, uid, mail, objectClass など)には最初から適切なインデックスが設定されています。
追加が必要になるのは、以下のようなケースです。
- カスタム属性: スキーマ拡張で追加した独自の属性(
myCompanyIDなど)。 - 数値属性:
uidNumber,gidNumber(SambaやLinuxログインで必須)。 - 特定用途の属性:
memberOf(グループ検索用)、entryUUIDなど。
第3章:実践!インデックスの作成と再構築 (reindex)
それでは、実際にインデックスを追加してみましょう。
例として、社員番号(employeeNumber)で高速に検索できるようにします。
1. 現在のインデックスを確認
dsconf コマンドで、対象のバックエンド(通常は userRoot)の設定を確認します。
# インスタンス名: localhost, サフィックス: dc=linuxkoubou,dc=com dsconf localhost index list --suffix "dc=linuxkoubou,dc=com"
ここに employeeNumber がなければ、インデックスはありません。
2. インデックスの作成
完全一致(eq)インデックスを追加します。
dsconf localhost index create --suffix "dc=linuxkoubou,dc=com" \ --attr employeeNumber --type eq
注意: このコマンドを実行しただけでは、設定ファイル(dse.ldif)に定義が追加されるだけで、実際のインデックスデータは生成されません。
3. 再インデックス (Reindex) の実行
既存のデータに対してインデックスファイルを生成するタスクを実行します。
データ量が多い場合、この処理には時間がかかりますが、サービスを停止する必要はありません(オンラインReindex)。
dsconf localhost index reindex --suffix "dc=linuxkoubou,dc=com" --attr employeeNumber
タスクの進行状況は以下のコマンドで確認できます。
dsconf localhost task list
「Finished」になれば完了です。
これで、(employeeNumber=12345) という検索が一瞬で終わるようになります。
💡 プロのノウハウ:System Index
objectClass や entryUUID などのシステム属性は、システムインデックスとして管理されています。
これらを誤って削除したり設定変更したりすると、サーバーのパフォーマンスが壊滅的になるので触らないようにしましょう。
第4章:メモリが命。キャッシュのチューニング (dbcache / entry cache)
インデックスがあっても、いちいちディスクを見に行っていたら遅いです。
データを可能な限りメモリ(RAM)に乗せるのが、データベースチューニングの基本です。
389 DSには2種類のキャッシュがあります。
1. Database Cache (nsslapd-dbcachesize)
バックエンドDB(Berkeley DB)が管理する、ページ単位のキャッシュです。
インデックスファイル(.db)やデータファイル自体をキャッシュします。
推奨値: /var/lib/dirsrv/slapd-{instance}/db/ 以下のファイルサイズの合計が入る大きさ。
![]() |
入門 モダンLinux ―オンプレミスからクラウドまで、幅広い知識を会得する 新品価格 |
2. Entry Cache (nsslapd-cachememsize)
LDAPエントリとしてパース(解凍)された状態のデータをキャッシュします。
検索結果を即座に返すために使われる、最も高速なキャッシュです。
推奨値: 全エントリを展開したサイズ(LDIFの総サイズに近い)が入る大きさ。
設定コマンド
例えば、物理メモリが16GBあるサーバーで、DBキャッシュに2GB、エントリキャッシュに4GBを割り当てる場合。
# DBキャッシュ (バイト単位: 2GB = 2147483648) dsconf localhost backend config set --db-cache-size 2147483648 # エントリキャッシュ (userRootバックエンドに対して設定) dsconf localhost backend create --suffix "dc=linuxkoubou,dc=com" --be-name userRoot --cache-mem-size 4294967296
設定変更後は、サービスの再起動が必要です。
systemctl restart dirsrv@localhost
💡 黄金比率の目安
物理メモリの全てを割り当ててはいけません。OSや他のプロセス、ファイルシステムキャッシュのために余裕を残す必要があります。
一般的には、物理メモリの 50%〜60% を389 DSのキャッシュに割り当て、残りをOSに任せるのが安全な構成です。
第5章:ログは嘘をつかない。ボトルネックの特定方法
「遅い」という感覚ではなく、数値で判断しましょう。
389 DSのアクセスログ(/var/log/dirsrv/slapd-{instance}/access)には、宝の山が埋まっています。
注目すべきパラメータ:etime
アクセスログの各行の最後にある etime は、処理にかかった時間(秒単位、小数点以下あり)を表します。etime=0.001 なら1ミリ秒で爆速ですが、etime=2.5 なら2.5秒もかかっており、問題です。
注目すべきフラグ:notes=U
ログに notes=U という記述があったら、それは「Unindexed(インデックスなし)」検索が行われたことを意味します。
これこそが遅延の犯人です。
ログ解析コマンド(ワンライナー)
「処理に1秒以上かかった検索クエリ」を抽出するコマンド例です。
grep "SRCH" /var/log/dirsrv/slapd-localhost/access | awk -F'etime=' '$2 > 1.0 {print $0}'
「インデックスなし検索(notes=U)」を抽出するコマンド例です。
grep "notes=U" /var/log/dirsrv/slapd-localhost/access
これらのログから、「どのクライアントIPが」「どんなフィルタ条件で」検索しているかを特定し、必要なインデックスを追加するか、クライアント側のアプリ設定(検索フィルタ)を修正させます。
第6章:プロの現場から。トラブルシューティング事例集
実際に私が現場で遭遇したパフォーマンス問題とその解決策を紹介します。
Case 1: 部分一致検索の乱用
現象: 住所録アプリで検索するとサーバーCPUが100%になる。
原因: アプリが (cn=*tarou*) のような「前方一致」ではなく「中間一致」検索を投げており、cn 属性に sub インデックスが設定されていなかった。
対策: cn 属性に sub インデックスを追加し、Reindexを実施。CPU負荷は数%まで低下。
Case 2: 仮想環境でのIOPS不足
現象: キャッシュは足りているのに書き込みが遅い。
原因: 仮想化基盤のストレージが遅く、トランザクションログの書き込み(fsync)がボトルネックになっていた。
対策: トランザクションログのディレクトリ(/var/lib/dirsrv/.../db)を、高速なSSDストレージ領域に移動(シンボリックリンクまたはマウント)。
Case 3: VLV (Virtual List View) の負荷
現象: GUIの管理ツールでユーザー一覧を表示すると固まる。
原因: サーバー側ソートとページング(VLV)を行うためのインデックス(Browsing Index)が生成されていなかった。
対策: VLVインデックスを作成(設定が少し複雑なので、基本的には検索フィルタで絞り込む運用を推奨)。
まとめ:パフォーマンスは「設計」で決まる
お疲れ様でした!
第7回は、389 DSのパフォーマンスチューニングについて、インデックスとキャッシュを中心に解説しました。
今回の重要ポイント:
- 遅延の最大の原因は「インデックス不足」による全件走査である。
- ログの
notes=Uとetimeを監視し、遅いクエリを特定する。 eqインデックスは必須。subは必要に応じて追加する。- 物理メモリの50%程度を目安に、DBキャッシュとエントリキャッシュに配分する。
サーバーのパフォーマンスは、ハードウェアを買えば解決するものではありません。
データの使われ方(検索クエリ)を知り、適切な索引(インデックス)を用意し、メモリ空間を有効活用する。
これこそがエンジニアの「技術力」です。
快適なレスポンスは、ユーザーへの最高のサービス提供になりますよ。
さて、サーバー側の設定はこれで完璧です。
最終回は、クライアント側の設定です。
LinuxサーバーからこのLDAPを使ってログインできるようにし、さらにホームディレクトリの自動作成なども行う統合環境を構築します。
次回、最終回(第8回)は「クライアント連携。SSSDによるオフライン認証と統合管理」です。
従来の nslcd に代わるモダンなクライアント SSSD の設定と、キャッシュによる耐障害性の向上について解説します。お楽しみに!
▼ チューニングの効果を測定する ▼
大量データを投入して検証
「おすすめVPS」
DBA・パフォーマンスエンジニアへ
「ITエンジニア転職」


コメント