It is important to keep in mind that potential for
cookdownstarts at the beginning of a
workflow at its first module, and proceeds onward in order of the
modules that compose the workflow. When lack of
cookdownis creating performance issues
in your management pack, the solution is to ensure that first
module is not breaking
cookdownby ensuring that
instance-specific data is moved out of this module. By doing this,
the first module will cook down. You can continue to do this
sequentially for the modules in your management pack up to the
point where it makes most sense; i.e. modules that are known to
have high performance impact in large instance spaces are cooked
down. Modules that are known to have such an impact are the
Powershellmodule, WMI module, and
Script Executer module. By ensuring that these modules are cooked
down, the number of instances of these modules is diminished
significantly, which greatly improves performance.
Let us discuss how to use this approach. This approach can be used
when a performance critical module can return needed data (for
instance, property bag) without using instance specific
information. For instance, this is true when the module is used
only for filtering out unnecessary objects. In such a case, the
performance critical module can return data for all objects, and
then use the
System.ExpressionFiltermodule to filter
the returned data. This way, the performance critical module will
be executed only once and will not cause a performance issue.
Moreover, the
System.ExpressionFiltermodule is very
efficient, and executing it multiple times will not result in
performance issues.
Now, let us examine this approach in detail using a common example.
This particular issue was found in an MP through
CookdownAnalysis:
Workflow
|
Interval
|
Target
|
Microsoft.Windows.ABCServer.2003.Monitor.DriveRunning
|
900 Seconds
|
Microsoft.Windows.ABCServer.2003.Drive
|
…
Microsoft.Windows.ABCServer.2003.Monitor.DriveRunning
Management Pack:
Microsoft.Windows.ABCServer.2003
Module (
critical module shown in
bold, all modules belonging to the parent composite module
shown with indentation)
Performance Issue (
shown only for unit modules)
ID:
DataSource
ID: Scheduler
ID: Probe
$Target/Property[Type='Microsoft.Windows.ABCServer.Library.Drive']/DriveName$
ID:
RunningFilter
The problem here is that instance-specific data is used in the
configuration of the WMI-based module. This leads to execution of
this module for every "Drive" object instance in the system. Taking
a closer look shows us that this instance-specific information is
used only for filtering out unnecessary objects:
<
UnitMonitorType
ID
=
"
Microsoft.Windows.ABCServer.Library.MonitorType.DriveRunningState"
>
<...>
<
MonitorImplementation
>
<
MemberModules
>
<
DataSource
ID
=
"
DataSource
"
TypeID
="
Windows
!Microsoft.Windows.WmiProvider
"
>
<
NameSpace
>
root\
MicrosoftABC
</
NameSpace
>
<
Query
>
Select * from
MicrosoftABC_Drivewhere Name =
'
$Target/
Property[Type="Microsoft.Windows.ABCServer.Library.Drive"]/DriveName$
'
</
Query
>
<
Frequency
>
$
Config/
IntervalSeconds$
</
Frequency
>
</
DataSource
>
<
ConditionDetection
ID
=
"
ShutdownFilter
"
TypeID
="
System
!System.ExpressionFilter
"
>
<
Expression
>
<
SimpleExpression
>
<
ValueExpression
>
<
XPathQuery
>
Property[@Name='Shutdown']
</
XPathQuery
>
</
ValueExpression
>
<
Operator
>
Equal
</
Operator
>
<
ValueExpression
>
<
Value
>
True
</
Value
>
</
ValueExpression
>
</
SimpleExpression
>
</
Expression
>
</
ConditionDetection
>
<...>
</
MemberModules
>
<
RegularDetections
>
<...>
</
RegularDetections
>
</
MonitorImplementation
>
</
UnitMonitorType
>
To solve this problem, we will modify it in such a way that it
returns data for all objects. We will then filter out unnecessary
objects. In this case, it can be done very easily by modifying the
System.ExpressionFiltermodule.
<
UnitMonitorType
ID
=
"
Microsoft.Windows.ABCServer.Library.MonitorType.DriveRunningState"
>
<...>
<
MonitorImplementation
>
<
MemberModules
>
<
DataSource
ID
=
"
DataSource
"
TypeID
="
Windows
!Microsoft.Windows.WmiProvider
"
>
<
NameSpace
>
root\
MicrosoftABC
</
NameSpace
>
<
Query
>
Select Name, Shutdown, Paused from
MicrosoftABC_Drive
</
Query
>
<
Frequency
>
$
Config/
IntervalSeconds$
</
Frequency
>
</
DataSource
>
<
ConditionDetection
ID
=
"
ShutdownFilter
"
TypeID
="
System
!System.ExpressionFilter
"
>
<
Expression
>
<
And
>
<
Expression
>
<
SimpleExpression
>
<
ValueExpression
>
<
XPathQuery
Type
=
"
String"
>Property[@Name='Name']
</
XPathQuery
>
</
ValueExpression
>
<
Operator
>
Equal
</
Operator
>
<
ValueExpression
>
<
Value
Type
=
"
String"
>
$Target/Property[Type="Microsoft.Windows.ABCServer.Library.Drive"]/DriveName$
</
Value
>
</
ValueExpression
>
</
SimpleExpression
>
</
Expression
>
<
Expression
>
<
SimpleExpression
>
<
ValueExpression
>
<
XPathQuery
>
Property[@Name='Shutdown']
</
XPathQuery
>
</
ValueExpression
>
<
Operator
>
Equal
</
Operator
>
<
ValueExpression
>
<
Value
>
True
</
Value
>
</
ValueExpression
>
</
SimpleExpression
>
</
Expression
>
</
And
>
</
Expression
>
</
ConditionDetection
>
<...>
</
MemberModules
>
<
RegularDetections
>
<...>
</
RegularDetections
>
</
MonitorImplementation
>
</
UnitMonitorType
>
So, as a result we can see that this workflow does not have any
cookdowncriteria for the module, i.e.
it is properly cooked down:
Workflow
Interval
Target
Microsoft.Windows.ABCServer.2003.Monitor.DriveRunning
900 Seconds
Microsoft.Windows.ABCServer.2003.Drive
…
Microsoft.Windows.ABCServer.2003.Monitor.DriveRunning
Management Pack:
Microsoft.Windows.ABCServer.2003
Module (
critical module shown in
bold, all modules belonging to the parent composite module
shown with indentation)
Performance Issue (
shown only for unit modules)
ID:
DataSource
ID: Scheduler
ID: Probe
ID:
RunningFilter
$Target/Property[Type='Microsoft.Windows.ABCServer.Library.Drive']/DriveName$
With this particular example in a lab, on a topology with 50
Drives, the non-cooked down workflow created 100% CPU consumption
for a few seconds. By implementing
cookdown, this was reduced to 5% CPU
spikes.
Target:Microsoft.Windows.ABCServer.2003.Drive
Interval:900 Seconds
Module:WMI-based module 'Select * from
MicrosoftABC_Drivewhere Name ='$Target/
Property[Type="Microsoft.Windows.ABCServer.Library.Drive"]/DriveName$''
Type:
Microsoft.Windows.WmiProvider
Type:
System.Scheduler
Type:
Microsoft.Windows.WmiProbe
Type:
System.ExpressionFilter
Target:Microsoft.Windows.ABCServer.2003.Drive
Interval:900 Seconds
Module:WMI-based module 'Select Name, Shutdown, Paused from
MicrosoftABC_Drive'
Type:
Microsoft.Windows.WmiProvider
Type:
System.Scheduler
Type:
Microsoft.Windows.WmiProbe
Type:
System.ExpressionFilter