Sunday, March 4, 2007

Mailbox Load Balancing Made Simple - Part 1

While creating our Exchange mailbox provisioning process I was faced with a problem of load balancing mailboxes across multiple databases and several servers. Our mailbox count made micro-managing databases for specific departments not advantageous. We decided to try to distribute mailboxes evenly across all databases (as closely as possible). Three methods for load balancing were identified: database file size, number of users per database, and a random distribution of mailboxes.

Equal Database File Sizes


The theory behind this method was to keep database sizes uniform for backup purposes. Some databases would host many ‘light’ users while other databases may only host a few ‘heavy’ users. Either way each database would host approximately the same amount of data. To find the smallest database file size on a server I needed to get a list of databases, find the size of each, and sort for the smallest in terms of size. The following command works well in a single server environment.

[PS] C:\>Get-MailboxDatabase | foreach { get-childitem $_.edbFilePath | select-object name,length} | sort -property length

Name      Length
---- ------
MDB19.edb 4257366016
MDB12.edb 4270080000
MDB6.edb 4312023040

MDB5.edb 7000571904
MDB8.edb 7174504448


Assuming your edb file name is the same as the mailbox database name you can easily extract this information for mailbox provisioning:

[PS] C:\>$TargetDatabase = (((Get-MailboxDatabase -Server:EVS1 | foreach { get-childitem $_.edbFilePath | select-object name,length} | sort -property length)[0].Name).Split(”.edb”))[0]
[PS] C:\>Enable-Mailbox -Identity:user@domain.com -Database:$TargetDatabase


This method becomes more difficult when trying to load balance across multiple servers. It can be done by converting the edbFilePath to a UNC path using the ServerName attribute of the mailbox database object. After sorting to find the smallest database you must determine the identity of the mailbox in the form ‘ServerName\StorageGroupName\DatabaseName’. I did not pursue this method much further because of its fatal flaw for new mailbox provisioning.

Pros: This method works well for migrating existing mailboxes that contain some amount of data and is my preferred method for migrating mailboxes from legacy Exchange servers. The script executes quickly in a single server Exchange environment.

Cons: This method becomes quite complex when running multiple Exchange servers or if the provisioning code does not run on the Exchange server itself. Unless databases are regularly defragmented offline, the database file size will include some amount of ‘whitespace’ from previously deleted emails/mailboxes and the file size may not be indicative of the amount of real data stored within the database.

Fatal flaw: This method does not work when adding new mailboxes in bulk. Ten/hundreds/thousands of empty mailboxes could be added to a single database without it growing beyond the size of the next smallest database.

In part two I will detail distributing users evenly accross all databases based upon mailbox count.

--Nick

No comments: