15. LDAP Sync 複製

LDAP Sync 複製エンジン(Sync replication engine: 略して syncrepl)は、コンシューマに用意する複製エンジンであり、コンシューマの LDAP サーバが DIT の一部分のシャドーコピーを管理できるようにします。 syncrepl エンジンは slapd (8) のスレッドの1つとしてコンシューマに存在しています。syncrepl は複製プロバイダに接続して初期 DIT の内容をロードした後、定期的に内容の調査かタイムリな変更内容の更新を行うことにより、コンシューマ側の複製を作成/管理します。

syncrepl は複製同期プロトコルとして LDAP 内容同期 (LDAP Content Synchronization: 略して LDAP Sync)プロトコルを使います。 syncrepl は push ベースと pull ベースの両方の同期をサポートするステートフルな複製を提供し、更新履歴を使用しません。

syncrepl は同期処理用の cookie を管理/交換することにより、複製内容の状態の軌跡を保持します。 syncrepl のコンシューマとプロバイダはそれぞれ内容の状態を管理しているので、コンシューマはプロバイダの内容を調べることができ、これによりコンシューマの複製がプロバイダの最新の内容と同一になるような関係するエントリを抽出し、差分同期を行います。また、syncrepl は、複製の状態を維持していることにより、複製の適切な管理を可能にしています。コンシューマの複製は、どの同期状態であってもコンシューマ側あるいはプロバイダ側のバックアップから構築できます。 syncrepl は、コンシューマの複製を最新のプロバイダの内容と再同期化できます。

syncrepl は push ベースと pull ベースの両方の同期をサポートします。基本の refreshOnly 同期モードでは、プロバイダが pull ベースの同期を利用します。このモードでコンシューマサーバは接続を維持し続ける必要がなく、履歴情報は管理されません。定期的な調査要求を処理するためにプロバイダに要求される情報は、要求自体の同期 cookie に格納されます。 pull ベースの同期の最適化のために、syncrepl は LDAP Sync プロトコルの存在フェーズと削除フェーズを利用し、頻繁な再ロードに頼ることはしません。 pull ベースの同期をさらに最適化するために、プロバイダは履歴の記録としてスコープ単位のセッションログを管理できます。同期の refreshAndPersist モードでは、プロバイダが push ベースの同期を使います。このモードでプロバイダは、永続検索を要求するコンシューマサーバとの接続を維持し、プロバイダの複製対象が更新された場合に必要な更新情報をコンシューマサーバに送ります。

syncrepl を使えば、コンシューマサーバはプロバイダサーバの設定変更も再起動も無しに複製を作成できます。ただし、コンシューマサーバは、DIT のうちの複製対象に対して適切なアクセス権を持っている必要があります。また、コンシューマサーバは、プロバイダ側の変更も再起動も無しに複製を停止できます。

syncrepl は部分複製も疎(sparse)複製の両方をサポートします。複製対象は、ベース、スコープ、フィルタ、属性リストから成る一般的な検索条件によって定義されます。また、複製は syncrepl 複製接続の bind で用いる利用者 ID が持つアクセス権限にしたがいます。

15.1. LDAP Content Synchronization プロトコル

LDAP Sync プロトコルは DIT の断片の同期化された複製をクライアントが保守できるようにします。 LDAP Sync 操作は、LDAP 検索操作を拡張する制御その他のプロトコル要素のセットとして定義されています。この節では、LDAP Content Sync プロトコルについて簡略に説明します。より詳しくは Internet Draft の For more information, refer to the Internet Draft The LDAP Content Synchronization Operation <draft-zeilenga-ldup-sync-05.txt> を参照してください。

LDAP Sync プロトコルは polling と listening の2つの変更をサポートし、それぞれの同期操作を定義しています。その同期操作とは refreshOnlyrefreshAndPersist です。 polling は refreshOnly 操作により実現します。クライアントの複製は polling の時間にサーバの複製対象と同期化します。サーバは、検索操作を終了するのに通常の検索と同様に SearchResultDone を返します。listening は refreshAndPersist 操作により実現します。現状で検索条件に一致するエントリすべてを返した後、同期検索を終了するのではなく、サーバで継続させます。その後でサーバの同期対象に更新があると、追加の更新エントリがクライアントに送られます。

refreshOnly 操作と refreshAndPersist 操作のリフレッシュステージは、存在フェーズまたは削除フェーズで実行されることがあります。

