‘ოპტიმიზაცია’ კატეგორიაში გამოქვეყნებული წერილები

RAID მასივები

Sunday, May 10th, 2009

ამ საკითხზე სემინარი მქონდა მოსამზადებელი და ბარემ პოსტსაც მივუძღვნი :)

რა არის ეს RAID (Redundant Array of Independent Disks) და რისთვის გამოიყენება? : )

როგორ შევინახოთ ინფორმაცია სისტემის აგების დროს დამოკიდებულია თვითონ ამოცანაზე. რა გვჭირდება: დიდი რაოდენობით ჩაწერა, წაკითხვა, სისწრაფე, საიმედოობა?

მაგალითად, არსებობს ამოცანები, სადაც კრიტიკული მნიშვნელობა აქვს ინფორმაციის საიმედოდ შენახვას და მასზე წვდომის შესაძლებლობას დროის ნებისმიერ მომენტში. ანუ, დისკის დაზიანების დროს უნდა არსებობდეს მისი შემცვლელი იგივე ინფორმაციით და თანაც რაც შეიძლება სწრაფად.

არის ამოცანები, სადაც წარმადობა უფრო პრიორიტეტულია. მაგალითად, როდესაც სერვერიდან დიდი რაოდენობით ვიდეო ნაკადები მოდის.

თავდაპირველად RAID-ის ძირითადი იდეა იყო, რომ რამდენიმე მყარი დისკი გაეერთიანებინა დისკების მასივში და ამით გაეუმჯობესებინა წარმადობა, რომელიც ერთ დიდი ზომის დისკს ჰქონდა.

ახლა RAID-ის არქიტექტურული დიზაინებიდან ყველაზე გავრცელებულია 5 ვარიანტი:  RAID 0, RAID 1, RAID 5, RAID 6, RAID 10.

ისინი ძირითადად ორ მიზანს ემსახურებიან: მონაცემთა შენახვის საიმედოობის გაზრდას, შეტანა/გამოტანის (დისკზე ჩაწერა/წაკითხვის) წარმადობის გაზრდას.

განვიხილოთ თითოეული მათგანი:

RAID 0

ჩაწერის დროს მონაცემები იყოფა ფრაგმენტებად და ეს ფრაგმენტები სათითაოდ ნაწილდება მასივში შემავალ დისკებზე. წაკითხვის დროს კი ყველა დისკიდან ერთდროულად ხდება წაკითხვა.

raid0

up_iconრაც უფრო მეტი დისკია, უფრო მეტად იზრდება სისწრაფე. უხეშად რომ შევადარო, ეს იგივეა, წყლის არხიდან ერთის მაგივრად რამდენიმე მილი გამოვიყვანოთ. იგივე რაოდენობის წყალს უფრო მალე მივიღებთ.

up_iconარ ვკარგავთ ადგილს. მთლიანად ვიყენებთ დისკების მოცულობას ჩვენი ინფორმაციისთვის.

down_iconასეთი სტრუქტურის სისუსტე დისკის დაზიანების დროს ჩანს. საკმარისია ერთ-ერთი მათგანის ამოვარდნა, რომ მთელი მასივი გადასაგდებია. წარმოიდგინეთ, წიგნში ყოველ სიტყვას მისი მესამედი რომ ჩამოვაჭრათ. წიგნი გამოუსადეგარი გახდება. თანაც მისი აღდგენა შეუძლებელია.

(more…)

შემთხვევითი ჩანაწერის ამორჩევა მონაცემთა ბაზის ცხრილიდან

Wednesday, December 31st, 2008
ალბათ ბევრგან დაგჭირვებიათ შემთხვევითი ჩანაწერის ამოღება (random წერილის გამოყვანა ბლოგზე, random ფრაზა, random წიგნი - ბიბლიოთეკის საიტზე, random პროდუქტი - მაღაზიის საიტზე, ა.შ.) და შეიძლება რაიმე კარგი მეთოდიც გაქვთ შერჩეული ამისთვის.
მე კვლევები არ მიწარმოებია :))) ამ საკითხზე. უბრალოდ შემხვდა სასარგებლო სტატია, სადაც ამ მეთოდების განხილვაა მოყვანილი და მათი სისწრაფეებია შედარებული.

მეთოდი 1:

ვიყენებთ RAND() ფუნქციას, რომელიც float ტიპის რიცხვს აბრუნებს 0-დან 1-მდე.
sql მოთხოვნას შემდეგი სახე აქვს: SELECT * FROM `table` ORDER BY RAND() LIMIT 0,1;

