RE:NODE

რესურსები11 წუთის საკითხავი

რას ცვლის NVMe სინამდვილეში და რას - არა

NVMe უფრო სწრაფი სერვერი არ არის, ეს პატარა ჩაწერებზე დაბალი latency-ა. რომელ ოპერაციებს ცვლის - შენახვები, რესტარტები, backup-ები, ბაზის commit-ები - და რომელს არასოდეს ეხება.

განახლებულია

0 მკითხველი

NVMe ჰოსტინგის ყველა შედარებაში ჩნდება და თითქმის არასოდეს არის ახსნილი, ამიტომ დასრულდა ისე, რომ „სწრაფს" ნიშნავს იმავე ბუნდოვანი გაგებით, როგორც „პრემიუმ აპარატურა". ის უფრო სწრაფი სერვერი არ არის. ეს საცავის პროტოკოლია, რომელსაც SATA SSD-ის თითო მოთხოვნის latency-ის დაახლოებით მეათედი აქვს და პარალელიზმისთვის აგებული რიგის დიზაინი, და ის იმდენად მნიშვნელოვანია, რამდენადაც შენი დატვირთვა დისკს ეხება. CPU-ზე დამოკიდებული shooter-ისთვის ეს თითქმის ნულია. ტრანზაქციების commit-ის მქონე ბაზისთვის, ან დიდი სამყაროსთვის, რომელიც ყოველ ათ წუთში ინახავს, ან 40 GB backup არქივისთვის, ეს განსხვავებაა hitch-ს შორის, რომელსაც ვერავინ ამჩნევს, და იმას შორის, რომელიც მოთამაშეებს გიკარგავს. ეს პოსტი ამ შემთხვევების გარჩევაზეა.

რა არის NVMe სინამდვილეში#

დაბნეულობა არასწორი რამეების შედარებიდან მოდის. NVMe ფლეშ მეხსიერების ტიპი არ არის; NVMe დისკისა და SATA SSD-ის ჩიპები ერთი და იგივე რამეა. განსხვავება ისაა, როგორ ესაუბრება მათ კომპიუტერი.

SATA SSD საუბრობს AHCI-ით, პროტოკოლით, რომელიც 2004 წელს მექანიკური დისკებისთვის შეიქმნა. AHCI-ს აქვს ერთი ბრძანებების რიგი 32 სიღრმის და ვარაუდობს, რომ მოთხოვნის ძვირი ნაწილი ფიზიკური მკლავის გადაადგილებაა. SATA III ხაზი პრაქტიკაში დაახლოებით 550 MB/s-ზე ჭერს აღწევს.

NVMe ფლეშისთვის შეიქმნა და პირდაპირ PCIe-ზე ზის. ის მხარს უჭერს 65 535 რიგამდე, თითოეული 65 536 ბრძანებით, რაც აბსურდულად ჟღერს, სანამ არ გაიხსენებ, რომ ფლეში შიგნით ათეულობით ჩიპზე პარალელურია და AHCI მათ ყველას ვერასოდეს დაკავებდა. PCIe 3.0 x4 დისკი დაახლოებით 3 500 MB/s-ს იძლევა; PCIe 4.0 x4 დისკი - დაახლოებით 7 000 MB/s-ს.

7 200 rpm HDDSATA SSDNVMe (PCIe 3.0)
მიმდევრობითი კითხვა150-200 MB/s~550 MB/s~3 500 MB/s
4K შემთხვევითი კითხვის IOPS100-20080 000-100 000300 000-1 000 000
მოთხოვნის ტიპური latency5-10 ms100-200 us20-100 us
რიგის სიღრმე132პრაქტიკულად შეუზღუდავი

გამტარობის სტრიქონი ის არის, რასაც მარკეტინგი ციტირებს და რომელსაც ყველაზე ნაკლები მნიშვნელობა აქვს. თითქმის არაფერი, რასაც გეიმ სერვერი აკეთებს, 3 GB მიმდევრობითი კითხვა არ არის. ბოლო ორი სტრიქონია მნიშვნელოვანი: რამდენ ხანს გრძელდება ერთი პატარა მოთხოვნა და რამდენი შეიძლება ერთდროულად იყოს ჰაერში. სწორედ იქ ცხოვრობს სიდიდის რიგის განსხვავება, და სწორედ ამიტომ იქცევა სრულიად სხვაგვარად დატვირთვა, რომელიც ათასობით პატარა წაკითხვისა და ჩაწერისგან შედგება - რაც სამყაროს შენახვაცაა და ბაზის commit-იც.