存在フェーズでサーバは検索スコープ内で直前の同期から更新されたエントリをクライアントに送ります。サーバは、更新されたエントリ中のすべての要求属性と、それが更新されたか否かを送ります。スコープ中の更新されていないエントリについて、サーバはエントリ名と状態が存在であることを示す同期制御から成る存在メッセージを送ります。存在メッセージではエントリの属性に関する情報を送りません。クライアントは更新と存在のメッセージを受け取った後、サーバに追加されたエントリを加え、サーバで更新されたエントリを置換し、更新されていながサーバに存在しないエントリをクライアントから削除することによりクライアントの新しいコピーを確定します。

削除フェーズにおいて、更新されたエントリの転送は存在フェーズと同様です。サーバは検索スコープ内で直前の同期から更新されたエントリの要求された属性をクライアントに送ります。しかし、削除フェーズでは検索スコープ内で削除されたエントリについて削除メッセージを送ります。削除メッセージはエントリ名と削除状態を示す同期制御から成ります。新しいクライアントコピーは、 SearchResultEntry メッセージに付加した同期制御にしたがってエントリを追加、更新、削除することにより確定します。

LDAP Sync サーバが更新履歴を管理していて、クライアントコピーから除外するエントリを判定できるのであれば、サーバは削除フェーズを使います。サーバが更新履歴を管理していなくて、更新履歴からは除外するエントリを判定できるない場合、もしくは更新履歴がクライアントの期限切れの同期状態を扱わない場合、サーバは存在フェーズを使います。存在フェーズの利用は、同期のトラフィックに関していえば完全な内容のリロードに比べてかなり効率的です。さらに同期のトラフックを減らすために、 LDAP Sync プロトコルは、entryUUID を正規化して転送したり、単一の syncIdSet メッセージで複数の entryUUID を転送するといった最適化も実現しています。

refreshOnly 同期の終了時にサーバは、同期が完了した後のクライアントコピーの状態を示すものとして同期 cookie をクライアントに送ります。クライアントは次の同期をサーバに要求するときに、受信した cookie を提示します。

refreshAndPersist 同期を利用する場合、サーバは TRUE refreshDone の Sync Info メッセージを送ることによるリフレッシュステージの終了で同期 cookie を送ります。また、同期検索の永続ステージで生成する SearchResultEntry に同期 cookie を付加して送ります。永続ステージの間、サーバがクライアントサイドの状態を更新したい時点で、サーバは同期 cookie を含んだ Sync Info メッセージを送ることもできます。サーバはまた、永続ステージの終了時にクライアントの同期状態を更新します。

LDAP Sync プロトコルにおいて、エントリは entryUUID 属性値で一意に識別されます。これはエントリの信頼できる識別子として機能します。一方でエントリの DN は経時変化する可能性があるので信頼できる識別子とは認められません。entryUUID は、同期制御の一部として個々の SearchResultEntrySearchResultReference に付加されます。

15.2. syncrepl の詳細

syncrepl エンジンにおいては、LDAP Sync プロトコルの refreshOnlyrefreshAndPersist 操作の両方とも利用できます。データベース定義に syncrepl の指定があれば、slapd (8) は syncrepl エンジンを slapd (8) スレッドとして起動し、その実行をスケジューリングします。 refreshOnly 操作が指定されていれば syncrepl エンジンは同期操作が完了した後に指定の時間間隔で再スケジュールを行います。 refreshAndPersist 操作が指定されていれば、エンジンは動作し続け、プロバイダからの永続同期メッセージを処理します。

syncrepl エンジンにおいては、リフレシュ同期の存在フェーズと削除フェーズのの両方とも利用できます。プロバイダサーバにはスコープ単位のセッションログを設定でき、複製対象から削除された有限個のエントリの entryUUID を記録します。単一のプロバイダ内容に対する複数の複製については同じスコープ単位のセッションログを共有します。 syncrepl エンジンは、このセッションログが存在し、コンシューマサーバの状態が、直前のクライアントの同期後、セッションログのエントリが切捨てられていない程度に十分に新しい場合、削除フェーズを使います。 syncrepl エンジンは、複製対象についてセッションログを設定していない場合、またはコンシューマの複製がセッションログでカバーできないほど古い場合に存在フェーズを使います。セッションログの現在の仕様では情報をメモリに記録するので、セッションログの情報は、複数回のプロバイダ起動の間で引き継がれるようにはなっていません。現在のところ、セッションログに記録されている情報への LDAP 操作でのアクセスはサポートしていません。また、セッションログに対するアクセス制御もサポートしていません。

さらに最適化するために、同期検索がどのセッションログとも関連づけられていない場合であっても、複製対象に何も更新がなければコンシューマサーバにはエントリを何も転送しません。

コンシューマ側の複製エンジンである syncrepl エンジンは、どのバックエンドでも動作できます。 LDAP Sync プロバイダは、どのバックエンドのオーバレイとしても設定できますが、back-bdb または back-hdb バックエンドで利用するのが一番です。back-ldbm バックエンドではロックの仕組上の制限から refreshAndPersist モードをサポートできません。

