اختيار أرشيفي لسجلات النسخ الاحتياطي

مرحبا بالجميع!


في هذه المقالة ، أود أن أتحدث عن كيفية اختيار أرشيفي لضغط سجلات نظام المكتب الأمامي لدينا.


يتمثل القسم الذي أعمل فيه في تطوير وصيانة نظام المكتب الأمامي الموحد للبنك. أنا مسؤول عن صيانتها ومراقبتها و DevOps.


نظامنا هو تطبيق محمّل للغاية يخدم أكثر من 5000 مستخدم فريد يوميًا. اليوم هو "متراصة" مع جميع مزاياها وعيوبها. ولكن الآن عملية نقل الوظائف إلى خدمات microservices مستمرة بنشاط.


كل يوم ، يولد نظامنا أكثر من 130 غيغابايت من السجلات الخام وعلى الرغم من أننا نستخدم ENG stack (Elasticsearch Nxlog Graylog) ، تحتوي سجلات الملفات على مزيد من المعلومات (على سبيل المثال ، أخطاء تتبع المكدس) وبالتالي تتطلب الأرشفة والتخزين.


نظرًا لأن موقع التخزين محدود ، فإن السؤال الذي يطرح نفسه هو: "وأي ملف أرشيف سوف يتعامل بشكل أفضل مع هذه المهمة."


لحل هذه المشكلة ، كتبت برنامج نصي PowerShell الذي أجرى التحليل لي.


تتمثل مهمة البرنامج النصي في استدعاء أرشيفات rar و 7z و zip ذات معلمات ضغط مختلفة ، لحساب سرعة تكوين الأرشيف ، وكذلك مساحة القرص المستخدمة.


ArchSearch.ps1
#Requires -Version 4.0 #  ,      Clear-Host #   ,     Set-Location $PSScriptRoot #  ,      $Archive = "Archive" $ArchFileName = "ArchFileName" [array]$path = (Get-ChildItem '.\logs').DirectoryName|Select-Object -Unique #      -.  ,     . if ((Test-Path -Path ".\$Archive") -ne $true){ New-Item -Path .\ -Name $Archive -ItemType Directory -Force } else { #    -    Get-ChildItem .\$Archive|Remove-Item -Recurse -Force } #      [array]$table=@() #   Rar #rar # m<0..5> Set compression level (0-store...3-default...5-maximal) 1..5|foreach{ $CompressionLevel = $("-m" + $_) $mc = Measure-Command {cmd /c .\rar.exe a -ep1 -ed $CompressionLevel -o+ -tsc .\$Archive\$($ArchFileName + $_) "$path"} [math]::Round(($mc.TotalMilliseconds), 0) $ArchFileNamePath = ".\$Archive\$($ArchFileName + $_ + ".rar")" $table += ""|Select-Object -Property @{name="ArchFileName"; expression={$ArchFileNamePath -split "\\"|Select-Object -Last 1}},` @{name="CompressionLevel"; expression={$CompressionLevel}},@{name="Extension"; expression={"rar"}},@{name="Size"; expression={(Get-ChildItem $ArchFileNamePath).Length}},` @{name="Time"; expression={[math]::Round(($mc.TotalMilliseconds), 0)}},` @{name="Size %"; expression={0}},@{name="Time %"; expression={0}},@{name="Result %"; expression={0}} } #   7z #7z # -mx[N] : set compression level: -mx1 (fastest) ... -mx9 (ultra) #cmd /c "$env:ProgramFiles\7-Zip\7z.exe" a -mx="$MX" -mmt="$MMT" -t7z -ssw -spf $($ArchFileName + "Fastest") "$path" 1..9|foreach{ $CompressionLevel = $("-mx=" + $_) $mc = Measure-Command {cmd /c "$env:ProgramFiles\7-Zip\7z.exe" a $CompressionLevel -t7z -ssw -spf .\$Archive\$($ArchFileName + $_) $path} #-mmt="$MMT" [math]::Round(($mc.TotalMilliseconds), 0) $ArchFileNamePath = ".\$Archive\$($ArchFileName + $_ + ".7z")" $table += ""|Select-Object -Property @{name="ArchFileName"; expression={$ArchFileNamePath -split "\\"|Select-Object -Last 1}},` @{name="CompressionLevel"; expression={$CompressionLevel}},@{name="Extension"; expression={"7z"}},@{name="Size"; expression={(Get-ChildItem $ArchFileNamePath).Length}},` @{name="Time"; expression={[math]::Round(($mc.TotalMilliseconds), 0)}},` @{name="Size %"; expression={0}},@{name="Time %"; expression={0}},@{name="Result %"; expression={0}} } #   zip (  PS "Compress-Archive") #zip 1..2|foreach{ Switch ($_){ 1{$CompressionLevel = "Fastest"} 2{$CompressionLevel = "Optimal"} } $mc = Measure-Command {Compress-Archive -Path $path -DestinationPath .\$Archive\$($ArchFileName + $_) -CompressionLevel $CompressionLevel -Force} [math]::Round(($mc.TotalMilliseconds), 0) $ArchFileNamePath = ".\$Archive\$($ArchFileName + $_ + ".zip")" $table += ""|Select-Object -Property @{name="ArchFileName"; expression={$ArchFileNamePath -split "\\"|Select-Object -Last 1}},` @{name="CompressionLevel"; expression={$CompressionLevel}},@{name="Extension"; expression={"zip"}},@{name="Size"; expression={(Get-ChildItem $ArchFileNamePath).Length}},` @{name="Time"; expression={[math]::Round(($mc.TotalMilliseconds), 0)}},` @{name="Size %"; expression={0}},@{name="Time %"; expression={0}},@{name="Result %"; expression={0}} } #     Size     [0] -     $Size = ($table|Sort-Object -Property Size)[0].Size / 100 #     Time     [0] -      $Time = ($table|Sort-Object -Property Time)[0].Time / 100 #    $table|foreach { $_.time $_."Size %" = [math]::Round(($_.Size / $Size), 0) $_."Time %" = [math]::Round(($_.Time / $Time), 0) if ($_."Size %" -ge $_."Time %"){ $_."Result %" = $_."Size %" - $_."Time %" } else { $_."Result %" = $_."Time %" - $_."Size %" } } #        "Size %" -     $table|Sort-Object -Property "Size %","Result %"|Select-Object -First 1|Format-Table -AutoSize #        "Result %" -          $table|Sort-Object -Property "Result %","Size %","Time %"|Select-Object -First 1|Format-Table -AutoSize $table|Sort-Object -Property "Size %","Result %"|Select-Object -First 1|Format-Table -AutoSize $table|Sort-Object -Property "Result %","Size %","Time %"|Select-Object -First 1|Format-Table -AutoSize #  !   ,     Get-ChildItem .\$Archive|Remove-Item -Force 

