ক্লাউড প্রোফাইলারের সাথে উত্পাদন কর্মক্ষমতা বিশ্লেষণ করুন

ক্লাউড প্রোফাইলারের সাথে উত্পাদন কর্মক্ষমতা বিশ্লেষণ করুন

এই কোডল্যাব সম্পর্কে

subjectজুল ১৪, ২০২১-এ শেষবার আপডেট করা হয়েছে
account_circleaalexand-এর লেখা

1. ওভারভিউ

যদিও ক্লায়েন্ট অ্যাপ এবং ফ্রন্টএন্ড ওয়েব ডেভেলপাররা সাধারণত অ্যান্ড্রয়েড স্টুডিও সিপিইউ প্রোফাইলার বা তাদের কোডের কার্যকারিতা উন্নত করতে Chrome-এ অন্তর্ভুক্ত প্রোফাইলিং টুলের মতো টুল ব্যবহার করে, সমতুল্য কৌশলগুলি ব্যাকএন্ড পরিষেবাগুলিতে যারা কাজ করে তাদের দ্বারা প্রায় অ্যাক্সেসযোগ্য বা ভালভাবে গ্রহণ করা হয়নি। ক্লাউড প্রোফাইলার তাদের কোড Google ক্লাউড প্ল্যাটফর্মে বা অন্য কোথাও চলছে কিনা তা নির্বিশেষে পরিষেবা বিকাশকারীদের কাছে এই একই ক্ষমতাগুলি নিয়ে আসে৷

95c034c70c9cac22.png

টুলটি আপনার প্রোডাকশন অ্যাপ্লিকেশন থেকে CPU ব্যবহার এবং মেমরি-বরাদ্দ সংক্রান্ত তথ্য সংগ্রহ করে। এটি সেই তথ্যটিকে অ্যাপ্লিকেশানের সোর্স কোডের জন্য দায়ী করে, আপনাকে অ্যাপ্লিকেশনের অংশগুলি সনাক্ত করতে সাহায্য করে যা সর্বাধিক সম্পদ ব্যবহার করে এবং অন্যথায় কোডের কার্যকারিতা বৈশিষ্ট্যগুলিকে আলোকিত করে৷ টুল দ্বারা নিযুক্ত সংগ্রহের কৌশলগুলির কম ওভারহেড এটিকে উত্পাদন পরিবেশে ক্রমাগত ব্যবহারের জন্য উপযুক্ত করে তোলে।

এই কোডল্যাবে, আপনি একটি Go প্রোগ্রামের জন্য ক্লাউড প্রোফাইলার কীভাবে সেট আপ করবেন তা শিখবেন এবং টুলটি উপস্থাপন করতে পারে অ্যাপ্লিকেশন কার্যকারিতা সম্পর্কে কী ধরনের অন্তর্দৃষ্টির সাথে পরিচিত হবেন।

আপনি কি শিখবেন

  • ক্লাউড প্রোফাইলারের সাথে প্রোফাইলিংয়ের জন্য কীভাবে একটি গো প্রোগ্রাম কনফিগার করবেন।
  • কিভাবে ক্লাউড প্রোফাইলারের মাধ্যমে কর্মক্ষমতা ডেটা সংগ্রহ, দেখতে এবং বিশ্লেষণ করতে হয়।

আপনি কি প্রয়োজন হবে

  • একটি Google ক্লাউড প্ল্যাটফর্ম প্রকল্প
  • একটি ব্রাউজার, যেমন ক্রোম বা ফায়ারফক্স
  • স্ট্যান্ডার্ড লিনাক্স টেক্সট এডিটর যেমন Vim, EMACs বা Nano এর সাথে পরিচিতি

কিভাবে আপনি এই টিউটোরিয়াল ব্যবহার ব্যবহার করবেন?

আপনি Google ক্লাউড প্ল্যাটফর্মের সাথে আপনার অভিজ্ঞতাকে কীভাবে মূল্যায়ন করবেন?

2. সেটআপ এবং প্রয়োজনীয়তা

স্ব-গতিসম্পন্ন পরিবেশ সেটআপ

  1. ক্লাউড কনসোলে সাইন ইন করুন এবং একটি নতুন প্রকল্প তৈরি করুন বা বিদ্যমান একটি পুনরায় ব্যবহার করুন৷ আপনার যদি ইতিমধ্যেই একটি Gmail বা Google Workspace অ্যাকাউন্ট না থাকে, তাহলে আপনাকে অবশ্যই একটি তৈরি করতে হবে।