LDAP Sync プロバイダは各データベースについて、プロバイダの複製対象の現在の同期状態を示すものとして contextCSN を管理しています。 contextCSN の値は、プロバイダの複製対象の中でこれより小さな entryCSN の値を持つエントリに関してトランザクションが未処理で残っていないことを示します。 contextCSN は最後に発行された entryCSN に設定されるわけではありません。なぜなら entryCSN はトランザクションが開始する前に獲得され、この発行順にトランザクションがコミットされるわけでもないからです。

プロバイダは、複製対象の contextCSN を複製対象の最上位エントリの contextCSN に格納します。変更操作のたびに、この属性についてデータベースを変更するわけではなく、ほとんどはメモリ上で管理します。データベースの開始時にプロバイダは保存されていた contextCSN をメモリに読み込み、以後は排他的にメモリ上のものを利用します。デフォルトでデータベースへの contextCSN の書込みは、サーバが正常に終了するまで行われません。 contextCSN をもっと多くデータベースに書き込みたい場合には、チェックポイント機能があります。

起動時にプロバイダが contextCSN を読み込めなかった場合には、この値を求めるためにデータベース全体を走査するので、巨大なデータベースでは長い時間を要します。 contextCSN の値を読み込んだ場合でも、データベースはその値よりも大きな entryCSN の値を走査し、contextCSN の値がデータベース中の最大の entryCSN に反映しているかを確認します。不等索引をサポートしているデータベースでは entryCSN に eq 索引を設定し、contextCSN のチェックポイントを設定しておけば走査ステップを大幅にスピードアップできます。

データベースの読込みや走査で contextCSN を決定できない場合には新しい値を生成します。また、contextCSN 属性に記録されていた値よりも大きな entryCSN がデータベースの走査で見つかった場合にも、チェックポイントは直ちに新しい値を書き込みます。

コンシューマはまた、同期 cookie として受信したプロバイダの複製状態である contextCSN を、suffix であるエントリの contextCSN 属性に格納します。この複製状態はコンシューマサーバで管理され、次にプロバイダサーバと増分同期を行うときに同期状態を示すものとして使われます。これはまた、多段の複製設定で第2プロバイダサーバとして機能する場合にプロバイダ側の同期状態として使われます。コンシューマとプロバイダの状態の情報が、同じ場所のそれぞれのデータベースで管理されるため、どのコンシューマも特別な処置をすることなく、プロバイダに昇格できます。

syncrepl の設定では一般的な検索フィルタを指定するので、コンテキスト中のいくつかのエントリは同期内容から失われる可能性があります。そこで syncrepl エンジンは、複製対象の一部に穴がある場合に、グルー(glue)エントリを生成して穴を埋めます。グルーエントリは ManageDsaIT 制御が与えられていない場合には検索の結果に返りません。

syncrepl 仕様では検索フィルタを使うことから、たとえプロバイダでエントリが削除されていなくても、エントリが移動して複製範囲から外れていることがありえます。論理的にはコンシューマの該当するエントリを削除しなければなりませんが、 refreshOnly モードでプロバイダがこのような変更を検出してコンシューマに伝えるにはセッションログの利用が必要です。

15.3. syncrepl の設定

syncrepl はコンシューマ側の複製エンジンであるので、 syncrepl に関する指定はコンシューマサーバの slapd.conf (5) に設定し、プロバイダサーバには設定しません。複製内容の初期ロードを行うには、同期 cookie 無しで syncrepl エンジンを起動するか、プロバイダでバックアップとしてダンプされている LDIF ファイルをコンシューマに追加して降格します。

バックアップをロードする場合、バックアップしてあるプロバイダの内容は最新のものでなくてもかまいません。syncrepl エンジンは初期のコンシューマの複製をプロバイダの内容と自動的に同期します。したがって、内容のバックアップとロードの処理の間に更新が入って矛盾が発生するのを避けるために、プロバイダサーバを停止する必要はありません。

大規模なディレクトリを複製する場合、特に帯域幅が制限された環境においては、syncrepl を使った完全初期ロードよりも、バックアップからコンシューマ複製をロードするほうを勧めます。

15.3.1. プロバイダ slapd の設定

プロバイダはオーバレイとして実装されているため、プロバイダとして利用するためには、まずこのオーバレイ自体の設定を slapd.conf (5) に行わなければなりません。プロバイダの設定ディレクティブは2つだけであり、 contextCSN のチェックポイントを設定するものと、セッションログを設定するものがあります。 LDAP Sync 検索はアクセス制御に従うので、複製される内容について適切なアクセス権を設定しておきます。