العمل التحضيري:


 #   ,   PowerShell  4.0 ($PSVersionTable): #Requires -Version 4.0 #  ,      Clear-Host #   ,     (   .\) Set-Location $PSScriptRoot 

 #  ,      $Archive = "Archive" $ArchFileName = "ArchFileName" [array]$path = (Get-ChildItem '.\logs').DirectoryName|Select-Object -Unique #      -.  ,      if ((Test-Path -Path ".\$Archive") -ne $true){ New-Item -Path .\ -Name $Archive -ItemType Directory -Force } else { #   ,     Get-ChildItem .\$Archive|Remove-Item -Recurse -Force } #      [array]$table=@() 

نحن نحلل بمزيد من التفاصيل


 #     1  5       foreach 1..5|foreach{ 

 #    $CompressionLevel   1  5($_),       $CompressionLevel = $("-m" + $_) 

 #  Measure-Command     ,   {} $mc = Measure-Command {cmd /c .\rar.exe a -ep1 -ed $CompressionLevel -o+ -tsc .\$Archive\$($ArchFileName + $_) "$path"} 

 #       [math]::Round(($mc.TotalMilliseconds), 0) #    $ArchFileName + $_ + ".rar": Archive1.rar $ArchFileNamePath = ".\$Archive\$($ArchFileName + $_ + ".rar")" #   $table (+=)   $table += ""|Select-Object -Property @{name="ArchFileName"; expression={$ArchFileNamePath -split "\\"|Select-Object -Last 1}},` @{name="CompressionLevel"; expression={$CompressionLevel}},@{name="Extension"; expression={"rar"}},@{name="Size"; expression={(Get-ChildItem $ArchFileNamePath).Length}},` @{name="SizeAVD"; expression={0}},@{name="Time"; expression={[math]::Round(($mc.TotalMilliseconds), 0)}},` @{name="Size %"; expression={0}},@{name="Time %"; expression={0}},@{name="Result %"; expression={0}} } 

 #     Size     [0] -     $Size = ($table|Sort-Object -Property Size)[0].Size / 100 #     Time     [0] -      $Time = ($table|Sort-Object -Property Time)[0].Time / 100 #    $table|foreach { $_.time $_."Size %" = [math]::Round(($_.Size / $Size), 0) $_."Time %" = [math]::Round(($_.Time / $Time), 0) if ($_."Size %" -ge $_."Time %"){ $_."Result %" = $_."Size %" - $_."Time %" } else { $_."Result %" = $_."Time %" - $_."Size %" } } #        "Size %" -     $table|Sort-Object -Property "Size %","Result %"|Select-Object -First 1|Format-Table -AutoSize #        "Result %" -          $table|Sort-Object -Property "Result %","Size %","Time %"|Select-Object -First 1|Format-Table -AutoSize #  !   ,    . Get-ChildItem .\$Archive|Remove-Item -Force 

 $table|Sort-Object -Property "Size %","Result %"|Format-Table -AutoSize 