96a9c957bc475304.png

b9a10ebdf5b5a448.png

a1e3c01a38fa61c2.png

প্রজেক্ট আইডিটি মনে রাখবেন, সমস্ত Google ক্লাউড প্রকল্প জুড়ে একটি অনন্য নাম (উপরের নামটি ইতিমধ্যে নেওয়া হয়েছে এবং আপনার জন্য কাজ করবে না, দুঃখিত!)। এটি পরে এই কোডল্যাবে PROJECT_ID হিসাবে উল্লেখ করা হবে।

  1. এর পরে, Google ক্লাউড সংস্থানগুলি ব্যবহার করার জন্য আপনাকে ক্লাউড কনসোলে বিলিং সক্ষম করতে হবে৷

এই কোডল্যাবের মাধ্যমে চালানোর জন্য খুব বেশি খরচ করা উচিত নয়, যদি কিছু থাকে। "ক্লিনিং আপ" বিভাগে যে কোনও নির্দেশাবলী অনুসরণ করতে ভুলবেন না যা আপনাকে কীভাবে সংস্থানগুলি বন্ধ করতে হবে তা পরামর্শ দেয় যাতে আপনি এই টিউটোরিয়ালের বাইরে বিলিং করতে না পারেন৷ Google ক্লাউডের নতুন ব্যবহারকারীরা $300 USD বিনামূল্যের ট্রায়াল প্রোগ্রামের জন্য যোগ্য৷

গুগল ক্লাউড শেল

যদিও Google ক্লাউড আপনার ল্যাপটপ থেকে দূরবর্তীভাবে পরিচালনা করা যেতে পারে, এই কোডল্যাবে সেটআপকে আরও সহজ করতে আমরা Google ক্লাউড শেল ব্যবহার করব, ক্লাউডে চলমান একটি কমান্ড লাইন পরিবেশ।

ক্লাউড শেল সক্রিয় করুন

  1. ক্লাউড কনসোল থেকে, ক্লাউড শেল সক্রিয় করুন ক্লিক করুন 4292cbf4971c9786.png .

bce75f34b2c53987.png

আপনি যদি আগে কখনও ক্লাউড শেল চালু না করে থাকেন, তাহলে আপনাকে একটি মধ্যবর্তী স্ক্রীন (ভাঁজের নীচে) উপস্থাপন করা হবে যা বর্ণনা করে। যদি এটি হয়, তবে চালিয়ে যান ক্লিক করুন (এবং আপনি এটি আর কখনও দেখতে পাবেন না)। এককালীন স্ক্রীনটি দেখতে কেমন তা এখানে রয়েছে:

70f315d7b402b476.png

ক্লাউড শেলের সাথে সংযোগ করতে এবং সংযোগ করতে এটির মাত্র কয়েক মুহূর্ত লাগবে৷

fbe3a0674c982259.png

এই ভার্চুয়াল মেশিনটি আপনার প্রয়োজনীয় সমস্ত ডেভেলপমেন্ট টুল দিয়ে লোড করা হয়েছে। এটি একটি ক্রমাগত 5GB হোম ডিরেক্টরি অফার করে এবং Google ক্লাউডে চলে, যা নেটওয়ার্ক কর্মক্ষমতা এবং প্রমাণীকরণকে ব্যাপকভাবে উন্নত করে। এই কোডল্যাবে আপনার অনেক কাজ, যদি সব না হয়, শুধুমাত্র একটি ব্রাউজার বা আপনার Chromebook দিয়ে করা যেতে পারে।

একবার ক্লাউড শেলের সাথে সংযুক্ত হয়ে গেলে, আপনি দেখতে পাবেন যে আপনি ইতিমধ্যেই প্রমাণীকরণ করেছেন এবং প্রকল্পটি ইতিমধ্যে আপনার প্রকল্প আইডিতে সেট করা আছে।

  1. আপনি প্রমাণীকৃত কিনা তা নিশ্চিত করতে ক্লাউড শেলে নিম্নলিখিত কমান্ডটি চালান:
gcloud auth list

কমান্ড আউটপুট

 Credentialed Accounts
ACTIVE  ACCOUNT
*       <my_account>@<my_domain.com>

