Monday, October 27, 2014

JIT -server || -client

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

ალბათ გექნებათ ნანახი აპლიკაციები, რომლებიც გაშვებული არიან JVM ის შემდეგი პარამეტრით: "-server" ან "-client".



ორივე შემთხვევაში, ვიყენებთ ჩვენ -server  თუ client პარამეტრს,  JVM იქცევა სხვადასხვანაგვარად. -server ის დროს JVM მეტ ოპტიმიზაციას ანხორციელებს (JIT ზე ვსაუბრობ აქ), აპლიკაციის დასტარტვის დრო ცოტა ნელია თუმცა საბოლოო ჯამში მეტად ოპტიმიზირებული შედეგი მიიღება. -client შემთხვევაში კი მსუბუქად უკეთებს ოპტიმიზაციას კოდის ისეთ ნაწილებს სადაც JVM-ს მეტად  მძიმე, დატვურთული, მუშაობა ჭირდება.

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

შენიშვნა Thread Visibility -ზე  წინა ერთერთ სტატიაში (შეგიძლიათ გახსათ lazy init, dc locking, volatile) დავწერე Volatile-ცვლადების სპეციფიურ ქცევაზე.  მაგალითი იყო შემდეგი: გვაქვს 2 სრედი, პირველი ნაკადი უყურებს whilte(flag){}-ს მეორე კი flag ზე ახდენს მოდიფიცირებას -მნიშვნელობას უცვლის ისე რომ ციკლი გააჩეროს.  ერთ შემთხვევაში flag არის volatile მეორეში კი უბრალოდ მარტივი, კოტხტა, ლამაზი და მშვენიერი boolean - რომელიც თავისთვის არის და არის, ცხოვრობს თავის თბილ სახლში, heap ად წოდებულში.

წარმოვიდგინოთ,  ზემოთ აღნიშნული კოდი წერია ერთერთ აპლიკაციაში რომელიც გაშვებულია სერვერზე - Tomcat მაგალითად, ან Jetty (ეს უკანასკნელი ძალიან კარგი ბიჭია asynchronous რექუესთების დამუშავებაში). ჩვენ უკვე ვიცით რომ, რომ სერვერ აპლიკაციები ყოველთვის უნდა იყვნენ დასტარტულები  -server ბრძანებით. მაგრამ Oops! -server  ის წყალობით , უფრო კი მისი ოპტიმიზაცთ, JVM მა შესაძლოა ციკლში არსებული არამოდიფიცირებადი ცვლადებისადმი ხედვის არიალი გადაიტანოს ციკლის გარეთ - უფრო გასაგები რომ იყოს, ციკლის შიგნით არ ხდება flag მნიშვნელობის შეცვლა, ამან კი შესაძლოა JVM დაარწმუნის, რომ ოპტიმიზაციისთვის ხედვის არეალი შეცვალოს. გილოცავთ, ეს არის უსასრულო ციკლი!  შედეგად,   შესაძლოა კოდმა იმუშაოს -client გარემოში, და არ იმუშაოს -server ში. დებაგირების დროსაც თუ  -server-ს გამოვიყენებთ, პროდაქშენზე დადებამდე, ამით შემდეგი ტიპის გაჟონვებს თავიდან ავიცილებთ - ტესტირების დროსვე დავიჭერთ შეცდომას.


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


Friday, October 10, 2014

NoSQL 'n CAP


 NoSQL მოიცავს ისეთ ბაზებს როგორებიცაა: Mongo, Neoj4, Cassandra, Riak, Hadoop (HDFS ხოლო რეალ თაიმ ბაზა HBase) და ასე შემდეგ, ისინი ერთმანეთისგან სტრუქტურულად განსხვავდებიან (ჰადუპის ეკო სისტემაზე სხვა დროს დეტალურად ვისაუბრებ). მაგალითად არსებობს, გრაფებზე აგებული ბაზები (Neo4j), Key Value სტრუქტურის მქონენი (Cassandra, Redis), Mongo სა და CouchDB– ში დოკუმენტების შენახვა JSON ობიექტებით ხდება

საბოლოოდ, მათში ინახება უსქემო მონაცემები*, ადვილია მათი დაკლასტერება, ეს სისტემები გამოირჩევიან დიდი სისწრაფით და ამარტივებენ ამოცანის გადაჭრას. NoSQL მონაცემთა ბაზა არ იყენებს SQL–ს, თუმცა ზოგი მათგანი query ენას გვაძლევს – მაგალითად Cassandra CQL.

*სიტყვა „უსქემო“ ხშირად დამაბნეველია, მაგალითად, როდესაც იგებენ, რომ მონგოს აქვს დიამიური სქემა- მასში შეგვიძლია შევქმნათ ქოლექშენები ისე რომ წინასწარ სტრუქტურა არ გვქონდეს აღწერლი.



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




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



Consistency (მუდმივობა) - ჩანაწერები იგივეა კლასტერის ყველა node ში.
Availability – თუ რომელიმე Node არის ჩავარდნილი, მაინც შესაძლებელია კლასტერთან წვდომა.
Partition Tolerance – კლასტერი განაგრძობს ფუნქციონალობას მაშინაც კი როდესაც node ებს შორის არის კომუნიკაციის პრობლემა.

ამ სამზე (CAP) დეტალურ მაგალითებს, ქვემოთ მოვიყვან.




როდესაც კომუნიკაციის პრობლემაა, არჩევანი გვაქვს:

1. ან დავუშვათ რომ არასინქრონირებული მნაცემები იყვნენ ბაზაში (დავივიწყოთ Consistency)
2. ჩავთვალოთ რომ კლასტერი დაზიანდა, ანუ დავივიწყოთ Availability

ყველა კომბინაცია ასე გამოიყურება:
CA ერთიდაიგივე მონაცემებია ყველა node ში. თუ რაიმე კომუნიკაციის პრობლემა დაფიქსირდა node ებს შორის (partition ), მონაცემები იქნება არასინქრონირებული სანამ პრობლემა არ გადაიჭრება. ანუ node ებს შორის სხვადასხვა მონაცემები იქნება.

CP აქაც მონაცემები მუდმივია ყველა node ში. მაგალითად, დაფიქსირდა დაფიქსირდა კომუნიკაციის პრობლემა. ამ დროს არასინქრონული რომ არ იყოს მონაცემები შესაბამისი node გახდება გაუქმებული ანუ წაკითხვა/ჩაწერა იქნება გაჩერებული შესაბამის node ში. აქ თავი გვაქ დაცული იმისგან რომ სხვადასხვა მონაცემები არ გვეწეროს ბაზაში.

AP იგივე მაგალითი – დაფისქირდა პრობლემა node ებს შორის. აქ დაზიანებული node ები არ არიან გაუქმებულები. ისინი დამოუკიდებლად განაგრძობენ მუშაობას. როდესაც კომუნიკაციის პრობლემა აღდგება დაიწყება სინქრონიზაცია მონაცემების, თუმცა გარანტია არ გვაქვს რომ ყველა მონაცემი იგივე იქნება ნოუდებს შორის.