ArchFileNameمستوى الضغطتمديدحجموقت٪ الحجمالوقت٪نتيجة٪
ArchFileName8.7z- م = 87Z265115206240410016741574
ArchFileName9.7zم = 97Z265115206461410017331633
ArchFileName7.7z-mx = 77Z289481765283210914171308
ArchFileName6.7z- م = = 67Z30051742373391131002889
ArchFileName5.7z- م = = 57Z3123935535169118943825
ArchFileName4.rar-m4رر3351469311426126306180
ArchFileName5.rar-m5رر3346515212894126346220
ArchFileName3.rar-M3رر336980799835127264137
ArchFileName2.rar-m2رر34399885835213022494
ArchFileName4.7z- م = = 47Z38926348647014717427
ArchFileName3.7z-mx = 37Z44545819588916815810
ArchFileName2.7z-mx = 27Z51690114475419512867
ArchFileName1.rar-m1رر53605833460020212379
ArchFileName1.7z-mx = 17Z574721723728217100117
ArchFileName2.zipالأمثلالرمز البريدي6573324214025248376128
ArchFileName1.zipأسرعالرمز البريدي81556824903130824266

 $table|Sort-Object -Property "Result %","Size %","Time %"|Format-Table -AutoSize 

ArchFileNameمستوى الضغطتمديدحجموقت٪ الحجمالوقت٪نتيجة٪
ArchFileName3.7z-mx = 37Z44545819588916815810
ArchFileName4.7z- م = = 47Z38926348647014717427
ArchFileName1.zipأسرعالرمز البريدي81556824903130824266
ArchFileName2.7z-mx = 27Z51690114475419512867
ArchFileName1.rar-m1رر53605833460020212379
ArchFileName2.rar-m2رر34399885835213022494
ArchFileName1.7z-mx = 17Z574721723728217100117
ArchFileName2.zipالأمثلالرمز البريدي6573324214025248376128
ArchFileName3.rar-M3رر336980799835127264137
ArchFileName4.rar-m4رر3351469311426126306180
ArchFileName5.rar-m5رر3346515212894126346220
ArchFileName5.7z- م = = 57Z3123935535169118943825
ArchFileName6.7z- م = = 67Z30051742373391131002889
ArchFileName7.7z-mx = 77Z289481765283210914171308
ArchFileName8.7z- م = 87Z265115206240410016741574
ArchFileName9.7zم = 97Z265115206461410017331633

 #  !   ,    . Get-ChildItem .\$Archive|Remove-Item -Force 

النتيجة:
الأكثر اقتصادا من حيث مساحة القرص كان 7z مع نسبة ضغط -mx = 8 و -mx = 9



كان أسرع وقت لإنشاء أرشيف هو 7z مع نسبة ضغط -mx = 1



كانت السرعة المثلى في السرعة والمساحة المشغولة هي 7z مع معدل ضغط -mx = 3



نختار 7z مع نسبة ضغط -mx = 8 ، لأن حجم الأرشيف هو -mx 9 ، لكنه يعمل بشكل أسرع قليلاً.


عظيم ، تم تحديد أرشيف ونسبة الضغط ، والآن دعونا أرشفة السجلات!


نحن بحاجة إلى حل المشاكل التالية:


  1. تجنب تحميل خادم عالية أثناء العملية.
  2. معالجة جميع المجلدات باستخدام سجلات مجلد فرعي.
  3. احذف الأرشيفات الأقدم من 30 يومًا (حتى لا ينفد من مساحة القرص).
  4. أنشئ أرشيفات كل يوم حسب الوقت الذي تم فيه تعديل الملفات.