contextCSN のチェックポイントは次のディレクティブで設定します。

        syncprov-checkpoint <ops> <minutes>

チェックポイントを行うかは書込み操作が成功した後でのみ判断します。直前のチェックポイントから <ops> 回の操作が実行されているか、 <minutes> 分が経過していれば、新しいチェックポイントが実行されます。

セッションログは次の形式のディレクティブで設定します。

        syncprov-sessionlog <size>

このディレクティブの <size> はセッションログに記録できるセッションログエントリの最大数です。セッションログが設定されていれば、データベースに対する LDAP Sync 検索で自動的に利用されます。

セッションログの利用は entryUUID の検索を必要とします。この属性に eq 索引を設定しておけば、プロバイダのセッションログの性能を大幅に改善します。

slapd.conf のプロバイダのより完全な設定例を以下に示します。

        database bdb
        suffix dc=Example,dc=com
        rootdn dc=Example,dc=com
        directory /var/ldap/db
        index objectclass,entryCSN,entryUUID eq

        overlay syncprov
        syncprov-checkpoint 100 10
        syncprov-sessionlog 100

15.3.2. コンシューマ slapd の設定

syncrepl 複製では、slapd.conf (5) のデータベースセクションで複製対象を設定します。 syncrepl エンジンはバックエンドに依存していないので、データベースの種類によらず定義が可能です。

        database hdb
        suffix dc=Example,dc=com
        rootdn dc=Example,dc=com
        directory /var/ldap/db
        index objectclass,entryCSN,entryUUID eq

        syncrepl rid=123
                provider=ldap://provider.example.com:389
                type=refreshOnly
                interval=01:00:00:00
                searchbase="dc=example,dc=com"
                filter="(objectClass=organizationalPerson)"
                scope=sub
                attrs="cn,sn,ou,telephoneNumber,title,l"
                schemachecking=off
                bindmethod=simple
                binddn="cn=syncuser,dc=example,dc=com"
                credentials=secret

上記の例で、コンシューマは、プロバイダ slapd ldap://provider.example.com にポート 389 で接続し、1日に1度 polling モード(refreshOnly)の同期を行います。バインドは簡易認証で行い、その際の DN は cn=syncuser,dc=example,dc=com でパスワードは "secret" です。 cn=syncuser,dc=example,dc=com のアクセス権は、複製対象を期待するどおりに取得するために、プロバイダに適切な設定にしておかなければなりません。また、プロバイダに対する検索に関する制限は、要求した内容を完全に取り込めるよう十分に大きくしておく必要があります。コンシューマは自分のデータベースへの書込みに rootdn を使うので、あやゆる書込みに対して全権限を持ちます。

上記の例での同期検索は、dc=example,dc=com をベースとしたサブツリー全体に対し、objectClass が organizationalPerson であるエントリを検索します。取得する属性は cn, sn, ou, telephoneNumber, title, l です。スキーマ検査は無効にしてあるので、コンシューマ slapd (8) はプロバイダ slapd (8) から得た更新情報の処理時にエントリのスキーマ検査を行いません。

syncrepl ディレクティブについてより詳しい説明は、この管理者ガイドの slapd の設定ファイルの章にある syncrepl の節を参照してください。

15.3.3. プロバイダとコンシューマの slapd の起動

プロバイダ slapd (8) は再起動の必要がありません。 contextCSN は必要に応じて自動的に生成されます。つまり、元々 LDIF ファイルに含まれていることもあれば、 slapadd によって生成されることもあり、内容の変更時に生成されることも、プロバイダに対する LDAP Sync 検索で生成されることもあります。 contextCSN を持たない LDIF ファイルをロードする場合には、 slapadd (8) コマンドに -w オプションを指定して contextCSN が生成されるようにしてください。これにより、サーバの最初の起動が少し速くなります。

コンシューマ slapd (8) を起動する時には、同期 cookie をコマンドラインオプション -c cookie で与えることができ、これにより特定の状態から同期を開始できます。この cookie には name=value のペアをカンマで区切ったリストを指定します。現在のところサポートしている syncrepl cookie フィールドには csn=<csn>rid=<rid> があります。 <csn> はコンシューマ複製の現在の同期状態を表します。 <rid> はコンシューマサーバ内のコンシューマ複製を識別するためのものです。これは、slapd.conf 内の syncrepl 指定から、同じ複製 ID を持った ものを cookie と関係づけるために利用されます。 <rid> は3桁以内の十進数を持ちます。コマンドラインに指定した cookie は、コンシューマ複製データベースに格納された cookie に優先します。