To set the active account, run:
    $ gcloud config set account `ACCOUNT`
  1. gcloud কমান্ড আপনার প্রকল্প সম্পর্কে জানে তা নিশ্চিত করতে ক্লাউড শেলে নিম্নলিখিত কমান্ডটি চালান:
gcloud config list project

কমান্ড আউটপুট

[core]
project = <PROJECT_ID>

যদি এটি না হয়, আপনি এই কমান্ড দিয়ে এটি সেট করতে পারেন:

gcloud config set project <PROJECT_ID>

কমান্ড আউটপুট

Updated property [core/project].

3. ক্লাউড প্রোফাইলারে নেভিগেট করুন

ক্লাউড কনসোলে, বাম নেভিগেশন বারে "প্রোফাইলার" এ ক্লিক করে প্রোফাইলার UI-তে নেভিগেট করুন:

37ad0df7ddb2ad17.png

বিকল্পভাবে আপনি প্রোফাইলার UI এ নেভিগেট করতে ক্লাউড কনসোল অনুসন্ধান বার ব্যবহার করতে পারেন: শুধু "ক্লাউড প্রোফাইলার" টাইপ করুন এবং পাওয়া আইটেমটি নির্বাচন করুন৷ যেভাবেই হোক, আপনি নীচের মত "প্রদর্শনের জন্য কোন ডেটা নেই" বার্তা সহ প্রোফাইলার UI দেখতে হবে৷ প্রকল্পটি নতুন, তাই এটিতে এখনও কোনো প্রোফাইলিং ডেটা সংগ্রহ করা হয়নি৷

d275a5f61ed31fb2.png

এটা এখন কিছু প্রোফাইল পেতে সময়!

4. বেঞ্চমার্ক প্রোফাইল

আমরা Github-এ উপলব্ধ একটি সাধারণ সিন্থেটিক গো অ্যাপ্লিকেশন ব্যবহার করব। ক্লাউড শেল টার্মিনালে যেটি আপনি এখনও খোলা আছে (এবং প্রোফাইলার UI-তে "প্রদর্শনের জন্য কোনও ডেটা নেই" বার্তাটি এখনও দেখানো হয়েছে), নিম্নলিখিত কমান্ডটি চালান:

$ go get -u github.com/GoogleCloudPlatform/golang-samples/profiler/...

তারপর অ্যাপ্লিকেশন ডিরেক্টরিতে স্যুইচ করুন:

$ cd ~/gopath/src/github.com/GoogleCloudPlatform/golang-samples/profiler/hotapp

ডিরেক্টরিতে "main.go" ফাইল রয়েছে, যা একটি সিন্থেটিক অ্যাপ যাতে প্রোফাইলিং এজেন্ট সক্রিয় থাকে:

main.go

...
import (
       
...
       
"cloud.google.com/go/profiler"
)
...
func main() {
       
err := profiler.Start(profiler.Config{
               
Service:        "hotapp-service",
               
DebugLogging:   true,
               
MutexProfiling: true,
       
})
       
if err != nil {
               
log.Fatalf("failed to start the profiler: %v", err)
       
}
       
...
}

প্রোফাইলিং এজেন্ট ডিফল্টরূপে CPU, হিপ এবং থ্রেড প্রোফাইল সংগ্রহ করে। এখানে কোডটি মিউটেক্স ("বিরোধ" নামেও পরিচিত) প্রোফাইল সংগ্রহ করতে সক্ষম করে।

এখন, প্রোগ্রাম চালান:

$ go run main.go

প্রোগ্রাম চলাকালীন, প্রোফাইলিং এজেন্ট পর্যায়ক্রমে পাঁচটি কনফিগার করা ধরনের প্রোফাইল সংগ্রহ করবে। সংগ্রহটি সময়ের সাথে র্যান্ডমাইজ করা হয়েছে (প্রতিটি প্রকারের জন্য প্রতি মিনিটে একটি প্রোফাইলের গড় হার সহ), তাই প্রতিটি প্রকার সংগ্রহ করতে তিন মিনিট পর্যন্ত সময় লাগতে পারে। প্রোগ্রামটি আপনাকে বলে যখন এটি একটি প্রোফাইল তৈরি করে। উপরের কনফিগারেশনে DebugLogging পতাকা দ্বারা বার্তাগুলি সক্রিয় করা হয়েছে; অন্যথায়, এজেন্ট নীরবে চলে:

