<?xml version="1.0" encoding="utf-8"?>
<rss xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:pingback="http://madskills.com/public/xml/rss/module/pingback/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:dc="http://purl.org/dc/elements/1.1/" version="2.0">
  <channel>
    <title>ControlSystemWorks Blog - historical data</title>
    <link>http://www.controlsystemworks.com/blog/</link>
    <description>Of CSWorks and software development</description>
    <language>en-us</language>
    <copyright>ControlSystemWorks.com</copyright>
    <lastBuildDate>Wed, 19 May 2010 21:18:06 GMT</lastBuildDate>
    <generator>newtelligence dasBlog 2.3.9074.18820</generator>
    <managingEditor>support@ControlSystemWorks.net</managingEditor>
    <webMaster>support@ControlSystemWorks.net</webMaster>
    <item>
      <trackback:ping>http://www.controlsystemworks.com/blog/Trackback.aspx?guid=0d6a6133-fc63-4893-992e-46336e15c8ad</trackback:ping>
      <pingback:server>http://www.controlsystemworks.com/blog/pingback.aspx</pingback:server>
      <pingback:target>http://www.controlsystemworks.com/blog/PermaLink,guid,0d6a6133-fc63-4893-992e-46336e15c8ad.aspx</pingback:target>
      <dc:creator>Sergey Sorokin</dc:creator>
      <wfw:comment>http://www.controlsystemworks.com/blog/CommentView,guid,0d6a6133-fc63-4893-992e-46336e15c8ad.aspx</wfw:comment>
      <wfw:commentRss>http://www.controlsystemworks.com/blog/SyndicationService.asmx/GetEntryCommentsRss?guid=0d6a6133-fc63-4893-992e-46336e15c8ad</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
If you are curious about the number of Trend controls you can run against your CSWorks
server infrastructure, you may find this post interesting. We will make minor changes
to historical data server configuration, run a few Trend control clients against it
and analyze what we see. 
</p>
        <p>
          <font size="4">Environment </font>
        </p>
        <p>
CSWorks 1.2.3800.0<br />
Server: Intel Core 2 Duo @ 2.40GHz, 2 GB RAM, Windows Server 2008<br />
Client: Intel Core 2 Duo T5300 @ 1.73GHz (notebook), 2 GB RAM, Windows XP SP3<br />
Network: Wireless 54 Mbps 
</p>
        <p>
          <font size="4">Server Configuration </font>
        </p>
        <p>
1. As usual, we have to configure History Recorder so it uses some scalable database.
Install SQL Server 2008 Express on your server machine. 
<br /><br />
2. Create database "CSWorks" 
<br /><br />
3. Create HistoricalData table - see "createCommand" parameter of &lt;dbtarget ...=""
name="Standard SQLServer DbTarget"&gt; in CSWorks.Server.HistoryRecorderService.exe.config. 
<br /><br />
4. Configure SQL Server data source and make it active in CSWorks.Server.HistoryRecorderService.exe.config:
</p>
        <font size="1" color="#0000ff" face="Verdana">
          <font color="#0000ff">&lt;dbTargetConfig&gt;<br />
  &lt;dbTargets <strong><font color="#ff0000">activeDbTarget="Standard SQLServer
DbTarget</font>"</strong>&gt;<br />
    &lt;dbTarget name="Standard SQLite DbTarget" ...<br />
      ...<br />
    /&gt;<br />
    &lt;dbTarget name="Standard SQLServer DbTarget"<br />
      providerInvariantName="System.Data.SqlClient"<br />
      connectionString="<font color="#ff0000">Data Source=localhost\sqlexpress;
Initial Catalog=CSWorks;user id=sa;password=...</font>;"<br />
      ...<br />
    /&gt;<br />
  &lt;/dbTargets&gt;<br />
&lt;/dbTargetConfig&gt;</font>
        </font>
        <br />
        <br />
5. Configure HistoryReaderWebService to read historical data from this database. In
the web.config, assign SQLServer target to the primary partition and specify correct
connection string:<br /><br /><font size="1" color="#0000ff">  &lt;historyTopology&gt;<br />
    &lt;historyPartitions&gt;<br />
      &lt;historyPartition name="partition1" primaryDbTarget="<b><font color="#ff0000">partition1
