AF SDKを用いたPI DAへの書き込み方法の使い分け

AF SDKを用いて、PI DAの複数のタグに対して複数の値を書き込む方法を検討しています。

Referenceを読んだところ、以下の4つの方法が使えそうであることが分かったのですが、

それぞれどういった特徴があり、どのように使い分ければよいでしょうか?

また、レスポンス的にはどれが一番早かったり、負荷が低かったりするのでしょうか?

 

  1.  1タグずつPIPointを取得し、タグごとにUpdateValuesでAFValueのListを登録する

     

    上記処理をタグごとにforループやforeach、Parallel.Forループで回す。
  2. 1タグずつPIPointを取得して、タグごとにUpdateValuesAsyncでAFValueのListを登録する

     

    上記処理をタグごとにforループやforeachループで回す。
  3. 事前にタグと紐づけたAFValueのListを用意し、PIServer.UpdateValuesで登録する
  4. 1タグずつPIPointを取得し、AFValueを1つずつUpdateValueで登録する

     

    上記処理をタグごとにforループで回し、AFValue分だけUpdateValueを実行する 
  • Google Translate to English:

     

    We are examining how to write multiple values to multiple tags of PI DA using AF SDK.  After reading Reference, I found that the following four methods could be used.  What kind of features are there and how should I use them separately?  Also, in terms of response, which one is the fastest or the load is low?

     

    1. Get PIPoint one tag at a time, and register AFValue List with UpdateValues for each tag.  The above process is performed for each tag with for loop, foreach, Parallel.For loop.
    2. Get PIPoint one tag at a time and register AFValue List with UpdateValuesAsync for each tag.  The above process is performed by for loop and foreach loop for each tag.
    3. Prepare a list of AFValues linked with tags in advance, and register them with PIServer.UpdateValues
    4. Get PIPoint one tag at a time, and register AFValue one by one with UpdateValue.  Execute the above processing in a for loop for each tag and execute UpdateValue for AFValue
  • Greetings Kenichi and thank you for your post,

     

    I will answer in my native English first and then use Google Translate to convert to Japanese.

     

    A couple of guiding principles to keep in mind:

     

    • Bulk calls are preferred over individual calls.
    • Bulk calls are preferred in many cases over parallel.
    • Parallel can be more complicated to debug and sometimes may perform slower than serial execution.

     

    There are exceptions to almost every rule.  Where bulk calls are concerned, this means that fewer calls across the network to a server are better than many, many calls.  However, a bulk call that is too big can lose efficiency so many developers look for the "sweet spot" of finding the right size of the bulk call.

     

    Any one call to a PI Data Archive is constrained by the ArcMaxCollect tuning parameter, most likely set to 1.5 million values.  When reading data, I would choose a size of 50K to 100K for a bulk call.  But with writing data, I would choose a smaller size, perhaps 10K, to allow the data to flow through the Snapshot Subsystem.

     

    Out of your options, I would choose the third one:

     

    Prepare a list of AFValues linked with tags in advance, and register them with PIServer.UpdateValues.

     

    It is critical that each individual AFValue in the AFValues collection has it's PIPoint property correctly set.  That is how the PIServer knows which tag is to receive that value.

     

    If I had only 10K values to update, I would only do the one bulk call.  If I had 20K values to update, and then do very little else, I would probably also do that in one bulk call.  But if I have more than 20K values, then I would break my bulk calls into 10K chunks. 

     

    While some may suggest you could send chunked bulk calls in parallel too, I would advise against it.  The AFValues collection may contain values for many PIPoints, but I would hope that for an given PIPoint that the values are time ascending order.  If you processed in parallel, you have allowed the possibility that values will not be received in time ascending order, which may affect what passes compression testing.  Also, 10K is a decent size to allow the PI Data Archive sufficient time to process the incoming data.  Parallel calls would only burden the PI Data Archive.

     

     

    Translation to Japanese via Google Translate

    Google翻訳による日本語への翻訳

    Kenichiさん、ご投稿ありがとうございます。

    私は最初に私の母国語の英語で答えてから日本語に変換するためにGoogle翻訳を使用します。

    心に留めておくべきいくつかの指針原則:

    バルクコールは個々のコールより優先されます。

     

    多くの場合、一括呼び出しが並列より優先されます。

     

    パラレルはデバッグが複雑で、シリアル実行よりも遅くなることがあります。

    ほとんどすべての規則には例外があります。バルクコールが関係しているところでは、これはネットワークを介したサーバへのコールの数が少ないほど多くのコールよりも優れていることを意味します。ただし、大きすぎるバルクコールは効率を低下させる可能性があるため、多くの開発者は正しいサイズのバルクコールを見つけることの「最適な場所」を探します。

    PI Data Archiveへの呼び出しは、ArcMaxCollect調整パラメーターによって制限されます。おそらく150万の値に設定されています。データを読むとき、私はバルクコールのために50Kから100Kのサイズを選びます。しかし、データの書き込みでは、データがSnapshot Subsystemを通過できるように、もっと小さいサイズ(おそらく10K)を選択します。

    あなたの選択肢の中から、私は3番目のものを選びます:

    あらかじめタグとリンクしたAFValuesのリストを用意し、PIServer.UpdateValuesに登録してください。

    AFValuesコレクション内の個々のAFValueのPIPointプロパティが正しく設定されていることが重要です。それがPIServerがどのタグがその値を受け取ることになっているかを知る方法です。

    更新する値が10Kしかない場合は、一括呼び出しを1回だけ実行します。更新する20Kの値があり、それ以外のことをほとんど行わない場合は、1回の一括呼び出しでもそれを実行します。しかし、20Kを超える値がある場合は、一括呼び出しを10Kのチャンクに分割します。

    チャンクされた一括呼び出しを並行して送信することを提案する人もいるかもしれませんが、それに対してお勧めします。 AFValuesコレクションには多くのPIPointの値が含まれている可能性がありますが、特定のPIPointについては、値が時間の昇順になるようにしてください。並列処理した場合は、値が時間の昇順で受け取られない可能性があります。これは、圧縮テストに合格したものに影響を与える可能性があります。また、10Kは、PI Data Archiveが受信データを処理するのに十分な時間を確保するのに適切なサイズです。並列呼び出しは、PI Data Archiveにのみ負担をかけます。

  • ご回答ありがとうございます。参考になりました。

    追加の質問が2つあります。

     

    1つ目は、先の回答の「10K」はデータ数(値の数)のことですよね?データ量(バイト数)ではないですよね?

     

    2つ目は、AFValuesコレクションを複数のチャンクに分割する際、同じタグでグループ化する方がよいのでしょうか?もしくは近いタイムスタンプでグループ化する方が良いのでしょうか?

    またそれは、AFValuesの期間が複数のアーカイブを跨るかどうかで変わりますか?

     

    Translation to English via Google Translate

    Thank you for your reply. It was helpful.

    There are two additional questions.

     

    First, "10K" in the previous answer is the number of data (number of values), right? It is not the amount of data (number of bytes), right?

     

    Second, when dividing an AFValues collection into multiple chunks, is it better to group by the same tag? Or is it better to group by near timestamps?

    Also does it change depending on whether the AFValues period spans multiple archives?

  • 1. Yes. 10K is the number of values and not the number of bytes.

    2. I would sort by tag first and then by time order. Reason to sort by time order is to avoid costly out-of-order event processing on the server. 

     

    You can also enable buffering to achieve 'async-like' behavior if you want to return on your call in the fastest time possible. 

     

    Google Translate to Japanese.

     

    1。 10Kは値の数であり、バイト数ではありません.

    2.最初にタグでソートし、次に時間順にソートします。時間順にソートする理由は、サーバー上でコストのかかるアウトオブオーダーのイベント処理を避けるためです.

     

     

    可能な限り最速の時間で通話に戻る場合は、バッファリングを有効にして「非同期のような」動作を実現することもできます。

     

  • > 2.最初にタグでソートし、次に時間順にソートします。
    上記は、全体としては時間順にソートされているという認識で正しいですか? 
    もしそうなら、近い時間でグループ化するようにデータを分割することは正しいですか?
    
    

    Translation to English via Google Translate

    > 2. I would sort by tag first and then by time order. 

    Is the above correct in recognition that it is sorted in time order as a whole?

     

    If so, is it correct to divide the data so as to group by the near time?
  • Greetings Kenichi,

     

    If you are issuing a bulk update for many PI points each with many values, that is with either the PIServer.UpdateValues or PIServerUpdateValuesAsync methods, the best advice is that for any given PIPoint that its values are sorted in ascending time order.  This is more of a recognition that the PI Data Archive archives values in this order but only after it has flowed through the other subsystems, such as Snapshot or Compression.  You will get different behavior and archived values if you sent values out of order.  If it within your means as a developer to sort by (1) PIPoint and (2) timestamp, then please do so.

     

    As long as you are not doing anything parallel, it does not matter if you break a chunk of values across a PIPoint.  When the second chunk comes across, that PIPoint would be at the top of that chunk and since its values are sorted in time ascending order, the data will be processed as one would hope.

     

    If you are processing in parallel, and I have already given my cautions against that, then you would want to make sure that all the values for a given PIPoint are included in the same chunk.

     

    If it is possible for you to share, it would be good to know the number of PI points for your application, the average count of values per given PIPoint, and the maximum count of values per PIPoint.

     

    Google Translate to Japanese

    Google日本語に翻訳する

    ケンイチ、

    それぞれが多数の値を持つ多数のPIポイント、つまりPIServer.UpdateValuesまたはPIServerUpdateValuesAsyncメソッドのいずれかを使用して一括更新を発行する場合は、すべてのPIPointに対して、値が時間の昇順でソートされることをお勧めします。これは、PI Data Archiveが値をこの順序でアーカイブすることを認識したものですが、スナップショットや圧縮などの他のサブシステムを通過した後に限られます。値を順序どおりに送信しなかった場合は、動作が異なり、値がアーカイブされます。 (1)PIPointと(2)タイムスタンプでソートすることが開発者としてのあなたの手段の範囲内であれば、そうしてください。

    並列処理をしていない限り、PIPointで値の塊を分割しても問題ありません。 2番目のチャンクが遭遇すると、そのPIPointはそのチャンクの先頭になり、その値は時間の昇順にソートされるので、データは期待どおりに処理されます。

    あなたが並行して処理していて、私がすでにそれに対して私の注意を払ったならば、あなたは与えられたPIPointのためのすべての値が同じチャンクに含まれることを確認したいでしょう。

    あなたが共有することが可能であるならば、あなたのアプリケーションのためのPIポイントの数、与えられたPIPointあたりの値の平均数、そしてPIPointあたりの値の最大数を知ることは良いでしょう。