$ go run main.go
2018/03/28 15:10:24 profiler has started
2018/03/28 15:10:57 successfully created profile THREADS
2018/03/28 15:10:57 start uploading profile
2018/03/28 15:11:19 successfully created profile CONTENTION
2018/03/28 15:11:30 start uploading profile
2018/03/28 15:11:40 successfully created profile CPU
2018/03/28 15:11:51 start uploading profile
2018/03/28 15:11:53 successfully created profile CONTENTION
2018/03/28 15:12:03 start uploading profile
2018/03/28 15:12:04 successfully created profile HEAP
2018/03/28 15:12:04 start uploading profile
2018/03/28 15:12:04 successfully created profile THREADS
2018/03/28 15:12:04 start uploading profile
2018/03/28 15:12:25 successfully created profile HEAP
2018/03/28 15:12:25 start uploading profile
2018/03/28 15:12:37 successfully created profile CPU
...

প্রথম প্রোফাইলগুলি সংগ্রহ করার পরেই UI নিজেই আপডেট হবে৷ এর পরে এটি স্বয়ংক্রিয়-আপডেট হবে না, তাই নতুন ডেটা দেখতে, আপনাকে প্রোফাইলার UI ম্যানুয়ালি রিফ্রেশ করতে হবে। এটি করতে, দুইবার সময় ব্যবধান পিকারে Now বোতামটি ক্লিক করুন:

650051097b651b91.png

UI রিফ্রেশ করার পরে, আপনি এরকম কিছু দেখতে পাবেন:

47a763d4dc78b6e8.png

প্রোফাইল টাইপ নির্বাচক পাঁচটি প্রোফাইল প্রকার উপলব্ধ দেখায়:

b5d7b4b5051687c9.png

আসুন এখন প্রতিটি প্রোফাইল প্রকার এবং কিছু গুরুত্বপূর্ণ UI ক্ষমতা পর্যালোচনা করি এবং তারপর কিছু পরীক্ষা-নিরীক্ষা করি। এই পর্যায়ে, আপনার আর ক্লাউড শেল টার্মিনালের প্রয়োজন নেই, তাই আপনি CTRL-C টিপে এবং "প্রস্থান" টাইপ করে এটি থেকে প্রস্থান করতে পারেন।

5. প্রোফাইলার ডেটা বিশ্লেষণ করুন

এখন যেহেতু আমরা কিছু ডেটা সংগ্রহ করেছি, আসুন এটি আরও ঘনিষ্ঠভাবে দেখি। আমরা একটি সিন্থেটিক অ্যাপ ব্যবহার করছি (উৎসটি Github এ উপলব্ধ ) যা উত্পাদনে বিভিন্ন ধরণের পারফরম্যান্স সমস্যাগুলির সাধারণ আচরণগুলিকে অনুকরণ করে৷

CPU-নিবিড় কোড

CPU প্রোফাইল টাইপ নির্বাচন করুন। UI এটি লোড করার পরে, আপনি শিখা গ্রাফে load ফাংশনের জন্য চারটি পাতার ব্লক দেখতে পাবেন, যা সম্মিলিতভাবে সমস্ত CPU খরচের জন্য দায়ী:

fae661c9fe6c58df.png

এই ফাংশনটি বিশেষভাবে একটি আঁটসাঁট লুপ চালিয়ে প্রচুর CPU চক্র গ্রহণ করার জন্য লেখা হয়েছে:

main.go

func load() {
        for i := 0; i < (1 << 20); i++ {
        }
}

ফাংশনটি পরোক্ষভাবে busyloop () থেকে চারটি কল পাথের মাধ্যমে বলা হয়: busyloop → { foo1 , foo2 } → { bar , baz } → load । একটি ফাংশন বক্সের প্রস্থ নির্দিষ্ট কল পাথের আপেক্ষিক খরচের প্রতিনিধিত্ব করে। এই ক্ষেত্রে চারটি পথের প্রায় একই খরচ আছে। একটি বাস্তব প্রোগ্রামে, আপনি কল পাথ অপ্টিমাইজ করার উপর ফোকাস করতে চান যা কর্মক্ষমতার ক্ষেত্রে সবচেয়ে গুরুত্বপূর্ণ। শিখা গ্রাফ, যা দৃশ্যত বৃহত্তর বাক্সের সাথে আরও ব্যয়বহুল পথের উপর জোর দেয়, এই পথগুলিকে সনাক্ত করা সহজ করে তোলে।

