Perforceのパフォーマンス調整
Perforceサーバは、通常、システムリソースをあまり多く消費しません。ただし、システムの規模が拡大するにつれ、あらためてシステム構成を見直し、最適なパフォーマンスが得られる構成になっているかどうか確認する必要が生じます。
この章では、Perforceサーバのパフォーマンスに影響するおそれのあるいくつかの要因について簡潔に概説するとともに、ネットワーク関連障害の原因追究に役立つ情報を提供し、システムの大型化に起因するサーバ負荷を軽減する方法を説明します。
パフォーマンスを調整する
一般に、Perforceはいかなるサーバクラスのハードウェアプラットフォームにおいても良好なパフォーマンスを発揮します。以下に、Perforceサーバのパフォーマンスに影響するおそれがある要因を示します。
メモリ
サーバのパフォーマンスは、メモリが十分に確保されているかどうかに大きく依存します。これには2つの問題があります。第1の問題を回避するには、大量のクエリを実行中のサーバにページングをさせないようにします。第2の問題を回避するには、db.rev
テーブル(またはそのうち少なくとも実際に使用する分量)がメインメモリにキャッシュされるようにします。
-
大量のクエリの実行に必要なメモリ容量は、簡単に割り出せます。サーバがページングしないようにするには、1ファイルにつき1KBのRAMが必要です。10,000ファイルある場合には、10MBのRAMが必要です。
-
db.rev
をキャッシュするには、既存のインストレーションのdb.rev
ファイルのサイズを確認し、1つの目安として利用すればよいでしょう。新しくインストレーションのPerforceでは、db.rev
は1リビジョンにつき150~200バイトを必要とします。概算のために1ファイルにつき3リビジョンとした場合、1ファイルにつき0.5KBのRAMが必要です。
したがって、1ファイルにつき1.5KBのRAM(100,000ファイルに対して150MBのRAM)が利用可能であれば、たとえすべてのファイルに関わる動作を実行しても、サーバはページングを行いません。もちろん、大規模な動作が複数同時に実行される可能性もありますから、ページングを回避するにはより多くのメモリが必要です。ただし、大多数の動作では、小規模なサブセットのファイルしか使用しません。
通常のインストレーションの場合、ディポの中で1ファイルにつき1.5KBのRAMがあれば十分です。
ファイルシステムのパフォーマンス
Perforceは、ディスクI/Oの使用に関して優れています。使用しているメタデータは検索しやすいうえに、データへアクセスする際には概してデータのなかでも限られたサブセットを順番にスキャンするという方法をとります。ディスクにもっとも負担がかかる動作はファイルのチェックインです。Perforceサーバがアーカイブのファイルの書き込みとリネームをしなければならない場合です。サーバのパフォーマンスは、オペレーティングシステムのファイルシステム実装に依存しており、とくに、ディレクトリの更新が同期式であるかどうかによって大きく左右されます。また、サーバのパフォーマンスは、基盤を成すハードウェアのI/Oサブシステムの性能にも大きく左右されます。
Perforceが特定のハードウェア構成やファイルシステムを推奨することはありません。とはいえ、Linuxサーバは(Linuxの非同期的ディレクトリ更新のおかげで)概して最も速く動作しますが、不適切なタイミングで電源が切れると、復旧に手間取ることがあります。それに比べると、(Solarisでも使用されている)BSDファイルシステムの動作は遅いですが、より信頼できます。NTFSのパフォーマンスは、LinuxとBSDの間の範囲に落ち着きます。
データベースとバージョンファイルがNFSマウント済みボリュームに保存されている場合、システムのパフォーマンスは、通常そのNFSの実装か、その基盤を成すストレージハードウェアに依存します。PerforceはSolarisのNFS環境でテストされ、サポートされています。
LinuxおよびFreeBSD上では、ファイルロッキングが比較的遅いので、NFSを介するデータベース更新に問題が生じるおそれがあります。これらのプラットフォーム上では、ジャーナルがNFSマウントされている場合、すべての動作が遅くなります。一般に(LinuxやFreeBSDでは特に)、Perforceのデータベース、ディポ、ジャーナルのファイルを、Perforceサーバプロセスを実行するマシンのローカルディスク上に保存することを推奨します。
上記の問題は、Perforceサーバプロセス(p4d)のみに影響します。Perforceアプリケーション(p4、Perforceコマンドラインクライアントなど)は、これまで常に、ユーザのホームディレクトリ中のクライアントワークスペースなどの、NFSマウント済みドライブ上のクライアントワークスペースでの稼働実績を挙げてきています。
ディスク容量の割り当て
Perforceが使用するディスク容量は、以下の3つの要素に依存します。
-
クライアントワークスペースの数とサイズ
-
サーバデータベースのサイズ
-
サーバ上にあるすべてのバージョン化ファイルのアーカイブのサイズ
以上の3つの要素すべてが、使用中のデータの性質と、Perforceの使用度によって変わります。
必要なクライアントファイルスペースは、ユーザが任意の時点でクライアントワークスペース内に必要とするファイルのサイズと一致します。
サーバのデータベースサイズはかなりの精度で計算できます。推定で、1ユーザ1ファイルにつき0.5KB必要です。(例えば、1つのシステムにファイルが10,000個あり、ユーザが50人いれば、データベースに250MBのディスク容量が必要です。)データベースは、時間の経過とともに個々のファイルの履歴が増加するにつれて、規模を増していくことが予想されます。
サーバにあるバージョン化ファイルのアーカイブのサイズは、保存されているオリジナルファイルのサイズに依存するので、リビジョンの増加に応じて規模を増していきます。大多数のサイトでは、少なくともオリジナルファイルのサイズの3倍にあたるディスク容量を割り当てておきましょう。
db.have
ファイルには、クライアントワークスペースで作業状態になっているファイルのリストが記録されています。したがってこのファイルのサイズはデータベース内の他のファイルと比べて急速に増大していく傾向があります。db.have
ファイルのサイズに関する問題に直面しており、かつ大きなファイルを適切にサポートしているサーバにすぐに切り換えられない場合、使っていないクライアントワークスペース仕様を削除することでクライアントワークスペースのビューの範囲を狭めると、問題を多少改善できることがあります。
ディスクの空き容量を監視する
ディスク空き容量を監視するには、p4 diskspaceコマンドを使用します。デフォルトでは、p4 diskspaceを実行すると、ディスクの空き容量、使用中の容量、およびPerforceによって使用されるファイルシステムの総容量が表示されます。
デフォルトでは、P4ROOT
、P4JOURNAL
、P4LOG
、TEMP
を保持するファイルシステムの空き容量が10MBを下回ると、Perforceサーバがコマンドを受け付けなくなります。この動作を変更するには、filesys.P4ROOT.min
構成可能変数(およびその他の関連する構成可能変数)に、希望の上限値を指定してください。
構成可能変数 |
デフォルト値 |
意味 |
---|---|---|
|
10M |
サーバのルート・ファイルシステムに必要な最少ディスク空き容量。これより少なくなると、サーバはコマンドを拒否します。 |
|
10M |
サーバのジャーナル・ファイルシステムに必要な最少ディスク空き容量。これより少なくなると、サーバはコマンドを拒否します。 |
|
10M |
サーバのログ・ファイルシステムに必要な最少ディスク空き容量。これより少なくなると、サーバはコマンドを拒否します。 |
|
10M |
一時的な処理に必要な最少ディスク空き容量。これより少なくなると、サーバはコマンドを拒否します。 |
|
10M |
ディポに必要な最少ディスク空き容量。これより少なくなると、サーバはコマンドを拒否します。(1つのディポで使用できる空き容量が |
Perforceサーバプロセスを動作させるユーザアカウントにディスククオータが適用される場合、当該ファイルシステムに実際に残っている物理的な空き容量にかかわらず、filesys.*.min
構成可能変数にはそれらのクオータが反映されます。
ディポ内の特定のファイルに現在占有されているディスク容量を見積もるには、管理中のサイトのデータ保存方法で使用されるのと同じブロックサイズをp4 sizesコマンドに指定します。例えば、
p4 sizes -a -s -b 512 //depot/...
というコマンドを使用すると、ブロックサイズを512バイトとして計算した場合の、//depot/...
内にあるすべてのリビジョン(-a
)の合計値(-s
)が表示されます。
//depot/... 34161 files 277439099 bytes 5429111 blocks
p4 sizesにより報告されるデータは、実際にはファイルとクライアントワークスペースの同期に必要なディスク容量を反映しているのですが、それでもサーバ側でのディスク使用量の概算として参考にすることができます。
ネットワーク
PerforceはTCP/IPネットワーク上で動作可能です。ネットワークの制約はまだ見つかっていませんが、帯域幅が広くなるほど動作は良好になるでしょう。
Perforceは各クライアントとサーバの通信にTCP/IP接続を使用します。サーバのポートアドレスはP4PORT
で定義されますが、クライアントのポート番号はTCP/IPによって決められます。コマンドが完了して接続が閉じると、ポートはその後2分間にわたってTIME_WAIT
という状態になります。ポート番号は1025
から32767
までの範囲に及びますが、ふつう数100から数1000の番号だけが同時に使用される可能性があります。したがって、例えばスクリプトを使用してPerforceコマンドを何度も立て続けに呼び出すと、使用可能なポートがすべてふさがれる可能性があります。
デフォルトでは、アイドル接続中のキープアライブは行われません。ネットワークによってアイドル接続がサイレントに切断されると、その動作が原因となって想定外の接続の問題が発生するおそれがあります。(p4 pullスレッドがマスターサーバとリモートサイトのレプリカとの間でデータを転送する場合に注意しましょう。この場合、各サイトの営業時間やユーザの作業負荷しだいでは、1日に数時間にわたるアイドル接続が発生する可能性があります。)以下の4つの構成可能変数を使用して、アイドル接続の状態を管理することができます。
構成可能変数 |
デフォルト値 |
意味 |
---|---|---|
|
0 |
ゼロ以外を指定すると、TCPキープアライブパケットの送信が無効になります。 |
|
0 |
キープアライブパケットの送信を開始するまでのアイドル時間(秒)です。 |
|
0 |
キープアライブパケットの送信間隔(秒)です。 |
|
0 |
キープアライブパケットが確認されなかった回数がこの構成可能変数に指定された数を超えると、接続失敗と判断されます。 |
ネットワーク構成でキープアライブパケットが必要な場合は、例えば3600秒(1時間)や数十分単位の間隔など、適切な長さの値をnet.keepalive.idle
に指定してください。
CPU
Perforceバージョン化サービスは、CPUのリソース消費量という観点からいえば、比較的軽量です。通常、Perforceサーバのインストール先プラットフォームを決定する際に、CPUの処理能力が主な懸案事項となることはありません。
ロックなしの読み取りを使用して同時並行処理を改善する
リリース2013.3よりも前のリリースでは、データベースからデータのみを読み取るコマンドを呼び出すと、1つ以上のデータベーステーブルがロックされて読み取り専用になります。他のコマンドは同時にテーブルからデータを読み取ることができますが、任意のコマンドが読み取り専用にロックされたテーブルに書き込みを試みると、ロックの解除後に書き込みを開始できるようになるまで強制的に待機させられます。現在、デフォルトでは、一部のコマンドで、前述のようなテーブルをロックせずに読み取ることができるようになっています。この動作と引き換えに一貫性や独立性が損なわれることはありません。この機能により、前述のようなテーブルに対して、読み取り専用ロックが解除されるまで書き込み操作を保留するのではなく、書き込みを即座に実行できるようになったため、パフォーマンスが大幅に改善されています。
Note
ロックなしの読み取り操作を実行するには、サーバロックを有効にしておく必要があります。この機能は長期にわたる同期に関する問題を引き起こすおそれがあるので、「sync」サーバロック(server.locks.sync
)を制御するためのデフォルト値は、現在デフォルトでは無効になっています。
Perforceサーバでロックなしの読み取りに関する設定を変更するには、p4 configure set
db.peeking=N
コマンドを使用します。
db.peeking
に変更を加えると、いかなる変更でもそれを有効にするには、サーバを再起動する必要が生じます。
db.peeking
に指定できる値は以下のとおりです。
|
意味 |
---|---|
|
この動作は、Perforceリリース2013.2以前の動作と一致します。 |
|
この構成は、主に障害の原因追究のために使用されます。 |
|
この構成により、大半のサイトで最良のパフォーマンス結果が得られることが期待されます。これがデフォルト値です。 |
|
この構成にすると、同時並行処理は改善されますが、コマンド完了速度が低下します。通常、リポジトリが1ファイルにつき多数のリビジョンを有している場合、 |
ロックなしの読み取りを実装しているコマンド
ピーキングが有効になっている場合、以下のコマンドは読み取り専用ロックなしで実行されます。
コマンド |
備考 |
---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
files -aに適用 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
sizes -aに適用 |
|
|
|
print -aに適用 |
|
|
|
|
|
以下のコマンドは一定条件下ではロックなしで動作します。大半の場合これらのコマンドは対象ファイルをロックせずに読み取りますが、いつも必ずロックなしで動作するという保証はありません。
コマンド |
備考 |
---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
デフォルトの動作をオーバーライドする
db.peeking
設定をコマンド単位でオーバーライドすることができます。それには、-Zpeeking=
フラグを使用し、その後に任意の値を指定します。例えば、1つのコマンドのピーキングを無効にするには、以下のコマンドを実行します。
p4 -Zpeeking=1 fstat
そして以下の結果と比較します。
p4 -Zpeeking=2 fstat
ロックなしの読み取りによる効果を計測する
読み取り専用ロックがパフォーマンスに悪影響を及ぼしているかどうか(また、ロックなしの読み取りを有効にした後でパフォーマンスがどれほど改善したか)判断するには、サーバログを検証するか、任意のコマンドに対し-Ztrack
フラグを使用してP4LOG
に書き込まれたはずの行を出力するとよいでしょう。例:
p4 -Zpeeking=1 -Ztrack sync
以上によって、11のデータベーステーブルの出力が生成されます。ここで重要な行は「locks read/write
」を呼び出している行です。
... --- db.counters --- pages in+out+cached 3+0+2 --- locks read/write 1/0 rows get+pos+scan put+del 1+0+0 0+0 --- db.user --- pages in+out+cached 3+0+2 --- locks read/write 1/0 rows get+pos+scan put+del 1+0+0 0+0 ...
(「locks read/write
1/0
」)各テーブルのロック結果に現れている1
は、1つのテーブルにつき1つの読み取り専用ロックがかかっていることを示しています。これに対して、
p4 -Zpeeking=2 -Ztrack sync
... --- db.counters --- pages in+out+cached 3+0+2 --- locks read/write 0/0 rows get+pos+scan put+del 1+0+0 0+0 ...
からの診断出力は、db.counters
で必要な読み取り専用ロックも書き込み専用ロックも行われることなく同期操作が完了したことを示しています。ピーキングを有効にしておくと、多数のコマンドでread/write 0/0
ロックがかかっていること(あるいは少なくとも、ほとんどロックがかかっていなかったこと)がわかるでしょう。
サイドトラックサーバでは、db.peekingレベルを同一の設定にしておく必要があります。
単一のPerforceインスタンスは、db.peeking
を意図せずオーバーライドする不適切な試行を検出し、無視します。そのような試行がテーブルロック方式を変更することによりデッドロックの危険を生むおそれがあるためです。(例えば、db.peeking
に0を指定する(または値を指定せずにいる)ことでピーキングを無効にしているサーバに対し、db.peeking=3
の使用を試行すると、サーバはその試行を完全に無視し、コマンドは古い方式で実行されます。)
以下のナレッジベース記事で説明している「サイドトラックサーバ」の場合、
http://answers.perforce.com/articles/KB_Article/Perforce-Metadata-Replication
このプロテクションは使用できません。
Warning
すべてのサイドトラックサーバでは、db.peeking
の設定をメインサーバと同一の設定にしておく必要があります。さもなければ、サーバのデッドロックが発生するおそれがあります。
応答時間の遅延の原因を突き止める
通常、Perforceはネットワークリソースをあまり使用しません。ユーザが極端に大規模な操作を行った場合にPerforceサーバの応答が遅延する可能性はありますが、p4コマンドに対する応答がずっと遅れている場合、その原因はたいていネットワークの問題にあります。応答時間の遅延を引き起こす可能性があるのは、以下のうちいずれかです。
-
ドメインネームシステム(DNS)構成の誤り
-
Windowsネットワークキング構成の誤り
-
ネットワーク化されたファイルシステム上で発生しているp4実行ファイルへのアクセス障害
まず行うべきテストは、p4 infoの実行確認です。それに対する応答が即座に得られない場合、ネットワークに問題が発生しています。ネットワークの問題を解決することはこのマニュアルの対象外ですが、以下に若干のトラブルシューティングのヒントを紹介しておきます。
ホスト名をIPアドレスに変えてみる
P4PORT
に、サービスのホスト名ではなくサービスのIPアドレスを指定してみます。例えば、
P4PORT=host.domain:1666
とする代わりに、
P4PORT=1.2.3.4:1666
などと、サイト特定のIPアドレスとポート番号を指定してみてください。
大半のシステムでは、以下のコマンドを使用するとホストのIPアドレスを特定できます。
ping hostname
p4 infoがIPアドレスの使用時に即座に応答する一方で、ホスト名の使用時に即座に応答しない場合は、問題はDNSに関連している可能性があります。
Windowsのワイルドカード
Windows上でp4コマンドを使用すると、ある条件の下では応答時間の遅延が生じるおそれがあります。その条件とは、そのコマンドがディポシンタックスとワイルドカードの組み合わせから成るファイルパターンを使用していること、かつそのファイルパターンが引用符で囲まれていないことです。
p4 files //depot/*
以下のようにファイルパターンの前後を二重引用符で囲むことによって、遅延を防ぐことができます。
p4 files "//depot/*"
この問題の原因は、p4コマンドがWindowsのワイルドカード拡張機能を使用することにあります。二重引用符を使用しなければ、この機能は//depot
をネットワーク接続されたコンピュータのパスとして解釈するので、depot
というマシンの検索のために時間をむだに使ってしまうことになります。
DNSルックアップとホストファイル
Windowsでは、%SystemRoot%\system32\drivers\etc\hosts
ファイルを使用して、IPアドレスホスト名のホスト名の組み合わせをハードコード化することができます。このファイルへのエントリを追加することによって、DNSの問題を回避することができます。これに対応するUNIXファイルは、/etc/hosts
です。
p4実行ファイルの場所
以上の原因追究の手順をすべて試しても応答時間の遅延の原因を明らかにできない場合は、p4の実行ファイルそのものが、きわめてパフォーマンスの低いネットワークファイルシステム上に存在している可能性があります。この可能性を確認するには、以下のコマンドを試行してください。
p4 -V
これは、ネットワークアクセスを試みずにただバージョン情報を出力するだけのコマンドです。応答が遅延する場合、問題はp4実行ファイルそのものへのネットワークアクセスにある可能性があります。ローカルのファイルシステムにp4のコピーを作成するかダウンロードすると、応答速度が向上するはずです。
信頼性の低いネットワークでの作業
ネットワーク上の個々の読み取りまたは書き込みを待機する接続時間に上限を設定するには、ネットワークエラーとして接続を切断するまでに待機する秒数を構成可能変数net.maxwait
に設定します。信頼性の低い接続状態で作業するユーザは、net.maxwait
をP4CONFIG
ファイル内で設定するか、-vnet.maxwait=
をコマンド単位で使用し、タイムアウトのまでの待機秒数をt
t
に指定するとよいでしょう。
Note
net.maxwait
をPerforceサーバ上に設定することもできますが、通常はそうしないことを推奨します。例えば、サーバ上でnet.maxwait
に60を指定すると、コマンドラインクライアントのユーザは対話式フォームへの入力を1分以内に完了しなければなりません。そうしなければコマンドがタイムアウトしてしまいます。これに対して、各ユーザが各自の(ワークステーション内の)P4CONFIG
ファイルのなかでnet.maxwait
を設定すると、そのユーザの接続は上記の制限の対象にはなりません。バージョニングサービスがリクエストに対する応答に60秒を超える時間を要した場合のみ、コマンドが失敗します。
net.maxwait
をグローバルオプションである-rN
と組み合わせて、ネットワークのタイムアウト時に再接続を試行する回数をN
に指定すると便利です。例:
p4 -r3 -vnet.maxwait=60 sync
というコマンドは、ユーザのワークスペースの同期が中断された場合に、同期を3回まで再試行します。3回目に60秒間でタイムアウトすると、コマンドは失敗します。
タイムアウトして再試行されるコマンド(ネットワーク接続が出力行の途中で失われた場合など)の出力形式は保証されないため、標準入力から読み込みを行うコマンドに-r
を使用するのは避けてください。例えば、以下は、標準入力からファイルのリストを読み込み、それをp4 addに送るコマンドです。このコマンドの動作の結果として、中途半端な名前のファイルをディポに追加する操作が試みられるおそれがあります。
find . -print | p4 -x - -r3 add
(例えば、信頼性が極めて低い接続状態でファイルを多数追加しなければならない状況で)このような現象を回避するには、以下のようなアプローチを検討してください。
find directoryname
-type f -exec p4
-r5 -vmax.netwait=60 add {} \;
このコマンドは、directoryname
内のすべてのファイル(-type f
)を検出したうえで、個々のファイルに対して「p4 -r5 -vmax.netwait=60
add」コマンドを実行することでファイルを1つずつ追加します。
すべてのファイルが追加されたら、p4 changeを使用してチェンジリストにチェンジリスト番号を割り当て、番号付きチェンジリストを最小単位でサブミットします。
p4 -r5 -vmax.netwait=60 submit -c
changenum
接続が中断されると、番号付きチェンジリストのサブミットは再試行されます。
サーバの停滞を防止する
通常、Perforceのパフォーマンスは、ディポのサイズにではなく、ユーザが1回のコマンド実行で処理しようとするファイルの個数に左右されます。言い換えれば、3,000,000個のファイルを持つディポのうち30個のファイルのクライアントビューを同期するのにかかる時間は、30個のファイルを持つディポのうち30個のファイルのクライアント・ビューを同期するのにかかる時間と比べて、それほど長くはならないはずです。
1つのコマンドによって影響を受けるファイルの数は、おおまかにいって以下の要素によって決定されます。
-
p4コマンドラインの引数(GUI操作の場合は選択したフォルダ)
引数を使用しなければ、ほとんどのコマンドはクライアントワークスペースビュー内のすべてのファイルに対して実行されるか、さもなければ少なくともそれらすべてのファイルを参照します。
-
クライアントビュー、ブランチビュー、ラベルビュー、プロテクション
引数を指定されていないコマンドはワークスペースビュー内のすべてのファイルに対して動作するので、ビューとプロテクションに制限を設定していない場合、そのようなコマンドはディポ内のすべてのファイルに対して実行されることになります。
サーバがリクエストに応えて処理を開始すると、その間データベースをロックします。通常の操作の場合は、この方法は成功します。なぜならサーバはリクエストのバックログを十分回避できるほどすばやく入出力を行うことができるからです。しかし異常なほど大規模なリクエストの処理には、数秒から数分かかることもあります。いらいらしたユーザがCTRL+Cキーを押して再試行すると、問題はよけいに悪化してしまいます。つまり、サーバがさらにメモリを消費するので、応答がますます遅くなってしまうのです。
極めて大規模なディポを持つサイトでは、ビューの範囲を無制限にしたり、引数を指定しないでコマンドを実行すると、Perforceサーバは必要以上のリソースを消費して稼働します。ユーザと管理者は、以下の方法により、サーバにかかる負荷を緩和することができます。
-
ビューの範囲を絞り込んで使用する
-
プロテクションを割り当てる
-
maxresults
に制限をかける -
server.maxcommands
を使用して同時接続数を制限する -
使用頻度の低いメタデータをアンロードする
-
効率のいいスクリプトを作成する
-
効率よく圧縮を活用する
-
その他のサーバ構成可能変数
ビューの範囲を絞り込んで使用する
以下の「ゆるく制限されている」ビューは、簡単に設定できますが、きわめて大規模なディポでは問題を引き起こすおそれがあります。
//depot/... //workspace/...
以上のビューでは、ディポ全体がクライアントワークスペースへマッピングされていました。大半のユーザにとって、このビューは著しく「絞り込む」ことができます。例えば、以下のビューの範囲は、ディポの特定の領域に限定されています。
//depot/main/srv/devA/... //workspace/main/srv/devA/... //depot/main/drv/lport/... //workspace/main/dvr/lport/... //depot/rel2.0/srv/devA/bin/... //workspace/rel2.0/srv/devA/bin/... //depot/qa/s6test/dvr/... //workspace/qa/s6test/dvr/...
クライアントビューについてはとくに言えることですが、ブランチビューやラベルビューもまた、ユーザにとって必要な作業を行うのに十分な範囲だけを表示するように設定する必要があります。
クライアント、ブランチ、ラベルビューは、Perforce管理者または個々のユーザがそれぞれp4 client、p4 branch、p4 labelコマンドを使用することにより、設定されます。
スクリプトを最適化する方法(ブランチビューを使用するおよび一時クライアントワークスペースの活用を参照)のうち2つは、同様のテクニックに基づいています。コマンドに使用できるビューのサイズを制限することにより、実行する必要のあるコマンドの数を減らすとともに、コマンドの実行に必要なリソースの消費量も減らします。
プロテクションを割り当てる
プロテクション(“Perforceの管理: 保護”を参照)は、もうひとつのタイプのPerforceビューです。プロテクションは、p4 protectコマンドで設定され、ユーザが実行するコマンドによって影響を受けるディポファイルを制御します。
ただしクライアントビュー、ブランチビュー、ラベルビューとは異なり、プロテクションによって使用されるビューは、Perforceスーパーユーザによってしか設定できません。(プロテクションは、ディポファイルに対する読み取り権限と書き込み権限も制御しますが、権限レベルそのものはサーバのパフォーマンスに影響しません。)Perforce内でプロテクションを割り当てることにより、たとえユーザが「ゆるく制限されている」クライアント仕様を使用している場合であっても、ユーザのビューのサイズを効果的に制限することができます。
プロテクションは、以下のように、ユーザにもグループにも割り当てることができます。例:
write user sam * //depot/admin/... write group rocketdev * //depot/rocket/main/... write group rocketrel2 * //depot/rocket/rel2.0/...
Perforceグループは、スーパーユーザがp4
groupコマンドを使用することにより、作成されます。Perforceグループによって、プロテクションの割り当てが簡単になるだけではなく、次のセクションで説明するように、maxresults
およびmaxscanrows
によって便利なエラー防止メカニズムが使用できます。
データベースへのクエリを制限する
各Perforceグループには、相互に関連するmaxresults、maxscanrows、maxlocktimeという値があります。それぞれデフォルトでは、unset
(無制限)に設定されていますが、スーパーユーザは、p4 groupコマンドを用いて特定グループに対してこれらの値を制限することができます。
MaxResultsは、コマンド実行中にバッファリングされるデータの量を制限することにより、サーバがメモリを過剰に使用しないようにします。制限されたグループのユーザは、そのグループのMaxResults
の制限値より多くデータベース行をバッファリングするようなコマンドを実行することはできません。(ほとんどのサイトでは、MaxResults
を各ユーザのクライアントワークスペースで想定されるファイルの最大数よりも大きく設定する必要があります。)
MaxResults
と同様に、MaxScanRows
もサーバへ過度の要求がなされるような特定のユーザコマンドを制限します。(通常、一回の操作でスキャンされる行の数は、ディポ内のファイルの平均リビジョン数をMaxResults
に積算した数とほぼ等しくなっています。)
最後に、ある種のコマンドがデータベースを長期間にわたってロックし続けないようにするためには、MaxLockTime
を使用します。ミリ秒単位の数値でMaxLockTime
を設定し、データベースのロックを許容する最大時間を指定します。
これらの制限を設定するには、p4
groupのフォーム内の当該フィールドに数値を入力します。1人のユーザが複数のグループに登録されている場合、それらのグループのMaxResults
(またはMaxScanRows
もしくはMaxLockTime
)制限値の最大値(unlimited
を含むがデフォルトのunset
設定を除く最大値)がそのユーザのMaxResults
(またはMaxScanRows
もしくはMaxLockTime
)値とみなされます。
Example 28. maxresults、maxscanrowsおよびmaxlocktimeの動作。
管理者として、グループrocketdev
のメンバーの操作を20,000ファイル以下に、さらにスキャンを100,000リビジョン以下に、そしてデータベーステーブルを30秒以上ロックしないように制限するものとします。
Group: rocketdev MaxResults: 20000 MaxScanRows: 100000 MaxLockTime: 30000 Timeout: 43200 Subgroups: Owners: Users: bill ruth sandy
ここで、クライアントビューが無制限、loose(「ゆるい」)に設定されているルースが
p4 sync
とコマンド入力すると、ディポにファイルが20,000以上ある場合、このsyncコマンドは拒否されます。この制限を回避するには、ルースのクライアントビューを限定するか、あるいはクライントビューで全ファイルが必要であるようなら、次のようにファイルを小セットに分けて同期させます。
p4 sync //depot/projA/... p4 sync //depot/projB/...
いずれの方法でも、サーバを極端に負荷の大きい1つのコマンド処理に専念させることなく、ルースは目的のファイルを自分のワークスペースに同期させることができます。
次のように、ルースが全ファイルの全リビジョンをスキャンするようなコマンドを試行したと仮定します。
p4 filelog //depot/projA/...
このとき、ファイル数が20,000より少なく、リビジョン数が100,000より多い場合(例えば、projA
のディレクトリにファイルが1,000存在し、その各ファイルにリビジョンが20未満で、それぞれに50を超えるブランチが存在するとき)、MaxResults
の制限は適用されませんが、MaxScanRows
の制限が適用されます。
また、どちらの制限が有効であるかにかかわらず、30,000ミリ秒のMaxLockTime
を超えてデータベースをロックするようなコマンドの実行は許可されません。
特定のグループについて、結果として処理される行数(またはスキャンされるデータベースの行数、もしくはデータベースロック時間を示すミリ秒)の制限を解除するには、そのグループのMaxResults
、MaxScanRows
、またはMaxLockTime
の値をunlimited
に設定します。
これらの制限はユーザに不便を強いることになる可能性があるため、特定の操作がサーバの動作を遅くしているのでない限りは使用しないでください。Perforceアプリケーションの中には大規模な処理を行うものもあるため、通例MaxResults
の値を10,000より小さくすることはありません。また、MaxScanRows
は50,000より小さくせず、MaxLockTime
の値は1,000から30,000(1秒から30秒)の範囲内に設定します。
各Perforceコマンドで影響を受けるファイル数などの詳細については、コマンドラインで以下を実行してください。
p4 help maxresults p4 help maxscanrows p4 help maxlocktime
複数グループに含まれるユーザを対象とする場合のMaxResults、MaxScanRowsおよびMaxLockTime
前述のように、ユーザが複数のグループに登録されている場合、所属するすべてのグループのMaxResults
の制限値のうち最大値がそのユーザに適用されます。
デフォルト値unset
は数値上の制限ではありません。MaxResults
がunset
に設定されているグループに属するユーザであっても、他のグループに所属していればそのグループのMaxResults
(またはMaxScanRows
もしくはMaxLockTime
)値の最大値によって制限されます。
ユーザのコマンドが実際に無制限になるのは、そのユーザがどのグループにも属さないとき、あるいは、そのユーザが属するすべてのグループのMaxResults
がunlimited
に設定されている場合に限られます。
同時接続を制限する
監視機能が有効(p4 configure set monitor=1またはそれ以上)の場合、構成可能変数server.maxcommands
を設定して、サービスが同時に処理できるコマンド要求の数を制限できます。
理想的には、この値は、ベースとなるハードウェアリソースが過負荷になる前に暴走スクリプトやサービス不能を検出できる程度に十分低く設定すると同時に、平均接続数とサイトでのピーク処理量との間に十分なゆとりが保たれる程度に高く設定します。
P4LOG
が設定されている場合、サーバログには次の形式の行が含まれます。
Server is now using
nnn
active threads.
サーバログで、サイトにおける通常時の処理量レベルを知ることができます。一般的には、server.maxcommands
はサイトでの予想される処理量のピークの200~500%以上に設定します。
使用頻度の低いメタデータをアンロードする
時間を経るにつれ、Perforceサーバにはアクティブな開発モードでなくなった古いプロジェクトに関連するメタデータが蓄積されていきます。大規模なサイトでは、使用されるデータ群(特にdb.have
とdb.labels
テーブルに格納されたデータ)を減らすことにより、パフォーマンスを大幅に向上することができます。
アンロードディポを作成する
//unload
という名前のアンロードディポを作成するには、p4 depot unloadと入力し、表示されるフォームに次のように入力します。
Depot: unload Type: unload Map: unloaded/...
この例では、アンロードされたメタデータはサーバルートの下にある(Map:
フィールドにより指定される)/unloaded
ディレクトリ内のフラットファイルに格納されます。
このようにアンロードディポを作成した後は、p4 unloadとp4 reloadを使用して、環境内のワークスペースおよびラベルに関連するメタデータの処理方法を管理できます。
古いクライアントワークスペース、ラベル、タスクストリームをアンロードする
p4 unloadコマンドは、使用頻度の低いメタデータをバージョン化エンジンのdb.*
ファイルからアンロードディポ内のフラットファイルのセットへ転送します。
ユーザは各自-c
、-l
、-s
の各オプションを使用して、自身が所有するワークスペース、ラベル、またはタスクストリームをアンロードできます。例えば、ビルドを連続して開発する環境下で、ワークスペースやラベルを1ビルドにつき1つずつ作成するビルドスクリプトの保守担当者は、各ビルドの終了時にその都度ラベルをアンロードすることが推奨されます。
p4 unload -c oldworkspace
p4 unload -l oldlabel
同様に、開発者は使用し終えたタスクストリームをその都度アンロード(p4
unload -s oldtaskstream
)または削除(p4 stream -d
oldtaskstream
)することが推奨されます。
古くなった、または使われなくなったメタデータをまとめて管理するには、管理者は-a
、-al
、-ac
フラグを-d
および/またはdate
-u
フラグと併用します。これにより、特定のuser
date
より古いか、特定のuser
が所有する、あるいは両方の条件に該当するすべてのラベルおよびワークスペースをアンロードできます。
デフォルトでは、ロックが解除されたラベルまたはワークスペースしかアンロードされません。ロックされたラベルまたはワークスペースをアンロードするには、-L
フラグを使用します。
ワークスペースやラベルのアンロードまたはリロードを行うには、ワークスペースのhaveリストにあるすべてのファイルおよび/または当該ラベルによってタグ付けされているファイルを、ユーザがスキャンできなくてはなりません。MaxScanrows
およびMaxResults
を十分な大きさの値に設定して(複数グループに含まれるユーザを対象とする場合のMaxResults、MaxScanRowsおよびMaxLockTimeを参照してください)、ユーザがp4 unloadまたはp4
reloadの操作にサポートを要求しなくて済むようにする必要があります。
アンロードされたデータへのアクセス
デフォルトでは、p4 clients、p4 labels、p4 files、p4
sizes、p4 fstatなどのPerforceコマンドは、アンロードされたメタデータを無視します。アンロードされたワークスペースやラベル(またはアンロードされたその他のメタデータ)を調べる必要のあるユーザは、それらのコマンドの使用時に-U
オプションを使用できます。詳細については、『P4コマンドリファレンス』を参照してください。
ワークスペースとラベルをリロードする
アンロードされたメタデータをdb.have
テーブルまたはdb.labels
テーブルに戻すことが必要になった場合は、p4 reloadコマンドを使用します。
効率的なスクリプトを用いる
Perforceのコマンドラインクライアントであるp4では、対話形式で実行可能なコマンドすべてをスクリプトにより実行できます。Perforceサーバは、ユーザのコマンド発行よりもはるかに速くコマンドを処理できるため、完全な対話形式の環境では、優れた応答時間が期待できます。ただし、例えばトリガ、レビューデーモン、コマンドラッパなどのスクリプトにより発行されたp4コマンドは、スクリプトの効率を考慮していないとパフォーマンス上の問題を引き起こすことがあります。これはp4コマンドが本来非効率的だからではありません。対話形式でユーザが実行したp4が、場合によっては繰り返し操作に適したものではないためです。
このセクションでは、よくある効率上の問題とその解決法をいくつか紹介します。
ファイルに対する繰り返し
Perforceの各コマンドを発行すると接続スレッドが生じ、p4dサブプロセスが起動します。スクリプトの効率を改善する第一歩は、スクリプトによって実行されるPerforceコマンドの数を減らすことです。
スクリプトでは、各ファイルに対して同じPerforceコマンドを繰り返し実行するような記述は避けます。可能であれば常に、ファイルのリストに対して1つのPerforceコマンドを実行し、その実行結果に対して繰り返し処理を行うようにします。
例えば、より効率的な方法は以下のようになります。
for i in `p4 diff2 path1/... path2/...` do [process diff output] done
以下のような非効率な方法は避けます。
for i in `p4 files path1/...` do p4 diff2 path1/$i path2/$i [process diff output] done
リスト入力ファイルを利用する
Perforceコマンドが、コマンドラインの引数にファイルのリストを指定できる場合は常に、あるファイルから同じ引数のリストを読み取ることもできます。最初にファイルのリストを作成し、そのリストファイルをp4 -xに引き渡すことにより、スクリプトでリスト入力ファイルを利用することができます。
例えば、スクリプトが以下のように記述されている場合が挙げられます。
for components in header1 header2 header3 do p4 edit ${component}.h done
効率を改善するには以下のように記述します。
for components in header1 header2 header3 do echo ${component}.h >> LISTFILE done p4 -x LISTFILE edit
-x
フラグは、p4に対して指定のファイルから1行ずつ引数を読み取ることを指示します。ファイル名がfile
-
(ダッシュ)の場合は、標準入力から読み取られます。
デフォルトでは、サーバは-x
からの引数を一回につき128個まとめて処理します。サーバによって処理される引数の数をfile
-b
フラグを用いて変更すると、異なるバッチサイズで引数を渡すことができます。
batchsize
ブランチビューを使用する
Perforceコマンドの実行回数を減らすために、p4 integrateまたはp4 diff2でブランチビューを使用できます。例えば、以下のようなコマンドを実行するスクリプトが挙げられます。
p4 diff2 pathA/src/... pathB/src/... p4 diff2 pathA/tests/... pathB/tests/... p4 diff2 pathA/doc/... pathB/doc/...
このとき、以下のようなブランチビューを作成すれば効率を改善できます。
Branch: pathA-pathB View: pathA/src/... pathB/src/... pathA/tests/... pathB/tests/... pathA/doc/... pathB/doc/...
また上記の3つのコマンドは次のように1つにまとめることができます。
p4 diff2 -b pathA-pathB
ラベル参照を制限する
大きなラベルへの反復参照は特に無駄を増やします。リビジョンにラベルを使用するファイルへの参照コマンドは、各ファイル引数ごとラベル全体のスキャンが行われることになります。Perforceサーバの回線を占有しないためには、サーバからラベルの適用されているファイルを取得し、それらのファイルに対してスキャンを行うスクリプトを使用します。
例えば、次のスクリプトでサーバへの負荷を軽くすることができます。
p4 files path/...@label | egrep "path/f1.h|path/f2.h|path/f3.h"
次のスクリプトよりも負荷は軽くなります。
p4 files path/f1.h@label path/f1.h@label path/f3.h@label
または次のスクリプトよりも負荷は軽くなります。
p4 files path/f1.h@label p4 files path/f2.h@label p4 files path/f3.h@label
以下に説明する「一時クライアントワークスペースの活用」も、ラベルによりファイルを参照する回数を減らすことに役立ちます。
大規模なサイトでは、参照頻度が低いか、または使用されていないラベルをデータベースからアンロードすることを検討してください。詳細については、使用頻度の低いメタデータをアンロードするを参照してください。
一時クライアントワークスペースの活用
ほとんどのPerforceコマンドは、現在のワークスペースビューのすべてのファイルを1つのコマンドライン引数で処理できます。作業したいファイルだけが含まれる一時クライアントワークスペースビューを利用すれば、実行するコマンドの数や、各コマンドに与えるファイル引数の数を減らすことができます。
例えば、次のコマンドを実行するスクリプトを仮定します。
p4 sync pathA/src/...@label p4 sync pathB/tests/...@label p4 sync pathC/doc/...@label
この場合、以下のようなクライアントワークスペース仕様を使えば、一度にまとめてコマンドを実行し、ラベルのスキャンを3回から1回に減らすことができます。
Client: XY-temp View: pathA/src/... //XY-temp/pathA/src/... pathB/tests/... //XY-temp/pathB/tests/... pathC/doc/... //XY-temp/pathC/doc/...
このワークスペース仕様は、次のように入力して実行します。
p4 -c XY-temp sync @label
効率よく圧縮を活用する
デフォルトでは、binary
タイプのファイルのリビジョンは、Perforceサーバに保存される際に圧縮されます。.GIFや.JPG画像、.MPGや.AVIのメディアコンテンツ、.gz
で圧縮されたファイルなどは、ファイルフォーマットの一部に圧縮を含みます。Perforceサーバでこのようなファイルを圧縮しようとすると、ディスク容量の節約がほとんどできない割に、サーバのCPUリソースを消費する結果となります。
これらのファイルタイプに対してサーバストレージでの圧縮を無効にするには、コマンドラインまたはp4 typemapテーブルを用いて、ファイルタイプにbinary+F
(圧縮せずに「+F」、サーバへ格納するバイナリ)を指定します。
サンプルのタイプマップテーブルを含め、p4 typemapについての詳細は、p4 typemapでファイルタイプを定義するを参照してください。
その他のサーバ構成可能変数
Perforceサーバには、パフォーマンス改善のために変更可能な多くの構成可能変数があります。
p4 help configurablesを実行すると、構成可能変数の完全なリストを表示できます。
並列処理
ワークスペースを同期するとき、転送するファイルの数とサイズに応じて、p4 syncコマンドは実行に時間がかかる場合があります。このコマンドで複数のスレッドを使用してファイルを転送することにより、処理を速くすることができます。これは構成変数net.parallel.max
を1より大きい値に設定し、--parallel
オプションをp4 syncコマンドに使用することにより行うことができます。並列処理は、距離が長く待機時間が長いネットワークや、単一のTCPフローを使用した帯域幅を使用できないネットワーク構成で使用すると最も効果的です。また、クライアントでファイルの解凍にかなりの作業を必要とする大規模な圧縮バイナリファイルを使用している場合にも役立ちます。
詳細については、『P4コマンドリファレンス』のp4 syncコマンドの解説を参照してください。
データベースツリーのバランス回復のためのチェックポイント
Perforceの内部データベースでは、データは通称BツリーとよばれるBayerツリーという構造で保存されます。Bツリーは高速アクセスが可能なきわめて一般的なデータ構成方法ですが、時間の経過とともに、ツリーに対するエレメントの追加や削除により、次第にデータ構造がアンバランスになってくることがあります。
最終的に、そのツリーがアンバランスになるあまり、パフォーマンスに悪影響が出る場合もあります。Perforceのチェックポイントと復旧のプロセス(バックアップとリカバリに関する基本的な考え方を参照してください)を実行することで、ツリーはバランスのとれた状態に再生されます。結果的に、バックアップ、db.*
ファイルの削除、チェックポイントからのdb.*
ファイルの再生の後、サーバのパフォーマンスにある程度の改善が得られます。
このツリーのバランス回復は、通常はデータベースファイルがチェックポイントのサイズの10倍以上になったときに初めて効果が得られます。Perforceを通常通り使用している限り、ツリーがアンバランスになるまでに長い時間を要します。大多数のサイトでは、パフォーマンス改善のためにチェックポイントからデータベースの復旧(つまりツリーのバランス回復)を行う必要はありません。
Perforce 2013.3のリリースのBツリーの変更により、db.*
ファイルのサイズが16TBに拡張されたほか、その他の点でもスケーラビリティが大きく向上しました。
Perforce 2013.2から2013.3でBツリーへ加えられた変更により、このリリースにまたがるすべてのアップグレードに関しては、古いリリースによりチェックポイントが作成され、新しいリリースによりそのチェックポイントが回復されなければなりません。詳細については、p4dをリリース2013.2から2013.3へアップグレードするを参照してください。