საცავი მარტო დისკი არ არის. RE:NODE ყველგან NVMe-ს იყენებს, ZFS pool-ზე, და ისეთი ფაილური სისტემა, როგორიც ZFS-ია, საკუთარ ქცევას ამატებს: ყოველი ბლოკი checksum-ირდება, ამიტომ უხმო დაზიანება მიწოდების ნაცვლად აღმოჩენილია, ჩაწერა copy-on-write-ია, ამიტომ დენის გათიშვა ნახევრად ჩაწერილის ნაცვლად თანმიმდევრულ ფაილურ სისტემას ტოვებს, და RAM-ში კითხვის ქეში ხშირად ნიშნავს, რომ ცხელი სამუშაო ნაკრები დისკს საერთოდ არ აღწევს. დისკი დაბალ ზღვარს აყენებს; ფაილური სისტემა წყვეტს, რამდენად ხშირად ეჯახები მას.

სად ეხება გეიმ სერვერი დისკს#

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

სამყაროს სერიალიზაციაბუფერირებულიflush-ზე ან fsync-ზედაბლოკილია დასრულებამდე, თუ სინქრონულიაGame serverმთავარი threadwrite() გამოძახებასწრაფად ბრუნდებაPage cacheRAM-შიფაილური სისტემაZFS, ext4NVMe მოწყობილობარეალური flush
ერთი სამყაროს შენახვის ჩაწერის გზა

გეიმ სერვერზე დისკის მუშაობა შვიდ დავალებად იყოფა, და მათი პროფილები ძალიან განსხვავებულია:

  • სამყაროს შენახვები. პერიოდული და ჩვეულებრივ ნაწილობრივ მთავარ thread-ზე. Minecraft ცვლილებებს chunk-ებს region ფაილებში წერს (region/r.0.0.mca, თითოეული chunk-ების 32x32 ბლოკს შეიცავს); Valheim მთელი სამყაროსთვის ერთ .db ფაილს წერს; Palworld და Unreal-ზე დაფუძნებული გადარჩენის თამაშები დიდ save blob-ებს წერს. დიდი სამყაროს შენახვა ათასობით პატარა ჩაწერაა ან ერთი უზარმაზარი, და ორივე დისკზეა დამოკიდებული.
  • Chunk-ებისა და ზონების ჩატვირთვა. მოთამაშე, რომელიც გამოუკვლეველ ტერიტორიაზე შედის, დისკიდან კითხულობს, ან აგენერირებს და შემდეგ წერს. ეს ის არის, რაც stutter-ს იწვევს, როცა ვინმე რუკაზე დაფრინავს.
  • ლოგები. უწყვეტი, პატარა, მხოლოდ დასამატებელი. იაფია, სანამ plugin ყოველ ბლოკის დადებას არ ლოგავს.
  • Plugin-ებისა და mod-ების ბაზები. EssentialsX-ის მომხმარებლის ფაილები, CoreProtect-ის ბლოკების ლოგი, SQLite ფაილი, რომელსაც სერვერზე ყოველი მოქმედება ურტყამს. ეს უხმოდ ბევრ Minecraft სერვერზე ყველაზე მძიმე დისკის დატვირთვაა.
  • გაშვება. jar-ის ან თამაშის binary-ების, mod სიის, plugin-ებისა და spawn chunk-ების კითხვა. mod-ებიანი სერვერი რამდენიმე გიგაბაიტს კითხულობს, სანამ კავშირს მიიღებს.
  • Backup-ები. მთელი სამყაროს წაკითხვა და შეკუმშული არქივის ჩაწერა. თითქმის წმინდა დისკი.
  • განახლებები და Workshop ჩამოტვირთვები. დიდი მიმდევრობითი ჩაწერები, პლუს გადამოწმების კითხვები.

