Altiris Technical Advisory Board Group

Deterministic Randomization 

Dec 15, 2009 11:16 AM

As an administrator of an enterprise installation of Symantec Client Management Suite and Server Management Suite, often I want to spread load over time.  Having 10,000 machines check in with a full software inventory at the same time is not exactly good for the performance of either my Notification Servers or our WAN!

In that particular situation (Software Inventory) in NS v6, Altiris provided us with a tool to spread the load randomly:  The AeXRunControl, and it worked really well.  It spread the load out over the week or the month as you set it up.  There were only three issues that I had with AeXRunControl:  1)  They syntax was cryptic, 2)  The uninitiated saw that "Software Inventory" was running every day (even though you were simply running the RunControl and it only actually ran once a month), and 3)  I had no easy way of determining which day a particular PC would report in.

This led me to seek a method that solved these issues.  It needed to be:  1)  Simple to understand, 2)  Not falsely run null tasks, and 3)  Be deterministic as to which day a particular PC ran.

I came up with two solutions, one very simple, but restrictive as to the increments I could randomize to, and one more complex and more flexible.  Both will be discussed herein.

Keep it Simple-Skip the Math
One attribute that I immediately seized upon to randomize computers was the GUID.  The Globally Unique Identifier is generated, at random, by the system.  By design, the GUID is random.  By it's nature, and the number of possible GUIDs available, it virtually guarantees lack of duplication of GUIDs, but to achieve this, a fairly sophisticated algorithm is used by SQL server to generate new GUIDs, and to ensure that those generated are incredibly random.

So, great, we've got an attribute that's random...how do we use it to spread load out...

First, create a filter (works with collections in V6 too).  You need to create a "Raw SQL" filter (make sure you have Platform SP3 in place before doing this, as there's a bug in pre-SP3 that makes these painfully slow to work with):

select
[_ResourceGuid] AS [Guid]

from
[Inv_AeX_AC_Identification]

where cast([_ResourceGuid]  as nvarchar(50)) like '0%'

This SQL will return all of your computers that have GUIDs starting with a zero.  Repeat this process for 1-9 and A-F, and voila.  You have filters that will break down all of your computers into 16 fairly even chunks.  Want to run half your computers on Tuesdays and half on Thursdays:  Apply 0-7 to Tuesday, and 8-F on Thursday.  Simple and effective.  If you're like me and have multiple sites, the sites will be load-shared too, so if you have 2,000 computers in a site, only 1,000 of them will be run on Tuesday and 1,000 on Thursdays (more or less...there will be variations, but only a few percent).

So...how does this stack up to the criteria I laid out before:
1)  Simple to understand:  The SQL here is pretty clean and easy to understand.  If you simply understand what a GUID is, you can figure it out
2)  Not falsely run tasks:  I can set things like SW audit to simply run on the day I want it (or ASAP thereafter), and not have to run a check task every day
3)  Deterministic:  By simply looking at the filters, or in the Resource Manger looking at the "Filter Summary", I can see which one a PC's in, and it doesn't change

The only issue here is that I have a fixed number of breakdowns:  16...how do you fix that:  Now you need to do some math...sorry.

Do the Math
Alright, so we had something simple, and we got 16 breakdowns with very little effort.  80% of the time, that's just fine...but what about that other 20% of the time when you really want to spread out load.  For example, if you want to break your computers down so that 5% of them run on the 1st-4th Monday-Friday?  Enter the humble "modulo" operator, one of the least used arithmetic operators!

The modulo operator (%) is simple.  It divides one integer by another, and returns the remainder.  So if I do a "Select 125 % 3", it will return a 2 (125/3 = 41 remainder 2).  This is the key to getting nice breakdowns to a specified number of gradiations:
 

DECLARE @NumberOfCategories INT
DECLARE @CurrentCategory INT

SET @NumberOfCategories = 20
SET @CurrentCategory = 0


SELECT
    _resourceguid AS guid
   ,mod = ABS(CAST(_resourceguid AS varbinary) % @NumberOfCategories)
FROM
    dbo.Inv_AeX_AC_Identification
WHERE
    ABS(CAST(_resourceguid AS varbinary) % @NumberOfCategories) = @CurrentCategory

At the top of this SQL, set your @NumberOfCategories to be the number you want to break down, then the @CurrentCategory to be each of the possible (in this case 0,1,2...19).  Now you will get, in this case, 1/20 of all your PCs, similarly broken down completely randomly, including breakdowns within sites etc.

So...how again does this stack up to the criteria I laid out before:
1)  Simple to understand:  The SQL here is a bit more complex.  You need to understand both GUIDs and the modulo operator to really get this one.  Maybe put some comments in.
2)  Not falsely run tasks:  I can set things like SW audit to simply run on the day I want it (or ASAP thereafter), and not have to run a check task every day
3)  Deterministic:  By simply looking at the filters, or in the Resource Manger looking at the "Filter Summary", I can see which one a PC's in, and it doesn't change

Conclusion
So, I've provided two pretty simple ways to break down your PCs randomly, allowing you to spread load for intensive processes, while at the same time being able to accurately predict when particular PCs are going to report in with results.  Try it out, I'll bet you'll find more and more reasons to use this functionality in the future.

Statistics
0 Favorited
0 Views
1 Files
0 Shares
0 Downloads
Attachment(s)
zip file
Random Breakdown Filters.zip   3 KB   1 version
Uploaded - Feb 25, 2020

Tags and Keywords

Comments

Feb 08, 2010 02:53 PM

Instead of building a "25%" filter as you've said, Kyle, I leave my 1/16 filters and simply add four of them to my deployment.

That way I don't have to build new filters for each rollout depending on how rapidly I want to deploy, I simply assign to multiple of my 1/16 filters as required.

Feb 08, 2010 12:26 PM

We do something similar here for some of our larger or potentially more impactful rollouts (such as disk encryption, XP SP3, Office 2007 SP2, etc).  One variation on your method is using the LEFT function with LIKE:

WHERE LEFT(_ResourceGuid, 1) LIKE '[0-3]'

This would effectively give you 25% of your environment (GUIDs starting with 0, 1, 2, or 3).  The MOD operator was a tricky idea; you can also use LEFT(Guid, 2) LIKE '0[0-7]' which will get you ~10% of the environment of GUIDs starting with 0 then the second character being 0 - 7.

Feb 05, 2010 03:18 PM

Hi Jeff,

Seems I didn't give you a vote when I last commented! Sorry about that -now rectified.

Kind Regards,
Ian./

Feb 05, 2010 12:38 PM

This is a very creative solution.  thanks for sharing.

Dec 22, 2009 03:50 PM

Nice little tip Jeff. Very interesting approach.

Kind Regards,
Ian./

Related Entries and Links

No Related Resource entered.