গত দিন HB টিম চ্যাট করছিল এবং Ben, আমাদের DevOps মাস্টার, বললেন সে চেয়েছিল ULID ব্যবহার করা UUID-এর বদলে একটি নির্দিষ্ট সিস্টেমের জন্য।
যেকোনো অভিজ্ঞ ইঞ্জিনিয়ারের মত, আমার রিয়্যাকশন ছিল কিছু নন-কমিটাল মামলা করুন তারপর গুগলে চলে যাই ULID আসলে কী সেটি বুঝতে।
দুই ঘন্টা পরেরে আমি এক হাজার গজ দূরদর্শী স্টেয়ার এবং এই বোধে বের হয়েলাম যে ইউনিক আইডেন্টিফায়ারের বিশ্ব আমার কল্পনার চেয়ে বড় এবং বেশি আশ্চর্য।
ULID-এ যাওয়ার আগে, বেসিকস থেকে শুরু করি এবং UUID কী সেটি ডিসকাস করি:
"নियमিত" ID-র সমস্যা কী?
ডাটাবেস ব্যবহার করে অধিকাংশ ওয়েব অ্যাপ্লিকেশন ডিফল্টলি न्यूमেরিক ID ব্যবহার করে যা অটোমেটিক্যালি ইনক্রিমেন্ট হয়। উদাহরণস্বরূপ, Rails-এ আপনি এমন বিহেভিয়ার দেখতে পারেন:
p1 = Person.create!
p1.id # => 1
p2 = Person.create!
p2.id # => 2
ডাটাবেস সিকুয়েনশিয়াল ID জেনারেট করতে পারে কারণ সেটি একটি কাউন্টার স্টোর করে যা রেকর্ড ক্রিয়েশনে ইনক্রিমেন্ট হয়।
এই প্যাটার্ন ডাটাবেসের বাইরেও দেখা যায়। কখনো কখনো আমাদের ম্যানুয়ালি ID অ্যাসাইন করতে হয়, এবং আমরা একটি কাস্টম কাউন্টার স্টোর করতে পারি - বলুন - একটি Redis ইনস্ট্যান্সে।
সিকুয়েনশিয়াল ID লো-ভলিউম ইউজ-কেসের জন্য ইজি টু ইমপ্লিমেন্ট, কিন্তু ভলিউম বাড়ার সাথে সাথে সেগুলো আরও প্রাব্লেম্যাটিক হয়ে যায়:
- রেকর্ড কনকারেন্টলি তৈরি করা অসম্ভব কারণ প্রতিটি ইনসার্টকে তার ID পাওয়ার জন্য লাইনে দাঁড়াতে হয়।
- সিকুয়েনশিয়াল ID রিকোয়েস্ট করতে হলে নেটওয়ার্ক রাউন্ড ট্রিপ লাগতে পারে এবং স্লোওয়ার পারফরম্যান্স ফলাফল আসতে পারে।
- সিকুয়েনশিয়াল ID প্রদানকারী ডেটা স্টোর স্কেল আউট করা কঠিন। আপনাকে চিন্তা করতে হয় বিভিন্ন সার্ভারের কাউন্টারগুলো আউট-অফ-সিন্ক না হয়।
- কাউন্টার থাকা নোডটি সহজে সিঙ্গল পয়েন্ট অফ ফেইলিউর হতে পারে।
সিকুয়েনশিয়াল ID ডেটা লিক ও করে, যা কিছু কেসে সমস্যা হতে পারে:
- আপনি সহজে রিসোর্সের ID গেস করতে পারেন যা আপনার নাও হতে পারে।
- আপনি একজন ইউজার তৈরি করেন এবং এর ID ২০, তাহলে আপনি জানте পারেন সার্ভিসে ২০ ইউজার আছে।
UUID হচ্ছে ওয়েব-স্কেল
UUID দেখতে সিকুয়েনশিয়াল ID থেকে আলাদা। এগুলো ১২৮-বিট নম্বর, সাধারণত ৩২ হেক্সাডেসিমেল ডিজিট হিসেবে এক্সপ্রেস করা হয়:
123e4567-e89b-12d3-a456-426655440000
UUID RFC 4122-এ ডিফাইনড নির্দিষ্ট অ্যালগরিদম ব্যবহার করে তৈরি হয়। সেগুলো সিকুয়েনশিয়াল ID-র সাথে হওয়া অনেক সমস্যা সমাধান করার চেষ্টা করে:
- আপনি যেকোনো সংখ্যক নোডে UUID জেনারেট করতে পারেন কোনো শেয়ার্ড স্টেট বা নোডগুলোর মধ্যে কোঅর্ডিনেশন ছাড়া।
- সেগুলো সিকুয়েনশিয়াল ID থেকে একটু কম গেসযোগ্য (আরো detal 후에)
- সেগুলো আপনার ডেটাসেটের সাইজ ডিসক্লোজ করে না।
ক্যাচ হচ্ছে দুটি নোড স্বতন্ত্রভাবে একই ID জেনারেট করার ছোট একটি চান্স আছে। এই ইভেন্টকে "কলিশন" বলা হয়।
UUID-এর অনেক ফ্লেভার
RFC 4122-এ UUID অ্যালগরিদমের পাঁচ টাইপ ডিফাইনড আছে। সেগুলো দুটি ক্যাটাগরিতে পড়ে:
- টাইম এবং র্যান্ডমনেস-বেসড অ্যালগরিদম যেগুলো আমরা আলোচনা করছি। সেগুলো প্রতিটি রানে একটি নতুন UUID ফলাফল দেয়।
- Type 4: একটি র্যান্ডমলি-জেনারেটেড ID। নতুন কোডের জন্য প্রায় সেরা বেট।
- Type 1: ID-তে হোস্টের MAC অ্যাড্রেস এবং করেন্ট টাইমস্ট্যাম্প থাকে। এগুলো ডিপ্রিকেটেড কারণ খুব সহজে গেস করা যায়।
- Type 2: এগুলো uncommon লাগে। এগুলো প্রাচীন একটি RPC ফর্মের জন্য পারপাস-বিল্ট বলে মনে হয়।
- নেম-বেসড অ্যালগরিদম একটু আলাদা। সেগুলো একটি প্রদত্ত ইনপুট সেটের জন্য সবসময় একই UUID প্রোডিউস করে।
- Type 5: SHA-1 হ্যাশ ব্যবহার করে UUID জেনারেট করে। রিকমেন্ডেড।
- Type 3: MD5 হ্যাশ ব্যবহার করে এবং ডিপ্রিকেটেড কারণ MD5 খুব ইনসিকিউয়ার।
Ruby-এ, আপনি uuidtools gem দিয়ে UUID জেনারেট করতে পারেন। এটি সব টাইপ সাপোর্ট করে, মিস্টেরিয়াস টাইপ ২ ছাড়া;
# uuidtools readme থেকে চুরি করা কোড। :)
require "uuidtools"
# Type 1
UUIDTools::UUID.timestamp_create
# => #
# Type 4
UUIDTools::UUID.random_create
# => #
# Type 3
UUIDTools::UUID.md5_create(UUIDTools::UUID_DNS_NAMESPACE, "www.widgets.com")
# => #
# Type 5
UUIDTools::UUID.sha1_create(UUIDTools::UUID_DNS_NAMESPACE, "www.widgets.com")
# => #
ULID-এ যাওয়া যাক
নোট: এই ব্লগ পোস্টের অরিজিনাল ভার্সনে আমি ULID স্পেসিফিকেশনের লিংক ভুলে গেছিলাম। এখানে সেটি। এতে Ruby এবং অন্যান্য ল্যাঙ্গুয়েজে ইমপ্লিমেন্টেশনের লিংক আছে।
ULID হচ্ছে ইউনিক আইডেন্টিফায়ারের একটি উপযোগী নতুন দৃষ্টিভঙ্গি। সবচেয়ে oč어가 পার্থক্য হচ্ছে সেগুলো একটু আলাদা দেখে:
01ARZ3NDEKTSV4RRFFQ69G5FAV
এগুলো দুইটি base32-এনকোডেড নম্বর দিয়ে তৈরি; একটি UNIX টাইমস্ট্যাম্প ফলো করা একটি র্যান্ডম নম্বর। এখানে স্ট্রাকচার, স্পেসিফিকেশনে ডিফাইনড হিসাবে:
01AN4Z07BY 79KA1307SR9X4MV3
|----------| |----------------|
Timestamp Randomness
48bits 80bits
এই স্ট্রাকচার চমৎকার! আপনি যদি মনে রাখেন, UUID বা টাইমস্ট্যাম্প বা র্যান্ডমনেসের উপর নির্ভর করে, কিন্তু ULID দুটোই ব্যবহার করে টাইমস্ট্যাম্প এবং র্যান্ডমনেস।
ফলস্বরূপ, ULID-এর কিছু ইন্টারেস্টিং প্রপার্টি আছে:
- সেগুলো লেক্সিকোগ্রাফিক্যালি (অর্থাৎ অ্যালফাবেটিক্যালি) সর্টেবল।
- টাইমস্ট্যাম্প মিলিসেকেন্ড একুরেসি পর্যন্ত সঠিক।
- UUID-এর চেয়ে প্রিটিয়ার :)
এই প্রপার্টিগুলো কিছু কুল পসিবিলিটি খুলে দেয়:
- আপনি যদি আপনার ডাটাবেস ডেটা দিয়ে পার্টিশন করেন, আপনি ULID-এ এমবেডেড টাইমস্ট্যাম্প ব্যবহার করে সঠিক পার্টিশন সিলেক্ট করতে পারেন।
- আপনি ULID দিয়ে সর্ট করতে পারেন আলাদা
created_atকলামের বদলে যদি মিলিসেকেন্ড প্রিসিশন একসেপ্টেবল হয়।
কিছু পসিবল ডাউনসাইডও আছে:
- যদি টাইমস্ট্যাম্প এক্সপোজ করা আপনার অ্যাপ্লিকেশনের জন্য ব্যাড আইডিয়া হয়, ULID সেরা অপশন নাও হতে পারে।
sort by ulidঅ্যাপ্রোচ কাজ নাও করতে পারে যদি সাব-মিলিসেকেন্ড একুরেসি দরকার হয়।- ইন্টারনেট অনুযায়ী, কিছু ULID ইমপ্লিমেন্টেশন বুলেটপ্রুফ নয়।
উপসংহার
UUID মানেই এবং থাকবে স্ট্যান্ডার্ড। সেগুলো যুগ যুগ ধরে আছে, এবং সব ইমেজিনেবল ল্যাঙ্গুয়েজে লাইব্রেরি আছে। তবে, নতুন অ্যাপ্রোচ বিবেচনা করা উচিত, বিশেষ করে যেহেতু আমরা একটি ऐसी বিশ্বে ঢুকছি যা ngày দিন ডিস্ট্রিবিউটেড সিস্টেম দ্বারা চালিত হচ্ছে। নিউ ইউনিক-আইডি অ্যাপ্রোচরা আমাদের সে সমস্যাগুলো সমাধান করতে সাহায্য করতে পারে যেগুলো RFC 4122 পাবলিশ হওয়ার সময় প্রিভ্যালেন্ট নয়।