სად ჩანს NVMe, თანმიმდევრობით#

ოპერაციარა არისრას ცვლის NVMe
სამყაროს პერიოდული შენახვაათასობით პატარა ჩაწერაგაყინვა მოკლდება, ზოგჯერ უხილავი ხდება
Backup და აღდგენაყველაფრის წაკითხვა, არქივის ჩაწერაწუთები მისი ნაწილი ხდება
სერვერის გაშვებადიდი მიმდევრობითი და შემთხვევითი კითხვებიშესამჩნევად უფრო სწრაფია mod-ებიან სერვერებზე
Chunk-ის ჩატვირთვა კვლევისასპატარა შემთხვევითი კითხვებინაკლები stutter, როცა მოთამაშეები მოძრაობენ
ბაზის commitfsync თითო ტრანზაქციაზეყველაზე დიდი ერთი განსხვავება
Plugin-ის SQLite ჩაწერებიმუდმივი პატარა სინქრონული ჩაწერებიხსნის გავრცელებულ დამალულ tick-ის ღირებულებას
ლოგის ჩაწერებიპატარა დამატებებიარაფერი, რასაც შეამჩნევ

შენახვის შემთხვევა დეტალს იმსახურებს, რადგან სწორედ მას გრძნობენ მოთამაშეები. უმეტესი თამაში სამყაროს სერიალიზაციას აკეთებს და წერს, სანამ სიმულაცია ელოდება. სამყაროზე, რომელიც ათობით გიგაბაიტამდე გაიზარდა, ეს ჩაწერა tick-ის ციკლის ყველაზე გრძელი ერთი ბლოკია, და ის ტაიმერზე ხდება, სამუდამოდ. Valheim სუფთა მაგალითია: მთელი სამყარო ერთი ფაილია, ყოველ -saveinterval წამში იწერება, და მომწიფებულ სამყაროზე პაუზა გაზომვადია. ინტერვალის შემცირება ამცირებს, რამდენის დაკარგვა შეგიძლია ავარიისას და ზრდის, რამდენად ხშირად იხდი პაუზას, და სწრაფი საცავი ის არის, რაც ამ გაცვლას იაფს ხდის. Valheim-ის გზამკვლევი შენახვის პარამეტრებს გადის.

Backup-ები მეორე პატიოსანი მოგებაა და თითქმის წმინდა დისკია. ღამის დავალება, რომელიც 30 GB სამყაროს კითხულობს და შეკუმშულ არქივს წერს, ზუსტად იმ სამუშაოს აკეთებს, რისთვისაც საცავია შეფასებული. ნელ დისკებზე ეს დავალება საღამოს ემთხვევა, თამაშს ეჯიბრება და იდუმალ lag-ად იქცევა, რომელსაც ყველა ჰოსტს აბრალებს. NVMe-ზე ის იმაზე ადრე მთავრდება, ვიდრე ვინმე შეამჩნევს. ის ასევე ცვლის რიცხვს, რომელიც გადაუდებელ შემთხვევაში ნამდვილად მნიშვნელოვანია, ანუ არა იმას, რამდენ ხანს გაგრძელდა backup, არამედ იმას, რამდენ ხანს გრძელდება აღდგენა - იხილე backup-ები, რომლებიც მართლა აღდგება და აღდგენის გამოცდა, სანამ დაგჭირდება.

სად არაფერს ცვლის საერთოდ#

ეს ნაწილია, რომელსაც ჰოსტინგის გვერდები აკლებენ.

Tick rate CPU-ზე დამოკიდებულ სერვერზე. თუ სიმულაცია თავის ბიუჯეტში ნაბიჯს ვერ ასრულებს, რადგან სასიმულაციო ძალიან ბევრია, დისკი არასოდეს იყო ჩართული. უფრო სწრაფი საცავი არაფერს ცვლის, და ფული უკეთესად დაიხარჯებოდა საათის სიხშირეზე. CPU თუ RAM არის ტრიაჟი, რომ გაიგო, რომელი გაქვს.

