0

私のユーザーは、私たちが持っている大規模な Lotus Notes アプリケーション (Web ではない) のパフォーマンスの悪さに本当に不満を感じています。現在10Gbで、約500.000のドキュメントがあり、リーダーフィールドが含まれています。

私がやりたいことは、アプリケーション アプリケーションのミニ バージョンを作成することです。これは、ほとんどのユーザーが昨年のドキュメントにしか関心がないためです。

現時点では、大きなアプリケーションをアーカイブまたは移動することはできないため、新しいミニ レプリカを提供し、今年のドキュメントのみを含めるように選択的な複製を行うことを考えています。

私が抱えている問題は、アプリケーションのフル バージョンをすべてのサーバーに配置する必要があることです。つまり、フル バージョンとミニ バージョンの両方を同じサーバーに同じレプリカ ID で取得することになり、少し怖いように見えます。

これを行うより良い方法はありますか?

4

2 に答える 2

3

私はこの問題に対して、シンプルなものから過度に設計されたものまで、さまざまなアプローチを見てきました。悲しいことに、私はいくつかの過剰設計されたアプローチの設計者だったと思います。幸いなことに、私はいくつかの教訓を学びました。これが私が考える最も低技術のアプローチです。

最初に行う必要があるのは、データベースの設計のみのコピーを作成することです。これを productiondocs.ntf と呼びます。オリジナルを alldocs.nsf と呼びます。

productiondocs.ntf に 2 つのエージェントを追加し、それらが設計の更新/置換から保護されていることを確認します。最初のエージェント「synch」を呼び出し、新しいドキュメントまたは変更されたドキュメントで実行するように設定し、新しいドキュメントまたは変更されたドキュメントを単純に alldocs.nsf にコピーするコードを記述します。このエージェントのメイン ループで削除されたドキュメントが処理されないように、isValid を確認してください。2 番目のエージェントを「パージ」と呼びます。日付 (適用するルールに応じて、ドキュメント内の作成日、変更日、またはデータ フィールド) をチェックし、1 年以上前のドキュメントを削除するコードを記述します。

これで、選択的レプリケーションを使用できるようになりましたが、1 回だけです。1 年分のドキュメントのみを含む alldocs.nsf の選択的レプリカを作成し、それを yeardocs.nsf と呼びます。次に、yeardocs.nsf の非レプリカ コピーを作成し、production.nsf と名付けます。最後に、production.ntf を使用して production.nsf の設計を置き換えます。エージェントが存在すること、および設計の更新/置換操作から保護されていることを再確認してください。(デザイナの一部のバージョンはこれを台無しにしました!) 同期を必要な頻度で実行するようにスケジュールし、パージを毎日または毎週実行するようにスケジュールします。production.nsf をすべてのサーバーに複製し、ユーザーを production.nsf に移動します。

(注: 逆に、既存のデータベースを削除した後にユーザーを保持することもできますが、正直なところ、クリーンな新しい NSF から開始することで、パフォーマンスがさらに向上すると思います。やりました。)

于 2012-09-25T18:07:59.940 に答える
0

私はリチャードのソリューションが本当に好きですが、最近、私が今のところ気に入っている派生物を実装しました。基本的に、各ドキュメントのメタデータを「インデックス」である個別のデータベースに配置し、インデックス ドキュメントを開くと、alldocs.nsf 内のドキュメントが開かれます (インデックス ドキュメントが閉じられます)。

これを行うには、文書が変更または保存されるたびにインデックス文書を作成するエージェントを alldocs.nsf に記述します。インデックス作成に使用するフィールド (メタデータ) のみをコピーする必要があります。インシデントのコピーからメインエージェントにこれを行うためのサンプル コード (サブルーチンや呼び出し関数なし) :

Sub Initialize
Dim session As New NotesSession
Dim maindb As NotesDatabase ' Main SIR
Dim mainincidents As NotesView ' view in Main SIR
Dim maindoc As NotesDocument ' document in Main SIR
Dim projectdoc, nextprojectdoc As NotesDocument ' document in this database
Dim ndc As NotesDocumentCollection ' unprocessed documents in this database
Dim fieldItem As NotesItem
Dim reportnumber, value, formtype As Variant
Dim fieldsToCopy (10) As String 
Dim reason As String

On Error GoTo errorhandler 

Call StartAgentLogging ( session )

Set thisdb = session.Currentdatabase

' find all unstamped documents
Set ndc = thisdb.Unprocesseddocuments

If ndc.Count = 0 Then
    Call agentLog.LogAction ( "No incidents to process" )
    Exit Sub
End If

maindbfilepath = DetermineKeyword("MAINSIR")
Set maindb = session.Getdatabase("","")
Call maindb.Open("", maindbfilepath)

If Not maindb.Isopen Then
    reason = "Main Security database could not be found at " & maindbfilepath
    Call agentLog.LogAction ( reason )
    MessageBox reason, 16, "Error"
    Exit Sub
End If

Set mainincidents = maindb.Getview("(Incidents for Upload)")
Set projectdoc = ndc.Getfirstdocument()
fieldsToCopy (0) = "ReportType"
fieldsToCopy (1) = "ReportNumber"
fieldsToCopy (2) = "ReportDate"
fieldsToCopy (3) = "IncidentDate"
fieldsToCopy (4) = "ProjectName"
fieldsToCopy (5) = "ProjectCountry"
fieldsToCopy (6) = "ProjectLocation"
fieldsToCopy (7) = "ReporterName"
fieldsToCopy (8) = "ReporterPhone"
fieldsToCopy (9) = "ReporterEmail"
fieldsToCopy (10) = "Appointment"