Primary DbTarget (SQLServer)</font></b>" secondaryDbTarget=""&gt;<br />
        ..<br />
      &lt;/historyPartition&gt;<br />
    &lt;/historyPartitions&gt;<br />
  &lt;/historyTopology&gt;<br /><br />
  &lt;dbTargetConfig&gt;<br />
    &lt;dbTargets&gt;<br />
      ...<br />
      &lt;dbTarget name="partition1 Primary DbTarget (SQLServer)"<br />
               
providerInvariantName="System.Data.SqlClient"<br />
               
connectionString="<font color="#ff0000">Data Source=localhost\sqlexpress; Initial
Catalog=CSWorks;user id=sa;password=...;</font>"<br />
               
...<br />
               
/&gt;<br />
    &lt;/dbTargets&gt;<br />
  &lt;/dbTargetConfig&gt;<br /></font><br />
6. Restart HistoryRecorder service and verify that it writes observation to the newly
configured database. 
<p><font size="4">Running clients </font></p><p>
Before running the clients, make sure you have prepared *.clientConfig in CSWorks.Client.TrendDemo.xap
to run from a remote machine. Please see <a target="_blank" href="http://www.controlsystemworks.com/blog/2010/02/25/RunningCSWorksDemoApplicationsFromRemoteClients.aspx">this
post</a> for details. 
<br /><br />
Now run a few Trend clients on your client machine using this command:<br /><br /><font size="1" color="#0000ff">start iexplore "http://myserver/CSWorksDemo/TrendDemo.html"</font><br /><br />
I ran 25 instances, increasing the load by 5-instance chunks. 
</p><p><font size="4">Results </font></p><p>
All 25 clients run without problems, trending data (both live and historical) arrives
without delays, server seems to be perfoming fine. <a target="_blank" href="content/binary/2010-05-19-ServerPerformance.png">Here
is a screenshot</a> made on the server machine. Clients consume about 200K of live
and historical data every second, server machine uses about 35% of its CPU capacity.
SQL Server and ASP.NET worker process are working hard (14% and 18%, respectively)
to deliver historical data to the clients. 
<br /><br />
The spikes in data transfer rates mark moments when Trend control were re-querying
bigger amounts of historical data - View-&gt;Tracking setting were set to On for all
Trend control instances, and all instances were refreshing the whole picture synchronously
(well, in chunks of 5 instances, of course). 
<br /><br />
The spikes in CPU consumption mark moments when I ran chunks of 5 IE instances. 
</p><p><font size="4">Summary </font></p><p>
Not bad for a commodity server box that runs every piece of the deployment: all CSWorks
services (LiveData, Alarm, HistoryRecorder), web services and database engine. Potential
bottlenecks are:<br />
- the database - not surprising;<br />
- web service layer - but we can scale it out using web farm. 
</p><img width="0" height="0" src="http://www.controlsystemworks.com/blog/aggbug.ashx?id=0d6a6133-fc63-4893-992e-46336e15c8ad" /></body>
      <title>Trending client performance - Lab 03</title>
      <guid isPermaLink="false">http://www.controlsystemworks.com/blog/PermaLink,guid,0d6a6133-fc63-4893-992e-46336e15c8ad.aspx</guid>
      <link>http://www.controlsystemworks.com/blog/2010/05/19/TrendingClientPerformanceLab03.aspx</link>
      <pubDate>Wed, 19 May 2010 21:18:06 GMT</pubDate>
      <description>&lt;p&gt;