আপনি প্রদর্শন আরও পরিমার্জিত করতে প্রোফাইল ডেটা ফিল্টার ব্যবহার করতে পারেন। উদাহরণস্বরূপ, ফিল্টার স্ট্রিং হিসাবে "baz" নির্দিষ্ট করে একটি "স্ট্যাক দেখান" ফিল্টার যোগ করার চেষ্টা করুন। আপনি নীচের স্ক্রিনশটের মতো কিছু দেখতে পাবেন, যেখানে load() জন্য চারটি কল পাথের মধ্যে মাত্র দুটি প্রদর্শিত হয়। এই দুটি পথই একমাত্র যেটি একটি ফাংশনের মধ্য দিয়ে যায় যার নামে "baz" স্ট্রিং থাকে। এই ধরনের ফিল্টারিং উপযোগী হয় যখন আপনি একটি বড় প্রোগ্রামের একটি সাবপার্টে ফোকাস করতে চান (উদাহরণস্বরূপ, কারণ আপনি এটির শুধুমাত্র একটি অংশের মালিক)।

eb1d97491782b03f.png

মেমরি-নিবিড় কোড

এখন "হিপ" প্রোফাইল টাইপ এ স্যুইচ করুন। পূর্ববর্তী পরীক্ষায় আপনার তৈরি করা যেকোনো ফিল্টার মুছে ফেলার বিষয়টি নিশ্চিত করুন। আপনি এখন একটি শিখা গ্রাফ দেখতে পাবেন যেখানে allocImpl , যাকে alloc দ্বারা বলা হয়, অ্যাপে মেমরির প্রধান ভোক্তা হিসাবে প্রদর্শিত হয়:

f6311c8c841d04c4.png

শিখা গ্রাফের উপরের সারাংশ সারণীটি নির্দেশ করে যে অ্যাপটিতে ব্যবহৃত মেমরির মোট পরিমাণ গড়ে ~57.4 MiB, এর বেশিরভাগই allocImpl ফাংশন দ্বারা বরাদ্দ করা হয়। এই ফাংশনটির বাস্তবায়নের কারণে এটি আশ্চর্যজনক নয়:

main.go

func allocImpl() {
        // Allocate 64 MiB in 64 KiB chunks
        for i := 0; i < 64*16; i++ {
                mem = append(mem, make([]byte, 64*1024))
        }
}

ফাংশনটি একবার সঞ্চালিত হয়, ছোট খণ্ডে 64 MiB বরাদ্দ করে, তারপর সেই খণ্ডগুলিতে পয়েন্টারগুলিকে একটি গ্লোবাল ভেরিয়েবলে সংরক্ষণ করে আবর্জনা সংগ্রহ করা থেকে রক্ষা করে। উল্লেখ্য যে প্রোফাইলার দ্বারা ব্যবহৃত মেমরির পরিমাণ 64 MiB থেকে কিছুটা আলাদা: Go heap প্রোফাইলার একটি পরিসংখ্যানগত টুল, তাই পরিমাপ কম-ওভারহেড কিন্তু বাইট-সঠিক নয়। এইরকম ~10% পার্থক্য দেখলে অবাক হবেন না।

আইও-নিবিড় কোড

আপনি যদি প্রোফাইল টাইপ সিলেক্টরে "থ্রেডস" বেছে নেন, তাহলে ডিসপ্লেটি একটি ফ্লেম গ্রাফে স্যুইচ করবে যেখানে বেশিরভাগ প্রস্থ wait এবং waitImpl ফাংশন দ্বারা নেওয়া হয়:

ebd57fdff01dede9.png

উপরের ফ্লেম গ্রাফের সংক্ষিপ্তসারে, আপনি দেখতে পাচ্ছেন যে 100টি গোরুটিন রয়েছে যেগুলি wait ফাংশন থেকে তাদের কল স্ট্যাক বৃদ্ধি করে। এটি ঠিক সঠিক, প্রদত্ত যে কোডটি এই অপেক্ষা শুরু করে তা এইরকম দেখায়:

main.go