While Not projectdoc Is Nothing
    formtype = projectdoc.GetItemValue ("Form")
    If formtype(0) = "Incident" Then
        ' check to see if that exists in the main SIR
        reportnumber = projectdoc.GetItemValue("ReportNumber")
        Call agentLog.LogAction ( "Checking " & reportnumber(0) )
        Set maindoc = mainincidents.GetDocumentByKey(reportnumber(0), True)
        Call agentLog.LogAction ( "Accessing " & reportnumber(0) )

        If maindoc Is Nothing Then
            Call agentLog.LogAction ( "Main does not contain " & reportnumber(0) & " creating new document." )
            ' if not, create new document
            Set maindoc = maindb.Createdocument()
            maindoc.Form = "Incident"

            ForAll fieldname In fieldsToCopy
                Call agentLog.LogAction ( "Field name: " & fieldname ) 
                Set fieldItem = projectdoc.Getfirstitem(fieldname)
                Call maindoc.Copyitem(fieldItem, fieldname)
            End ForAll

            Call maindoc.Save(True, False)
            Call CreateNotice ( maindoc )
        Else
            Call agentLog.LogAction ( "Main contains " & reportnumber(0) & " updating document." )
            ' if it does, update data
            ForAll fieldname In fieldsToCopy
                Call agentLog.LogAction ( "Field name: " & fieldname ) 
                value = projectdoc.GetItemValue(fieldname)
                Call maindoc.ReplaceItemValue(fieldname, value(0))
            End ForAll
        End If

        'Path and filename
        Call maindoc.Replaceitemvalue("Path", thisdb.Filepath)
        Call maindoc.Save(True, False)
        Call agentLog.LogAction ( "Saved " & reportnumber(0) )
    Else
        Call agentLog.LogAction ( "Project form is " & projectdoc.Form(0) )
    End If

    ' stamp document as processed
    Set nextprojectdoc = ndc.GetNextDocument(projectdoc)
    Call session.Updateprocesseddoc(projectdoc)
    Set projectdoc = nextprojectdoc
Wend 

exiting:
    Exit Sub
errorhandler:' report all errors in a messagebox
    reason = "Error #" & CStr (Err) & " (" & Error & ") when creating incident in Main database, on line " & CStr (Erl)
    Call agentLog.LogAction ( reason )
    MessageBox reason, 16, "Error" 
    Resume exiting
End Sub

次に、インデックス データベースのインデックス フォームの onLoad イベントにコードを追加する必要があります。私は ToolsRunMacro によって呼び出されるエージェントに私のものを入れましたが、直接入れることもできます。これは私のOpen Project Copyエージェントです。

Sub Initialize
' this button opens the incident report in the project database
Dim ws As New NotesUIWorkspace
Dim session As New NotesSession
Dim reportdb As NotesDatabase
Dim view As NotesView
Dim uidoc As NotesUIDocument
Dim thisdoc, reportdoc As NotesDocument
Dim filepath, reportnumber As Variant
Dim baseurl, opener, unid As String

Call StartAgentLogging ( session )
Set thisdb = session.Currentdatabase

Set uidoc = ws.CurrentDocument
Set thisdoc = uidoc.Document
filepath = thisdoc.GetItemValue ( "Path" )
reportnumber = thisdoc.GetItemValue ( "ReportNumber" )

Set reportdb = session.GetDatabase (thisdb.Server, filepath (0), False )
If reportdb Is Nothing Then
    MessageBox ( "Could not find Project Security Incident Report database" & Chr$(10) & thisdb.Server & "\" & filepath(0) )
    Call agentLog.LogAction ( "Could not find Project Security Incident Report database" & Chr$(10) & thisdb.Server & "\" & filepath(0) )
    Exit Sub
End If
If Not reportdb.Isopen Then
    Call reportdb.Open(thisdb.Server, filepath (0)) 
End If
Set view = reportdb.GetView ( "Incidents" )
Set reportdoc = view.GetDocumentByKey ( reportnumber(0) )
If reportdoc Is Nothing Then
    MessageBox ( "Could not find Report #" & reportnumber(0) )
    Call agentLog.LogAction ( "Could not find Report #" & reportnumber(0) )
    Exit Sub
End If

Call uidoc.Close
unid = reportdoc.UniversalID
baseurl = reportdb.NotesURL
opener = Left$ ( baseurl, InStr ( baseurl, "?" ) -1 ) & "/Incidents/" & unid & "?OpenDocument"
Call ws.URLOpen ( opener )
Call agentLog.LogAction ( "Opened Report #" & reportnumber(0) )
End Sub

これで、インデックス データベースを最新のドキュメントのみに制限したり、すべてのドキュメントが含まれている場合の動作を確認したりできます。ビューで使用できるようにする必要があるデータの量に大きく依存します。

私の状況では、インデックス データベースには多くのデータベースからのドキュメントのインデックス ドキュメントが含まれており、「完全なデータ」データベースの中央アクセス ポイントとして機能します。まだテスト段階なので、うまくいくかどうかはわかりませんが、可能性として提供したいと思います。

于 2012-09-26T14:32:15.683 に答える