ქსელის latency. მოთამაშე 180 ms-ზე სერვერიდან 180 ms-ზეა. საცავს ამის შესახებ აზრი არ აქვს.

ყველაფერი, რაც უკვე მეხსიერებაშია. აქტიური სამყარო, entity სია, plugin-ის state, JVM heap: არცერთი დისკს არ ეხება შენახვებს შორის. სერვერი, რომელსაც საკმარისი მეხსიერება აქვს სამუშაო ნაკრების დასატევად, დისკიდან იშვიათად კითხულობს, სწორედ ამიტომ ხსნის მეხსიერების დამატება ზოგჯერ იმას, რაც საცავის პრობლემას ჰგავს.

პატარა სერვერის სტაბილური მდგომარეობის წარმადობა. Counter-Strike სერვერი სტატიკურ რუკაზე რუკას ერთხელ კითხულობს და შემდეგ დანარჩენ ღამეს თითქმის არანაირ დისკის I/O-ს არ აკეთებს. ამ გეგმაზე საცავი ფაილების შესანახი ადგილია.

ცუდი კონფიგურაცია. plugin, რომელიც ყოველ tick-ზე მთავარ thread-ზე სინქრონულ ბაზის query-ს აკეთებს, NVMe-ზეც ნელია. უბრალოდ, ოდნავ უფრო სწრაფად ნელია.

ბაზებში ის ნამდვილად დომინირებს#

თუ ბაზას უშვებ - Postgres ან MongoDB ინსტანციას, FiveM სერვერს ნამდვილი მონაცემთა საცავით, Minecraft-ის ეკონომიკის plugin-ს ათასობით ტრანზაქციით - საცავის latency გამტარუნარიანობას მკაცრ ჭერს უწესებს, და არითმეტიკა შეუბრალებელია.

გამძლე ბაზა fsync-ს commit-ის დადასტურებამდე იძახებს, რადგან commit, რომელიც მხოლოდ page cache-შია, დაპირებაა, რომლის შესრულებაც დენის გაქრობას ვერ გადაურჩება. ეს fsync მოწყობილობამდე სინქრონული round trip-ია, და ერთი კავშირი ერთდროულად ერთ fsync-ზე სწრაფად commit-ს ვერ გააკეთებს:

code
max commits per second, per connection = 1 / fsync latencyHDD,  8 ms fsync   ->    125 commits/sSATA, 1 ms fsync   ->  1,000 commits/sNVMe, 50 us fsync  -> 20,000 commits/s

ეს ჭერებია და არა პროგნოზები, და რეალური სისტემები რამდენიმე კავშირის commit-ებს აჯგუფებენ, რომ უკეთესი შედეგი მიიღონ. მაგრამ ფორმა ის არის, რატომაც აწყდება ჩაწერაზე მძიმე აპლიკაცია ნელ საცავზე კედელს, რომელსაც query-ების ტიუნინგი ვერ აქრობს, და რატომაც არ ამჩნევს იგივე აპლიკაცია NVMe-ზე ამას. PostgreSQL-ის ტიუნინგი პატარა სერვერებისთვის ამასთან დაკავშირებულ პარამეტრებს ეხება, ხოლო explain analyze ნელი query-ებისთვის - მეორე ნახევარს, ანუ თავად query-ებს.

კითხვის წარმადობა სხვაგვარად მნიშვნელოვანია. query, რომელიც თავის მონაცემებს ქეშში პოულობს, დისკს საერთოდ არ ეხება - სწორედ ამიტომ ეწყობა shared_buffers და ოპერაციული სისტემის page cache პირველად. NVMe ცვლის იმას, რაც ქეშის miss-ზე ხდება, და მეხსიერებაზე დიდ სამუშაო ნაკრებზე ეს დროის უმეტესობაა. მონაცემთა ბაზების ჰოსტინგის გეგმები ამის გათვალისწინებით არის ზომაზე, მაგრამ ზოგადი წესი ყველგან მართებულია: მეხსიერება კითხვებს აქრობს, სწრაფი საცავი კი იაფს ხდის იმ კითხვებს, რომელთა მოშორებაც არ შეგიძლია.