func main() {
        ...
        // Simulate some waiting goroutines.
        for i := 0; i < 100; i++ {
                go wait()
        }

এই প্রোফাইল টাইপ প্রোগ্রামটি অপেক্ষায় কোন অপ্রত্যাশিত সময় ব্যয় করে কিনা তা বোঝার জন্য উপযোগী (যেমন I/O)। এই ধরনের কল স্ট্যাকগুলি সাধারণত CPU প্রোফাইলার দ্বারা নমুনা করা হবে না, কারণ তারা CPU সময়ের কোনো উল্লেখযোগ্য অংশ গ্রহণ করে না। আপনি প্রায়শই থ্রেড প্রোফাইলের সাথে "স্ট্যাকগুলি লুকান" ফিল্টার ব্যবহার করতে চান - উদাহরণস্বরূপ, gopark, যেহেতু সেগুলি প্রায়শই নিষ্ক্রিয় গোরুটিন এবং I/O তে অপেক্ষা করাগুলির চেয়ে কম আকর্ষণীয়৷

থ্রেড প্রোফাইল টাইপ প্রোগ্রামের পয়েন্টগুলি সনাক্ত করতেও সাহায্য করতে পারে যেখানে থ্রেডগুলি দীর্ঘ সময়ের জন্য প্রোগ্রামের অন্য অংশের মালিকানাধীন মিউটেক্সের জন্য অপেক্ষা করছে, তবে নীচের প্রোফাইলের ধরণটি তার জন্য আরও কার্যকর।

বিতর্ক-নিবিড় কোড

কনটেন্ট প্রোফাইল টাইপ প্রোগ্রামের সবচেয়ে "কাঙ্ক্ষিত" লকগুলিকে চিহ্নিত করে৷ এই প্রোফাইল টাইপটি Go প্রোগ্রামগুলির জন্য উপলব্ধ তবে এজেন্ট কনফিগারেশন কোডে " MutexProfiling: true " উল্লেখ করে স্পষ্টভাবে সক্ষম করতে হবে৷ সংগ্রহটি রেকর্ড করে ("বিরোধ" মেট্রিকের অধীনে) কতবার কাজ করে যখন একটি নির্দিষ্ট লক, যখন একটি গুরুটিন A দ্বারা আনলক করা হয়, অন্য একটি গুরুটিন বি লকটি আনলক হওয়ার জন্য অপেক্ষা করে। এটিও রেকর্ড করে ("বিলম্ব" মেট্রিকের অধীনে) যে সময় অবরুদ্ধ গোরুটিন লকের জন্য অপেক্ষা করেছিল। এই উদাহরণে, একটি একক বিতর্ক স্ট্যাক রয়েছে এবং লকটির জন্য মোট অপেক্ষার সময় ছিল 10.5 সেকেন্ড:

83f00dca4a0f768e.png

যে কোডটি এই প্রোফাইল তৈরি করে তাতে একটি মিউটেক্সের বিরুদ্ধে লড়াই করা 4টি গোরুটিন রয়েছে:

main.go

func contention(d time.Duration) {
        contentionImpl(d)
}

func contentionImpl(d time.Duration) {
        for {
                mu.Lock()
                time.Sleep(d)
                mu.Unlock()
        }
}
...
func main() {
        ...
        for i := 0; i < 4; i++ {
                go contention(time.Duration(i) * 50 * time.Millisecond)
        }
}

6. সারাংশ

এই ল্যাবে, আপনি শিখেছেন কিভাবে একটি গো প্রোগ্রাম ক্লাউড প্রোফাইলারের সাথে ব্যবহারের জন্য কনফিগার করা যায়। আপনি এই টুলের মাধ্যমে পারফরম্যান্স ডেটা সংগ্রহ, দেখতে এবং বিশ্লেষণ করতে শিখেছেন। আপনি এখন Google ক্লাউড প্ল্যাটফর্মে চালানো আসল পরিষেবাগুলিতে আপনার নতুন দক্ষতা প্রয়োগ করতে পারেন৷

7. অভিনন্দন!

আপনি ক্লাউড প্রোফাইলার কনফিগার এবং ব্যবহার করতে শিখেছেন!

আরও জানুন

লাইসেন্স

এই কাজটি ক্রিয়েটিভ কমন্স অ্যাট্রিবিউশন 2.0 জেনেরিক লাইসেন্সের অধীনে লাইসেন্সপ্রাপ্ত।