If you are curious about the number of Trend controls you can run against your CSWorks
server infrastructure, you may find this post interesting. We will make minor changes
to historical data server configuration, run a few Trend control clients against it
and analyze what we see. 
&lt;/p&gt;
&lt;p&gt;
&lt;font size="4"&gt;Environment &lt;/font&gt;
&lt;/p&gt;
&lt;p&gt;
CSWorks 1.2.3800.0&lt;br&gt;
Server: Intel Core 2 Duo @ 2.40GHz, 2 GB RAM, Windows Server 2008&lt;br&gt;
Client: Intel Core 2 Duo T5300 @ 1.73GHz (notebook), 2 GB RAM, Windows XP SP3&lt;br&gt;
Network: Wireless 54 Mbps 
&lt;/p&gt;
&lt;p&gt;
&lt;font size="4"&gt;Server Configuration &lt;/font&gt;
&lt;/p&gt;
&lt;p&gt;
1. As usual, we have to configure History Recorder so it uses some scalable database.
Install SQL Server 2008 Express on your server machine. 
&lt;br&gt;
&lt;br&gt;
2. Create database "CSWorks" 
&lt;br&gt;
&lt;br&gt;
3. Create HistoricalData table - see "createCommand" parameter of &amp;lt;dbtarget ...=""
name="Standard SQLServer DbTarget"&amp;gt; in CSWorks.Server.HistoryRecorderService.exe.config. 
&lt;br&gt;
&lt;br&gt;
4. Configure SQL Server data source and make it active in CSWorks.Server.HistoryRecorderService.exe.config:
&lt;/p&gt;
&lt;font size="1" color="#0000ff" face="Verdana"&gt;&lt;font color="#0000ff"&gt;&amp;lt;dbTargetConfig&amp;gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;lt;dbTargets &lt;strong&gt;&lt;font color="#ff0000"&gt;activeDbTarget="Standard SQLServer
DbTarget&lt;/font&gt;"&lt;/strong&gt;&amp;gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;dbTarget name="Standard SQLite DbTarget" ...&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;...&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;/&amp;gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;dbTarget name="Standard SQLServer DbTarget"&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;providerInvariantName="System.Data.SqlClient"&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;connectionString="&lt;font color="#ff0000"&gt;Data Source=localhost\sqlexpress;
Initial Catalog=CSWorks;user id=sa;password=...&lt;/font&gt;;"&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ...&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; /&amp;gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;lt;/dbTargets&amp;gt;&lt;br&gt;
&amp;lt;/dbTargetConfig&amp;gt;&lt;/font&gt;&lt;/font&gt;
&lt;br&gt;
&lt;br&gt;
5. Configure HistoryReaderWebService to read historical data from this database. In
the web.config, assign SQLServer target to the primary partition and specify correct
connection string:&lt;br&gt;
&lt;br&gt;
&lt;font size="1" color="#0000ff"&gt;&amp;nbsp; &amp;lt;historyTopology&amp;gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;historyPartitions&amp;gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;historyPartition name="partition1" primaryDbTarget="&lt;b&gt;&lt;font color="#ff0000"&gt;partition1
Primary DbTarget (SQLServer)&lt;/font&gt;&lt;/b&gt;" secondaryDbTarget=""&amp;gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ..&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/historyPartition&amp;gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/historyPartitions&amp;gt;&lt;br&gt;
&amp;nbsp; &amp;lt;/historyTopology&amp;gt;&lt;br&gt;
&lt;br&gt;
&amp;nbsp; &amp;lt;dbTargetConfig&amp;gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;dbTargets&amp;gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ...&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;dbTarget name="partition1 Primary DbTarget (SQLServer)"&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
providerInvariantName="System.Data.SqlClient"&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
connectionString="&lt;font color="#ff0000"&gt;Data Source=localhost\sqlexpress; Initial
Catalog=CSWorks;user id=sa;password=...;&lt;/font&gt;"&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
...&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
/&amp;gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/dbTargets&amp;gt;&lt;br&gt;
&amp;nbsp; &amp;lt;/dbTargetConfig&amp;gt;&lt;br&gt;
&lt;/font&gt; 
&lt;br&gt;
6. Restart HistoryRecorder service and verify that it writes observation to the newly
configured database. 
&lt;p&gt;
&lt;font size="4"&gt;Running clients &lt;/font&gt;
&lt;/p&gt;
&lt;p&gt;
Before running the clients, make sure you have prepared *.clientConfig in CSWorks.Client.TrendDemo.xap
to run from a remote machine. Please see &lt;a target="_blank" href="http://www.controlsystemworks.com/blog/2010/02/25/RunningCSWorksDemoApplicationsFromRemoteClients.aspx"&gt;this
post&lt;/a&gt; for details. 
&lt;br&gt;
&lt;br&gt;
Now run a few Trend clients on your client machine using this command:&lt;br&gt;
&lt;br&gt;
&lt;font size="1" color="#0000ff"&gt;start iexplore "http://myserver/CSWorksDemo/TrendDemo.html"&lt;/font&gt;
&lt;br&gt;
&lt;br&gt;
I ran 25 instances, increasing the load by 5-instance chunks. 
&lt;/p&gt;
&lt;p&gt;
&lt;font size="4"&gt;Results &lt;/font&gt;
&lt;/p&gt;
&lt;p&gt;
All 25 clients run without problems, trending data (both live and historical) arrives
without delays, server seems to be perfoming fine. &lt;a target="_blank" href="content/binary/2010-05-19-ServerPerformance.png"&gt;Here
is a screenshot&lt;/a&gt; made on the server machine. Clients consume about 200K of live
and historical data every second, server machine uses about 35% of its CPU capacity.
SQL Server and ASP.NET worker process are working hard (14% and 18%, respectively)
to deliver historical data to the clients. 
&lt;br&gt;
&lt;br&gt;
The spikes in data transfer rates mark moments when Trend control were re-querying
bigger amounts of historical data - View-&amp;gt;Tracking setting were set to On for all
Trend control instances, and all instances were refreshing the whole picture synchronously
(well, in chunks of 5 instances, of course). 
&lt;br&gt;
&lt;br&gt;
The spikes in CPU consumption mark moments when I ran chunks of 5 IE instances. 
&lt;/p&gt;
&lt;p&gt;
&lt;font size="4"&gt;Summary &lt;/font&gt;
&lt;/p&gt;
&lt;p&gt;
Not bad for a commodity server box that runs every piece of the deployment: all CSWorks
services (LiveData, Alarm, HistoryRecorder), web services and database engine. Potential
bottlenecks are:&lt;br&gt;
- the database - not surprising;&lt;br&gt;
- web service layer - but we can scale it out using web farm. 
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.controlsystemworks.com/blog/aggbug.ashx?id=0d6a6133-fc63-4893-992e-46336e15c8ad" /&gt;</description>
      <comments>http://www.controlsystemworks.com/blog/CommentView,guid,0d6a6133-fc63-4893-992e-46336e15c8ad.aspx</comments>
      <category>historical data</category>
      <category>performance</category>
    </item>
    <item>
      <trackback:ping>http://www.controlsystemworks.com/blog/Trackback.aspx?guid=20a658ae-d7c3-4b0e-808f-59472db7098b</trackback:ping>
      <pingback:server>http://www.controlsystemworks.com/blog/pingback.aspx</pingback:server>
      <pingback:target>http://www.controlsystemworks.com/blog/PermaLink,guid,20a658ae-d7c3-4b0e-808f-59472db7098b.aspx</pingback:target>
      <dc:creator>Sergey Sorokin</dc:creator>
      <wfw:comment>http://www.controlsystemworks.com/blog/CommentView,guid,20a658ae-d7c3-4b0e-808f-59472db7098b.aspx</wfw:comment>
      <wfw:commentRss>http://www.controlsystemworks.com/blog/SyndicationService.asmx/GetEntryCommentsRss?guid=20a658ae-d7c3-4b0e-808f-59472db7098b</wfw:commentRss>
      <title>History Recorder performance - Lab 02</title>
      <guid isPermaLink="false">http://www.controlsystemworks.com/blog/PermaLink,guid,20a658ae-d7c3-4b0e-808f-59472db7098b.aspx</guid>
      <link>http://www.controlsystemworks.com/blog/2010/04/20/HistoryRecorderPerformanceLab02.aspx</link>
      <pubDate>Tue, 20 Apr 2010 17:09:46 GMT</pubDate>
      <description>&lt;p&gt;