საკუთარი ხელით გაზომვა#

სპეციფიკაციის ფურცელს ნუ ენდობი და კონკრეტულად dd-ს ნუ ენდობი.

bash
# Misleading: writes through the page cache, measures RAM$ dd if=/dev/zero of=test bs=1M count=1024# Better, but still only sequential throughput$ dd if=/dev/zero of=test bs=1M count=1024 oflag=direct conv=fdatasync

მიმდევრობითი გამტარობა ყველაზე ნაკლებ რელევანტური რიცხვია. რაც გინდა, პატარა შემთხვევითი I/O latency და IOPS-ია:

bash
$ fio --name=randread --ioengine=libaio --direct=1 --rw=randread \    --bs=4k --iodepth=32 --numjobs=1 --size=1G --runtime=30 \    --time_based --group_reporting$ fio --name=syncwrite --ioengine=sync --fsync=1 --rw=write \    --bs=4k --size=256M --runtime=30 --time_based

პირველი გაძლევს შემთხვევითი კითხვის IOPS-ს და latency-ის განაწილებას. მეორე fsync ტესტია, და ის ბაზის ქცევას წინასწარმეტყველებს. წაიკითხე 99-ე პერცენტილის latency და არა საშუალო - საშუალო გეუბნება, როგორ გრძნობა ჩვეულებრივ, კუდი კი - როგორ გამოიყურება გაყინვა.

სწრაფი შემოწმებისთვის, არაფრის დაყენების გარეშე, ioping -c 20 . მიმდინარე დირექტორიაში თითო მოთხოვნის latency-ს ბეჭდავს. ცოცხალი სერვერის დასაკვირვებლად:

bash
$ iostat -xz 1

შეხედე r_await-ს და w_await-ს - საშუალო მილიწამები, რამდენიც მოთხოვნა ელოდა - და aqu-sz-ს, საშუალო რიგის სიღრმეს. NVMe მოწყობილობაზე %util უგულებელყავი; ის ერთრიგიანი დისკებისთვის იყო შექმნილი და 100%-ს აჩვენებს დისკზე, რომელიც ძლივს მუშაობს, რადგან ზომავს, იყო თუ არა რომელიმე მოთხოვნა ფრენაში და არა ის, არის თუ არა მოწყობილობა გაჯერებული. მაღალი %util 0.1 ms-იან w_await-თან ჯანსაღი NVMe დისკია და არა ბოთლის ყელი.

პანელზე დაფუძნებულ ჰოსტზე fio არ გექნება, და სასარგებლო შემცვლელი დისკის გრაფიკია მეხსიერებისა და CPU-ს გრაფიკების გვერდით. დისკის გრაფიკზე ხერხისებრი ფორმა, რომელიც ზუსტად ემთხვევა hitch-ებს, რომლებზეც მოთამაშეები ჩივიან, შენი პასუხია, და სერვერის დატვირთვის გრაფიკის წაკითხვა ფორმებს განიხილავს.

დისკის ადგილი დისკის სიჩქარისგან ცალკე კითხვაა#

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

თითქმის სავსეზე მუშაობა ნელია. ფლეშს ჩასაწერად თავისუფალი ბლოკები სჭირდება, და თითქმის სავსე დისკი დროს ხარჯავს მონაცემების გადაადგილებაზე ადგილის გასათავისუფლებლად. copy-on-write ფაილურ სისტემებს, ZFS-ის ჩათვლით, ეფექტურად სამუშაოდ თავისუფალი ადგილი სჭირდება. გამოყენების დაახლოებით 80%-ს ქვემოთ შენახვა წარმადობის პარამეტრია და არა უბრალოდ სისუფთავე.

