I asked one of our Exchange Architects, Jake Ballecer, to articulate what the Exchange community takes for granted - sizing Exchange data stores. No one thinks twice about throwing a hundred or so spindles at an Exchange implementation and they have the methodology to justify that spindle count - so why is it so hard for us when attempting to size the disk subsystem for an MIIS implementation? Let's see what Jake has to say on the subject:
Simplified Spindle Calculation for Exchange Storage Allocation
Since the disk subsystem is the most common performance bottleneck for Exchange 2003, Exchange engineers have learned to include adequate spindle counts in their storage designs. The fundamental design protocol is deceptively simple: (1) determine your Exchange IOPS (I/O per second) requirement and (2) make sure that you provide enough dedicated physical disks to match the IOPS value. It’s the classic supply and demand scenario.
An Exchange IO can be loosely defined as a read or write operation on a single database page. The IOPS demand value can either be measured or estimated. Measuring this value in an existing Exchange environment gives a great view of actual real world numbers. Use perfmon to log disk reads/sec, disk writes/sec, and disk transfers/sec on the Exchange database disks during periods of heaviest usage. This method will provide you with the actual IOPS value (transfers/sec) and the read:write ratio that we will need later on. Use peak or near-peak transfers/sec values to determine your IOPS demand number. Divide this IOPS demand number by the number of mailbox users that were actively accessing the database at the time of the transfer/sec reading. This is your IOPS/mailbox value for Exchange 2003 calculations. Use averages for read:write ratio.
To summarize measured values:
- IOPS/mailbox = (peak or near-peak transfers/sec)/(active mailbox users at the time of peak reading)
- Read_ratio = (average reads/sec)/((average reads/sec)+(average writes/sec))
- Write_ratio = (average writes/sec)/((average reads/sec)+(average writes/sec))
If you need to estimate your IOPS demand value, you will need to determine if the mailbox users can be profiled as light, average, heavy, or hard core Exchange users. We’ve learned to use more aggressive estimates in recent years due to the evolution of corporate email usage. The most common light Exchange users are workers that only casually access email and have very small mailboxes. Use an IOPS/mailbox value between .2 and .4 for this category. Average Exchange users are workers who typically receive around 40-100 emails and send less than 25 per day. Use an IOPS/mailbox value of .5 to .8 for this category. Heavy Exchange users are workers that have Outlook open pretty much their entire work day and constantly access their mailbox and calendar contents. Use an IOPS/mailbox value between 1 and 1.5 for this category. Hard core Exchange users are heavy users that regularly send and receive messages larger than 512MB. Use an IOPS/mailbox of 2-2.5 for this category. For read:write ratios, use .75:.25 for typical environments or .67:.33 if your messaging environment is skewed heavier towards writing.
The last piece of the demand side of the equation is the RAID penalty on writes. Different RAID levels will write an Exchange page differently. RAID 1, 10, or 0+1 configurations will write a page twice due to mirroring. Due to this behavior, these RAID levels are assigned a write penalty value of 2. In the case of RAID 5, the write operation follows this sequence: the new Exchange page is written, the rest of the contents of a stripe is read, the parity is calculated, then the parity for the stripe is written. Due to this behavior, RAID 5 configurations are assigned a RAID penalty of 4.
With the values compiled above, we can calculate the IOPS demand for a given set of mailboxes (#mailboxes):
IOPS_demand = (IOPS/mailbox * #mailboxes * Read_ratio)+(IOPS/mailbox * #mailboxes * Write_ratio * RAID_Penalty)
The second component in the calculation is the supply part. We need to know how many spindles it will take to sufficiently cover the IOPS demand. The rule of thumb is that a single physical disk is able to provide 100 IOPS for every 10,000rpm. So that’s 72 IOPS for a 7,200 rpm drive, 100 IOPS for a 10,000rpm drive, or 150 IOPS for a 15,000rpm drive.
#Spindles = IOPS_demand / IOPS_per_Spindle
Note though that this number of spindles will cover the demand but will be at 100% performance capacity. Allow for growth.
Jake Ballecer
Technical Architect
Ensynch, Inc
So sure, Exchange doesn't use SQL and MIIS does, so how does this apply? Well, the methodology behind using disk IOPS to drive the sizing of the array isn't limited to just Exchange, or SQL, but any I/O intensive application.
Transactions vs Mailboxes
When MIIS begins to process a synchronization for a connectorspace object it begins a SQL transaction which includes all operations from the start of the sync through inbound attribute flow, provisioning, and export attribute flow for all other connectors associated with that metaverse object. The transaction commits at the conclusion of the sync as long as no errors occurred. For any given MIIS implementation, one SQL transaction may contain as few as one record up to the total number of connectors connected to that metaverse object plus one for the metaverse object itself. The number of objects processed for each sync might be expressed as such:
total_number_of_connectors + 1
So, if I have an metaverse object with 5 connectors then I have 6 objects to sync for every transaction although granted that depending on your rules not every metaverse object will have the same number of connectors. Whereas in the Exchange calculations we use # of mailboxes, for MIIS we would use the number of transactions executed at peak to calculate demand.
Calculations
At the very least I think the following information is crucial to obtain during development:
IOPS/Transaction = (Disk Transfers/sec [Avg]) / (SQL Transactions/sec [Peak])
This data would need to be gathered on the following items:
- MIIS Database logical disk
- MIIS Log logical disk
- tempDB Database logical disk
- tempDB Log logical disk
Furthermore, the read and write ratio's would need to be calculated for the same instances:
- Read_ratio = (Disk Reads/sec [Avg])/((Disk Reads/sec [Avg]) + (Disk Writes/sec [Avg]))
- Write_ratio = (Disk Writes/sec [Avg])/((Disk Reads/sec [Avg]) +(Disk Writes/sec [Avg]))
Last but not least, the IOPS demand would be calculated using the following equation for each given instance:
IOPS_demand = (IOPS/Transaction * Transactions/sec [Peak] * Read_ratio)+(IOPS/Transaction * Transactions/sec [Peak] * Write_ratio * RAID_Penalty [2 for RAID 1/1+0, 4 for RAID 5])
The following table illustrates the performance counters required:
Object |
Counter |
Instance |
Logical Disk |
Disk Reads/sec |
MIIS DB & Logs
tempdb DB & logs
|
Logical Disk |
Disk Transfers/sec |
MIIS DB & Logs
tempdb DB & Logs |
Logical Disk |
Disk Writes/sec |
MIIS DB & Logs
tempdb DB & Logs |
SQLServer:Databases |
Transactions/sec |
MIIS DB |
SQLServer:Databases |
Transactions/sec |
tempdb |
So far my initial calculations of existing implementations has produced realistic spindle counts but only time and much more evaluation will decide whether or not this approach is ultimately valid for MIIS implementations. I have started a conversation concerning general disk performance tuning in the MIIS TechNet forum, please post your own performance data in this thread if you've applied the above calculations.