miércoles, 6 de agosto de 2014

Evaluando nuestro RPS actual de los servicios de Sharepoint - Parte 2

Parte 1 - Realizando un capacity planning efectivo definiendo correctamente el RPS

Part 2   - Evaluando nuestro RPS actual de los servicios de Sharepoint (acá estamos)

La segunda parte de esta serie de post, es evaluar los RPS reales sobre una ambiente actual. Por ej: nos podría servir si estamos migrando de una granja de Sharepoint 2010 a 2013.

Vamos a usar el siguiente script: http://1drv.ms/1okT5Kg (al final del post también se los dejo)

Guardar los archivos del archivo descargado, y dejar todos los logs del IIS en la misma carpeta. Por ej: u_ex14081.log está en el mismo directorio que el script.

image

El script tomará cada archivo .log y lo procesará para generar por hora el valor más alto (peak) de RPS, y lo guardará en el archivo resultadosrpsTemp.csv. Después se toma los datos del archivo generado, y los cargas en el archivo ResultadosRPS.xlsx.

image

Como pueden ver se generó el archivo resultadosrpsTemp.csv

image

Abro el archivo resultadosrpsTemp.csv y ResultadosRPS.xlsx. Copio los datos de un archivo al otro.

image

En el gráfico veo que el máximo pico de RPS fue a las 11 hs. Las horas con más througput fueron desde las 6 am hasta las 18 hs, lo que da 12 hs de trabajo (recuerdan la variable D de la fórmula para calcular los RPS en el post anterior)

image

Si vemos el promedio de RPS en esas horas de trabajo, vemos que no da 100.30 RPS en promedio. Si lo comparamos con la estimación inicial de RPS del post anterior, vemos que nos quedamos corto con los RPS que iba a soporta la plataforma (60 RPS)

image

image

Ya con 100 RPS, estamos en el límite de los RPS soportados por un sólo WFE. Obviamente dependerá mucho de su plataforma (ej: Blob cache, cantidad de recursos del servidor, etc).

Ahora lo que voy a calcular es la cantidad de usuarios por minuto que tengo, de esta manera podré sacar la concurrencia del sistema (variable B de nuestra fórmula). La ejecución es muy similar al script anterior, dejo los logs del IIS en el mismo folder donde está el script.

Descargar Script powershell: http://1drv.ms/1qUD54O

image

Una vez ejecutado nos dejará el archivo resultadosUsuarios.csv

image

Copio los resultados al excel ResultadosUsuariosXHora.xlsx, y obtengo el peak de usuarios por hora.En este ejemplo: 197 usuarios de forma concurrente. Se podría obtener por minutos, pero prefiero por hora, así obtenemos un pico más alto de usuarios y estimamos hacia arriba.

image

Para finalizar, les dejo la querie para obtener la cantidad de usuarios que accedieron a la plataforma:

SELECT cs-username As User FROM c:\inetpub\logs\LogFiles\W3SVC1\*.log WHERE User Is Not Null GROUP BY User