როგორც სტატიის ავტორი წერს, მეთოდის პრობლემა მისი შესრულების დროა. MySQL-ს ყველა ჩანაწერი დროებით ცხრილში გადააქვს, თითოეულს ანიჭებს რაღაც შემთხვევით ინდექსს სორტირებისთვის. შემდეგ შედეგებს ასორტირებს და აბრუნებს პირველ ჩანაწერს.

უკეთესი მიდგომის აზრი ის არის, რომ ჯერ შეირჩეს შემთხვევითი რიცხვი და ამ შემთხვევითი რიცხვის მიხედვით ამოირჩეს მხოლოდ ერთი ჩანაწერი.

მეთოდი 2:

იმ შემთხვევაში, თუ თითოეულ ჩანაწერს უნიკალური გასაღები (მაგალითად id) გააჩნია, მაშინ შეგვიძლია ავირჩიოთ შემთხვევითი id უმცირეს და უდიდეს id-ებს შორის და შემდეგ დავაბრუნებინოთ იმ არჩეული id-ის ჩანაწერი. 

უდიდესი და უმცირესი id-ის გასაგებად MAX() და MIN() ფუნქციები გამოვიყენოთ.

$range_result = mysql_query( ” SELECT MAX(`id`) AS max_id , MIN(`id`) AS min_id FROM `table` “);
$range_row = mysql_fetch_object( $range_result ); 
$random = mt_rand( $range_row->min_id , $range_row->max_id );
$result = mysql_query( ” SELECT * FROM `table` WHERE `id` >= $random LIMIT 0,1 “);
მეთოდი საკმაოდ შეზღუდულია, რადგან შეიძლება ცხრილს უნიკალური გასაღები საერთოდ არ ჰქონდეს. ამიტომ მესამე მეთოდში MySQL-ის LIMIT-ს ვეყრდნობით.

მეთოდი 3:

LIMIT ორ არგუმენტს იღებს. მაგალითად LIMIT 5,10  დააბრუნებს ჩანაწერებს 6-დან 15-მდე. ათვლა 0-დან იწყება.  პირველი არგუმენტი offset-ია (არ ვიცი როგორ ითარგმნება), ხოლო მეორე - offset-დან ათვლილი წამოსაღები ჩანაწერების მაქსიმალური რაოდენობა.

რომ გამოვთვალოთ offset პირველ ჩანაწერამდე - დავაგენერიროთ შემთხვევითი რიცხვი MySQL-ის RAND() ფუნქციის საშუალებით. შემდეგ მიღებული რიცხვი გადავამრავლოთ ცხრილში არსებულ ჩანაწერთა რაოდენობას (ამ რაოდენობას COUNT() ფუნქციის მივიღებთ). რადგან LIMIT მხოლოდ მთელ რიცხვებს იღებს არგუმენტებად, ეს ნამრავლი უნდა დავამრგვალოთ - გამოვიყენოთ FLOOR() ფუნქცია.

FLOOR() არითმეტიკული ფუნქციაა, რომელიც გამოთვლის უდიდეს მთელ რიცხვს გადაცემულ პარამეტრამდე. საბოლოოდ, კოდს ასეთი სახე ექნება:

$offset_result = mysql_query( ” SELECT FLOOR(RAND() * COUNT(*)) AS `offset` FROM `table` “);

$offset_row = mysql_fetch_object( $offset_result ); 
$offset = $offset_row->offset;

$result = mysql_query( ” SELECT * FROM `table` LIMIT $offset, 1 ” );
 
MySQL 4.1 და უფრო მაღალ ვერსიებში ეს ორი მეთოდი შეგვიძლია ასე გავაერთიანოთ:

მეთოდი 4:

SELECT * FROM `table` WHERE id >= (SELECT FLOOR( MAX(id) * RAND()) FROM `table` ) ORDER BY id LIMIT 1;

ამ მეთოდს იგივე ნაკლი აქვს, რაც მეორეს. ის მხოლოდ უნიკალურ გასაღებიან ცხრილებთან მუშაობს.

სტატიის ავტორმა მეთოდების სისწრაფეები შეადარა და სოფტის და ჰარდის სპეციპიკაციებს თუ არ ჩავუღრმავდებით, მიახლოებით ასეთი შედეგი მიიღება:

ყველაზე ნელი პირველი მეთოდია. ვთქვათ, რომ მას დროის 100% დასჭირდა შესრულებისთვის.
მეორე მეთოდს 79%.
მესამეს - 13%.
მეოთხეს - 16%.
გამოდის, რომ ყველაზე სწრაფია მესამე მეთოდი.