In the latest release of CSWorks, we have improved Historical Data Server performance.
Let's see what History Recorder is capable of now. 
&lt;/p&gt;
&lt;p&gt;
&lt;font size="4"&gt;Environment &lt;/font&gt;
&lt;/p&gt;
&lt;p&gt;
CSWorks 1.2.3730.0&lt;br&gt;
Server: Intel Core 2 Quad Q6600 @ 2.40GHz,&amp;nbsp;4 GB RAM, Windows&amp;nbsp;7&lt;br&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;font size="4"&gt;Set-up&lt;/font&gt; 
&lt;/p&gt;
&lt;p&gt;
1. Install SQL Server 2008 Express on your server machine. 
&lt;br&gt;
&lt;br&gt;
2. Create database "CSWorks" 
&lt;br&gt;
&lt;br&gt;
3. Create HistoricalData table - see "createCommand" parameter of 
&lt;dbtarget ...="" name="Standard SQLServer DbTarget"&gt;
in CSWorks.Server.HistoryRecorderService.exe.config. 
&lt;br&gt;
&lt;br&gt;
4. Configure SQL Server data source and make it active in CSWorks.Server.HistoryRecorderService.exe.config: 
&lt;/dbtarget&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;font size="1" color="#0000ff"&gt;&lt;font face="Courier New"&gt;&lt;font color="#0000ff"&gt;&amp;lt;dbTargetConfig&amp;gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;lt;dbTargets &lt;strong&gt;&lt;font color="#ff0000"&gt;activeDbTarget="Standard SQLServer
DbTarget&lt;/font&gt;"&lt;/strong&gt;&amp;gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;dbTarget name="Standard SQLite DbTarget" ...&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;...&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;/&amp;gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;dbTarget name="Standard SQLServer DbTarget"&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;providerInvariantName="System.Data.SqlClient"&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;connectionString="Data Source=localhost\sqlexpress;
Initial Catalog=CSWorks;user id=sa;password=...;"&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;createCommand="..."&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;writeCommand="..."&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;maintenanceCommand="delete top &lt;strong&gt;&lt;font color="#ff0000"&gt;(300000)&lt;/font&gt;&lt;/strong&gt; from
HistoricalData ..."&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;maxObservationAge=&lt;strong&gt;&lt;font color="#ff0000"&gt;"600"&lt;/font&gt;&lt;/strong&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;writeInterval="1"&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;maintenanceInterval=&lt;strong&gt;&lt;font color="#ff0000"&gt;"30"&lt;/font&gt;&lt;/strong&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;maxQueryLength="65535"&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;queryDelimiter=";"&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;writeTxnBeginCommand="..."&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;writeTxnCommitCommand="..."&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;/&amp;gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;lt;/dbTargets&amp;gt;&lt;br&gt;
&amp;lt;/dbTargetConfig&amp;gt;&lt;/font&gt;
&lt;br&gt;
&lt;/font&gt;&lt;/font&gt;
&lt;/p&gt;
&lt;p&gt;
Please note we tell History Recorder to keep alarm event records in the database for
10 minutes only, and we perform record cleaning every 30 seconds. This only because
our SQL Server is not capable of taking heavy load. 
&lt;br&gt;
&lt;br&gt;
5. Restart History Recorder service. Make sure events are now written to CSWorks database
(run "select * from HistoricalData" to confirm it). 
&lt;br&gt;
&lt;br&gt;
6. Using cscript tool, run a script that generates 2000 historical data points: 
&lt;/p&gt;
&lt;p&gt;
&lt;font size="1" color="#0000ff" face="Courier New"&gt;function main()&lt;br&gt;
{&lt;br&gt;
&amp;nbsp;&amp;nbsp;var itemCount = 2000;&lt;br&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;WScript.Echo("RecorderDataPoints.xml");&lt;br&gt;
&amp;nbsp;&amp;nbsp;for (i = 0; i &amp;lt; itemCount; i++)&lt;br&gt;
&amp;nbsp;&amp;nbsp;{&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;var id = i.toString();&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;while(id.length &amp;lt; 4)&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;id = "0" + id;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;WScript.Echo("&lt;datapoint id="{00000000-0000-0000-0000-00000000&amp;quot; + id + &amp;quot;}" expression="tank1-&amp;quot; + id +&amp;quot;" description="Tank 1 fill - &amp;quot; + id + &amp;quot;"&gt;
");&lt;br&gt;
&amp;nbsp;&amp;nbsp;}&lt;br&gt;
}&lt;br&gt;
&lt;br&gt;
main();&lt;br&gt;
&lt;/datapoint&gt;
&lt;/font&gt;
&lt;br&gt;
&lt;/p&gt;
&lt;p&gt;
7. Copy generated historical data point descriptions to RecorderDataPoints.xml: 
&lt;/p&gt;
&lt;p&gt;
&lt;font size="1" color="#0000ff" face="Courier New"&gt;&amp;lt;dataPoints&amp;gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;...&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;lt;dataPoint id='{00000000-0000-0000-0000-000000000000}' description='Tank
1 fill - 0000' expression='tank1-0000'/&amp;gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;...&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;lt;dataPoint id='{00000000-0000-0000-0000-000000001999}' description='Tank
1 fill - 1999' expression='tank1-1999'/&amp;gt;&lt;br&gt;
&amp;lt;/dataPoints&amp;gt;&lt;br&gt;
&lt;/font&gt;
&lt;br&gt;
&lt;/p&gt;
&lt;p&gt;
History Recorder will pick up the change in a couple of seconds and will start saving
observation for those 2000 data points to the database. Give our setup some time to
stabilize. 
&lt;/p&gt;
&lt;p&gt;
&lt;font size="4"&gt;Results&lt;/font&gt;
&lt;/p&gt;
&lt;p&gt;
After 10 minutes, History Recorder maintains about 3.5 million observation records
in the database and writes about 6000 observation records every second on average.
Database file size is between 1 and 1.5 gigabytes. Here is a screenshot with Performance
Monitor and DbgView windows: 
&lt;/p&gt;
&lt;p&gt;
&lt;a href="content/binary/2010-04-20-RecorderServicePerformance-big.gif" target="_blank"&gt;&lt;img src="content/binary/2010-04-20-RecorderServicePerformance.gif" border="0"&gt;&lt;/a&gt; 
&lt;/p&gt;
&lt;p&gt;
Since our test live data changes in a very predictable way, there is a clear pattern
in observation recording on the top perfmon chart. History Recorder memory consumption
is under control too. Tracing shows that History Recorder deletes between 120000 and
270000 "obsolete" observations every 30 seconds. As you may have noticed, the maximum
number of record it is allowed to delete in one shot is 300K, see 'maintenanceCommand'
parameter above. Our setup is properly balanced, so History Recorder does not reach
this limit. 
&lt;/p&gt;
&lt;p&gt;
If you add more historical datapoints and make total count, say 5000, you may end
up in a situation when History Recorder simply cannot write all collected observations
in a timely manner, and they will accumulate in the memory buffer. Major symptom will
be growing memory consumption by History Recorder. CSWorks 1.2.3800.0 introduces "Write
Buffer Size" performance counter that shows current number observations to be written
to the database by HistoryRecorder, so this overload scenario becomes more obvious. 
&lt;/p&gt;
&lt;p&gt;
&lt;font size="4"&gt;Summary &lt;/font&gt;
&lt;/p&gt;
&lt;p&gt;
Please plan your historical data management carefully. Use scalable database engine,
and give it a lot of spare CPU resources. Use multiple History Recorder machines if
needed. If the amount of data is extremely big, use multiple databases and apply partitioning
technique described in CSWorks documentation. 
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.controlsystemworks.com/blog/aggbug.ashx?id=20a658ae-d7c3-4b0e-808f-59472db7098b" /&gt;</description>
      <comments>http://www.controlsystemworks.com/blog/CommentView,guid,20a658ae-d7c3-4b0e-808f-59472db7098b.aspx</comments>
      <category>historical data</category>
      <category>performance</category>
    </item>
  </channel>
</rss>