Si tienes varios web applications, deberás ejecutar este script por cada folder del IIS (asociados a un web application) y consolidar resultados (Ej: en el excel es muy simple: http://office.microsoft.com/en-us/excel-help/filter-for-unique-values-or-remove-duplicate-values-HP010073943.aspx)

Con estos scripts ya tenemos todas las variables necesarias para hacer un capacity planning continuo.

En el próximo post, estaré realizando load testing con Visual Studio 2013, para ver si realmente la infraestructura soporta el nivel de usuarios/RPS planificados.

SCRIPTS UTILIZADOS

GET RPS FROM IIS LOGS

$programfiles = (Get-Childitem 'Env:\ProgramFiles(x86)').Value
$logParser = $programfiles + "\Log Parser 2.2\LogParser.exe"
$psScriptRoot = Split-Path -Parent -Path (Get-Item -Path $MyInvocation.MyCommand.Path).FullName;

Write-Host "Step 1 - Processing log files to single source for querying..." -ForegroundColor Cyan
Start-Process -FilePath $logParser -ArgumentList "-i:IISW3C file:'rpsquery1.txt' -o:csv -q" -WorkingDirectory $psScriptRoot -RedirectStandardOutput "$psScriptRoot\rps1.csv" -Wait -WindowStyle Hidden
Write-Host "Done" -ForegroundColor Green

Write-Host "Step 2 - Calculating per second distribution..." -ForegroundColor Cyan
Start-Process -FilePath $logParser -ArgumentList "-i:CSV –o:CSV `"select count(*) as ct,secs,max(ss) as ss,max(mi) as mi,max(hh) as hh from rps1.csv group by secs order by secs`" -q" -WorkingDirectory $psScriptRoot -RedirectStandardOutput "$psScriptRoot\rps2.csv" -Wait -WindowStyle Hidden
Write-Host "Done" -ForegroundColor Green

Write-Host "Step 3 - Calculating per minute distribution..." -ForegroundColor Cyan
Start-Process -FilePath $logParser -ArgumentList "-i:CSV –o:CSV `"select count(*) as ct,div(secs,60) as minu,max(ss) as ss,max(mi) as mi,max(hh) as hh from rps1.csv group by minu order by minu`" -q" -WorkingDirectory $psScriptRoot -RedirectStandardOutput "$psScriptRoot\rps3.csv" -Wait -WindowStyle Hidden
Write-Host "Done" -ForegroundColor Green

Write-Host "Step 4 - Calculating hourly average, per minute peak and per second peak..." -ForegroundColor Cyan
Start-Process -FilePath $logParser -ArgumentList "-i:CSV –o:CSV `"select hh,avg(ct) from rps3.csv group by hh order by hh`" -q" -WorkingDirectory $psScriptRoot -RedirectStandardOutput "$psScriptRoot\Havg.csv" -Wait -WindowStyle Hidden
Start-Process -FilePath $logParser -ArgumentList "-i:CSV –o:CSV `"select hh,max(div(ct,60)) from rps3.csv group by hh order by hh`" -q" -WorkingDirectory $psScriptRoot -RedirectStandardOutput "$psScriptRoot\Mpeak.csv" -Wait -WindowStyle Hidden
Start-Process -FilePath $logParser -ArgumentList "-i:CSV –o:CSV `"select hh,max(ct) from rps2.csv group by hh order by hh`" -q" -WorkingDirectory $psScriptRoot -RedirectStandardOutput "$psScriptRoot\Speak.csv" -Wait -WindowStyle Hidden
Write-Host "Done" -ForegroundColor Green

Write-Host "Step 5 - Combining outputs..." -ForegroundColor Cyan
$results = @{}
$results["Havg"] = @{}
$results["Mpeak"] = @{}
$results["Speak"] = @{}

$havg = Import-Csv $psScriptRoot\havg.csv
$i = 0
while ($i -le 23) {
    $results["Havg"][$i] = $havg[$i].'AVG(ALL ct)'
    $i++
}
$Mpeak = Import-Csv $psScriptRoot\Mpeak.csv
$i = 0
while ($i -le 23) {
    $results["Mpeak"][$i] = $Mpeak[$i].'MAX(ALL DIV(ct, 60))'
    $i++
}
$Speak = Import-Csv $psScriptRoot\Speak.csv
$i = 0
while ($i -le 23) {
    $results["Speak"][$i] = $Speak[$i].'MAX(ALL ct)'
    $i++
}

$newline = [System.Environment]::NewLine
$output = "Hour`tHavg`tMpeak`tSpeak" + $newline
$i = 0
while ($i -le 23) {
    $output = $output + [String]::Format("{3}`t{0}`t{1}`t{2}" + $newline, $results["Havg"][$i], $results["Mpeak"][$i], $results["Speak"][$i], $i)
    $i++
}
$output | Out-File $psScriptRoot\results.csv
Write-Host "Done" -ForegroundColor Green

Write-Host "Step 6 - Cleaning up temp files..." -ForegroundColor Cyan
Remove-Item $psScriptRoot\rps1.csv
Remove-Item $psScriptRoot\rps2.csv
Remove-Item $psScriptRoot\rps3.csv
Remove-Item $psScriptRoot\Havg.csv
Remove-Item $psScriptRoot\Mpeak.csv
Remove-Item $psScriptRoot\Speak.csv
Write-Host "Done" -ForegroundColor Green

 

GET USER PER MINUTE FROM IISLOGS

$logParserPath = "C:\Program Files (x86)\Log Parser 2.2\LogParser.exe"
$pathScript = Split-Path -Parent -Path (Get-Item -Path $MyInvocation.MyCommand.Path).FullName;

Write-Host "Paso 1 - Proceso los logs..." -ForegroundColor Red
Start-Process -FilePath $logParserPath -ArgumentList "-i:IISW3C file:'query.txt' -o:csv -q" -WorkingDirectory $pathScript -RedirectStandardOutput "$pathScript\usuariosTemp.csv" -Wait -WindowStyle Hidden
Write-Host "Finalizado" -ForegroundColor Green

Write-Host "Paso 2 - Calculo la distribucion de usuarios..." -ForegroundColor Red
Start-Process -FilePath $logParserPath -ArgumentList "-i:CSV –o:CSV `"select count(*) as ct,cs-username,secs,max(ss) as ss,max(mi) as mi,max(hh) as hh from usuariosTemp.csv group by secs,cs-username order by secs,cs-username`" -q" -WorkingDirectory $pathScript -RedirectStandardOutput "$pathScript\usuariosTemp1.csv" -Wait -WindowStyle Hidden
Write-Host "Finalizado" -ForegroundColor Green
 
Write-Host "Paso 3 - Consolido hora..." -ForegroundColor Red
Start-Process -FilePath $logParserPath -ArgumentList "-i:CSV –o:CSV `"select hh,cs-username,sum(ct) as req from usuariosTemp1.csv group by hh,cs-username order by hh,cs-username`" -q" -WorkingDirectory $pathScript -RedirectStandardOutput "$pathScript\MaximosUsersTemp.csv" -Wait -WindowStyle Hidden
Write-Host "Finalizado" -ForegroundColor Green

Write-Host "Paso 4 - Agrupo hora x usuarios" -ForegroundColor Red
Start-Process -FilePath $logParserPath -ArgumentList "-i:CSV –o:CSV `"select hh,count(*) from MaximosUsersTemp.csv group by hh`" -q" -WorkingDirectory $pathScript -RedirectStandardOutput "$pathScript\UsuariosXHora.csv" -Wait -WindowStyle Hidden
Write-Host "Finalizado" -ForegroundColor Green


Write-Host "Paso 5 - Genero el excel..." -ForegroundColor Red
$results = @{}
$results["UsuariosXHora"] = @{}

$PicoXHora = Import-Csv $pathScript\UsuariosXHora.csv

$i = 0
while ($i -le 23) {
    $results["UsuariosXHora"][$i] = $PicoXHora[$i].'COUNT(ALL *)'
    $i++
}

$newline = [System.Environment]::NewLine
$output = "Hora`tUsuariosXHora" + $newline
$i = 0
while ($i -le 23) {
    $output = $output + [String]::Format("{1}`t{0}" + $newline, $results["UsuariosXHora"][$i], $i)
    $i++
}
$output | Out-File $pathScript\resultadosUsuarios.csv


Remove-Item $pathScript\usuariosTemp.csv
Remove-Item $pathScript\usuariosTemp1.csv
Remove-Item $pathScript\MaximosUsersTemp.csv
Remove-Item $pathScript\UsuariosXHora.csv
Write-Host "Finalizado" -ForegroundColor Green 

No hay comentarios:

Publicar un comentario