Backup-ები იმავე ადგილზე ცხოვრობს, თუ არ ცხოვრობს. თამაშის ჩაშენებული backup ფუნქცია სამყაროს გვერდით წერს, რაც ნიშნავს, რომ 30 GB სამყარო ოთხი შენახული backup-ით 150 GB-ს საჭიროებს და იცავს ზუსტად ერთი ჩავარდნის რეჟიმისგან: დაზიანებული შენახვისგან. ის არაფერს აკეთებს წაშლილი სერვერის ან ცუდი აღდგენის წინააღმდეგ. RE:NODE-ზე პლატფორმის backup-ები ცალკე აპარატურაზე კოპირდება, მოწმდება და განრიგით იწმინდება, ხოლო პანელის საკუთარი backup სლოტები იმ მანქანის გარეთ ინახება, რომელსაც იცავს - ეს თვისებაა, რაც backup-ს backup-ად აქცევს და არა იმავე დისკზე ფაილის მეორე ასლად.

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

FAQ#

ღირს თუ არა NVMe-ში დამატებით გადახდა?

თუ ეს ხაზოვანი ხარჯია, ჯერ შენს დატვირთვას შეხედე. ღირს ბაზებისთვის, დიდი სამყაროებისთვის, რომლებიც ხშირად ინახება, და ყველაფრისთვის, რაც ხშირ backup-ს აკეთებს. არ ღირს პრემიუმი პატარა shooter სერვერისთვის ან Discord bot-ისთვის, რომლებიც გაშვების შემდეგ დისკს ძლივს ეხებიან. RE:NODE-ზე ეს ხაზოვანი ხარჯი არ არის; ყველა გეგმა NVMe-ა, ყველაზე იაფის ჩათვლით, რადგან ალტერნატივა ცრუ ეკონომიაა აპარატურაზე, რომელიც ღირებულების მცირე ნაწილია.

გამოასწორებს თუ არა NVMe ჩემი სერვერის lag-ს?

მხოლოდ თუ lag პერიოდულია და შენახვებს, backup-ებს ან მოთამაშეების კვლევას ემთხვევა. lag, რომელიც მუდმივია, უარესდება მეტი entity-ით და მაღალ tick დროდ ჩანს მშვიდი დისკის გრაფიკით, CPU-ს პრობლემაა და საცავი მას ვერ შეეხება.

გაუშვებს თუ არა NVMe ჩემს სერვერს უფრო სწრაფად?

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

რა განსხვავებაა NVMe-სა და SSD-ს შორის?

SSD ფლეშ საცავია; NVMe პროტოკოლია მასთან PCIe-ით სასაუბროდ. ჰოსტინგის ტექსტში „SSD" უმეტესად SATA SSD-ს ნიშნავს AHCI-ით, რაც 2004 წლის პროტოკოლია ერთი არაღრმა რიგით. იგივე ჩიპები, ძალიან განსხვავებული latency და პარალელიზმი.

მჭირდება თუ არა NVMe Minecraft სერვერისთვის?

ის უფრო მეტად ეხმარება, ვიდრე ხალხი ელოდება, რადგან Minecraft-ის დისკის მუშაობა პატარა შემთხვევითი კითხვები და ჩაწერებია: chunk-ების ჩატვირთვა, როცა მოთამაშეები იკვლევენ, region ფაილები შენახვისას და plugin ბაზები, როგორიც CoreProtect-ია, რომლებიც განუწყვეტლივ წერენ. არცერთი მათგანი გამტარობა არ არის და ყველა latency-ა, რაც NVMe-ს ცვლის.

შეუძლია თუ არა ნელ საცავს დაბალი TPS-ის გამოწვევა?

დიახ, არაპირდაპირ და წყვეტილად. შენახვა ან სინქრონული plugin-ის ჩაწერა, რომელიც მთავარ thread-ს ბლოკავს, tick ბიუჯეტს ხარჯავს, რაც უზარმაზარ მაქსიმალურ tick დროდ ჩანს ნორმალური საშუალოთი. ეს ნიმუში საცავის პრობლემაა, რომელიც CPU-ს ეპატიჟება, და რას ნიშნავს tick rate სინამდვილეში გვიჩვენებს, როგორ წავიკითხოთ განსხვავება.


კომენტარები

სრულიად ანონიმურად: ანგარიშის, ელფოსტის და cookie-ის გარეშე. ინახება მხოლოდ სახელი, ტექსტი და დრო - სხვა არაფერი. ბმულების რაოდენობა ლიმიტირებულია.

0/2000