ArchLogs.ps1
 #Requires -Version 4.0 #          #SCHTASKS /Create /SC DAILY /ST 22:00 /TN ArchLogs /TR "C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe C:\Scripts\ArchLogs.ps1" /RU "NT AUTHORITY\NETWORKSERVICE" /F /RL HIGHEST #  ,      Clear-Host #   ,     Set-Location $PSScriptRoot #           . #  1 Function Set-MMTCore { $Core = (Get-WmiObject –class Win32_processor|Measure-Object NumberOfLogicalProcessors -sum).Sum / 2 $CoreTMP = $Core / 4 IF ($Core -lt 4) { $Core = $Core -1 } Else { $Core = $Core - $CoreTMP } [math]::Round($Core) } #    $MX = 8 #     $MMT = Set-MMTCore #  ,      $SearchFolder = "C:\inetpub" #     $SearchFolder $InetpubFolder = Get-ChildItem $SearchFolder #     Logs #  2 $LogsFolder = $InetpubFolder|foreach {Get-ChildItem $_.Fullname|Where-Object{$_.PSIsContainer -eq $true}|Where-Object{$_.name -eq "logs"}} #  ,      $Archive = "Archive" $ArchiveFile = "ArchFiles.txt" #      $LogsFolder   $LogsFolderName   foreach($LogsFolderName in $LogsFolder.Fullname){ $LogsFolderName #   $Archive,       IF ((Test-Path -Path "$LogsFolderName\$Archive") -ne $true){New-Item -Path $LogsFolderName -Name $Archive -ItemType Directory -Force} #    30  #  3 Get-ChildItem "$LogsFolderName\$Archive"|Where-Object {$_.LastWriteTime -le (Get-Date).AddDays(-30)}| Remove-Item -Force #     [Array]$ArchiveItems = Get-ChildItem -Path $LogsFolderName -Exclude $Archive #   , .    -  IF ($ArchiveItems.Count -ne ^_^quot&#0;quot^_^){ #       $AllLogsFiles = Get-ChildItem $ArchiveItems -Recurse <#-Filter *.log#>|Where-Object {$_.LastWriteTime -lt (Get-Date).Date} #     #  4 $AllData = ($AllLogsFiles|Sort-Object -Property LastWriteTime).LastWriteTime.Date|Select-Object -Unique $AllData foreach ($Data in $AllData){ IF ($ArchiveItems.Count -ne ^_^quot&#0;quot^_^){ #         ($AllLogsFiles|Where-Object {$_.LastWriteTime -lt (Get-Date).Date}|Where-Object {$_.LastWriteTime -ge (Get-Date $Data) -and $_.LastWriteTime -lt (Get-Date $Data).AddDays(1)}).FullName|Out-File .\$ArchiveFile -Force -Encoding default Write-Host "===" $Data Write-Host "===" #      IF ($(Get-Content .\ArchFiles.txt -Encoding default) -ne $null){ $ArchiveFileName =$(($LogsFolderName.Remove($LogsFolderName.LastIndexOf("\"))) -split "\\"|Select-Object -Last 1) + "_" + $(Get-Date $Data -Format dd-MM-yyyy) cmd /c "$env:ProgramFiles\7-Zip\7z.exe" a -mx="$MX" -mmt="$MMT" -t7z -ssw -sdel "$LogsFolderName\$Archive\$ArchiveFileName" "@$ArchiveFile" #        IF(Test-Path ".\$ArchiveFile"){Remove-Item ".\$ArchiveFile" -Force} #      Logs $LogsFolderName|foreach {Get-ChildItem $_|Where-Object {(Get-ChildItem -Path $_.FullName) -eq $null}|Remove-Item -Force} } } } } } 

هنا لن أرسم كل سطر من البرنامج النصي (الموصوف في التعليقات) ، لكنني أطوِّل فقط على وظيفة Set-MMTCore ، والتي تتيح لنا حساب عدد مؤشرات الترابط لـ 7z حتى لا يتم تحميل المعالج على خادمنا:


 Function Set-MMTCore { #        2 $Core = (Get-WmiObject –class Win32_processor|Measure-Object NumberOfLogicalProcessors -sum).Sum / 2 #      4 $CoreTMP = $Core / 4 IF ($Core -lt 4) { $Core = $Core -1 } Else { $Core = $Core - $CoreTMP } #    [math]::Round($Core) } 

بدون استخدام وظيفة Set-MMTCore

يمكن أن نرى أن وحدة المعالجة المركزية تقع على 100 ٪. هذا يعني أننا سوف نتسبب حتماً في حدوث مشاكل على الخادم ، بالإضافة إلى تلقي تنبيه من نظام المراقبة.



عند استخدام وظيفة Set-MMTCore

يمكن أن نرى أن وحدة المعالجة المركزية هي 30-35 ٪. هذا يعني أن استخدام وظيفة Set-MMTCore يسمح لك بأرشفة الملفات دون التأثير على تشغيل الخادم.



نتيجة البرنامج النصي النسخ الاحتياطي:


المجلد قبل الأرشفة:


المجلد بعد الأرشفة:


الملفات التي تم إنشاؤها أثناء عملية الأرشفة:


الملفات في الأرشيف:


Source: https://habr.com/ru/post/ar484414/


All Articles