दूसरे दिन HB टीम बातचीत कर रही थी और हमारे डेव-ऑप्स मास्टर बेन ने उल्लेख किया कि काश वह किसी विशेष सिस्टम के लिए UUIDs के बजाय ULID का उपयोग करता।
किसी भी अनुभवी इंजीनियर की तरह, मेरी प्रतिक्रिया थी कि मैं कुछ गैर-कम्फ़र्टेबल बात करूं और फिर Google के पास जाकर यह पता लगाने की कोशिश करूं कि ULID क्या है।
दो घंटे बाद मैं एक हजार गज की टकटकी और इस अहसास के साथ उभरा कि अद्वितीय पहचानकर्ताओं की दुनिया मेरी कल्पना से कहीं अधिक बड़ी और चमत्कारिक है।
इससे पहले कि हम यूएलआईडी के साथ शुरुआत करें, आइए बुनियादी बातों पर वापस जाएं और चर्चा करें कि यूयूआईडी क्या हैं:
"नियमित" आईडी में क्या समस्या है?
डेटाबेस का उपयोग करने वाले अधिकांश वेब एप्लिकेशन संख्यात्मक आईडी के लिए डिफ़ॉल्ट होते हैं जो स्वचालित रूप से बढ़ते हैं। उदाहरण के लिए, रेल में आप इस तरह का व्यवहार देख सकते हैं:
p1 = Person.create!
p1.id
# => 1
p2 = Person.create!
p2.id
# => 2
डेटाबेस अनुक्रमिक आईडी उत्पन्न कर सकता है क्योंकि यह एक काउंटर संग्रहीत करता है जो रिकॉर्ड निर्माण पर वृद्धि करता है।
यह पैटर्न डेटाबेस के बाहर भी देखा जा सकता है। कभी-कभी हमें मैन्युअल रूप से आईडी असाइन करने की आवश्यकता होती है, और हम एक कस्टम काउंटर को - जैसे - एक रेडिस इंस्टेंस में स्टोर कर सकते हैं।
कम-मात्रा वाले उपयोग-मामलों के लिए अनुक्रमिक आईडी लागू करना आसान है, लेकिन वॉल्यूम बढ़ने पर वे अधिक समस्याग्रस्त हो जाते हैं:
- एक साथ रिकॉर्ड बनाना असंभव है क्योंकि प्रत्येक इंसर्ट को अपनी आईडी प्राप्त करने के लिए लाइन में इंतजार करना पड़ता है।
- अनुक्रमिक आईडी का अनुरोध करने के लिए नेटवर्क राउंड ट्रिप की आवश्यकता हो सकती है और इसके परिणामस्वरूप प्रदर्शन धीमा हो सकता है।
- अनुक्रमिक आईडी प्रदान करने वाले डेटा स्टोर को मापना मुश्किल है। आपको विभिन्न सर्वरों पर काउंटरों के सिंक से बाहर होने के बारे में चिंता करनी होगी।
- काउंटर वाले नोड के लिए विफलता का एकल बिंदु बनना आसान है।
अनुक्रमिक आईडी भी डेटा लीक करते हैं, जो कुछ मामलों में एक समस्या हो सकती है:
- आप उन संसाधनों के आईडी का आसानी से अनुमान लगा सकते हैं जो शायद आपके नहीं हैं।
- यदि आप एक उपयोगकर्ता बनाते हैं और उसकी आईडी 20 है, तो आप जानते हैं कि सेवा में 20 उपयोगकर्ता हैं।
UUIDs वेब-स्केल हैं
यूयूआईडी अनुक्रमिक आईडी से थोड़ा अलग दिखते हैं। वे 128-बिट संख्याएं हैं, जिन्हें आमतौर पर 32 हेक्साडेसिमल अंकों के रूप में व्यक्त किया जाता है:
123e4567-e89b-12d3-a456-426655440000
UUIDs RFC 4122 में परिभाषित विशिष्ट एल्गोरिदम का उपयोग करके बनाए जाते हैं। वे अनुक्रमिक आईडी के साथ होने वाली कई समस्याओं को हल करने का प्रयास करते हैं:
- आप बिना किसी साझा स्थिति या नोड्स के बीच समन्वय के किसी भी संख्या में नोड्स पर यूयूआईडी उत्पन्न कर सकते हैं।
- अनुक्रमिक आईडी (उस पर बाद में अधिक) की तुलना में वे थोड़ा कम अनुमान लगाने योग्य हैं
- वे आपके डेटासेट के आकार का खुलासा नहीं करते हैं।
पकड़ यह है कि एक ही आईडी को स्वतंत्र रूप से उत्पन्न करने वाले दो नोड्स की एक छोटी सी संभावना है। इस घटना को "टकराव" कहा जाता है।
यूयूआईडी के कई फ्लेवर
RFC 4122 में परिभाषित पांच प्रकार के UUID एल्गोरिथम हैं। वे दो श्रेणियों में आते हैं:
- समय और यादृच्छिकता-आधारित एल्गोरिदम वे हैं जिनकी हम चर्चा कर रहे हैं। वे प्रत्येक रन के लिए एक नया यूयूआईडी बनाते हैं।
- टाइप 4 :एक बेतरतीब ढंग से उत्पन्न आईडी। शायद नए कोड के लिए हमारी सबसे अच्छी शर्त है।
- टाइप 1 :आईडी में होस्ट का मैक पता और वर्तमान टाइमस्टैम्प होता है। ये बहिष्कृत हैं क्योंकि इनका अनुमान लगाना बहुत आसान है।
- टाइप 2 :ये असामान्य प्रतीत होते हैं। ऐसा प्रतीत होता है कि वे आरपीसी के पुराने रूप के उद्देश्य से बनाए गए हैं।
- नाम आधारित एल्गोरिदम थोड़े अलग हैं। वे हमेशा दिए गए इनपुट के सेट के लिए एक ही UUID का उत्पादन करते हैं।
- टाइप 5 :UUID जनरेट करने के लिए SHA-1 हैश का उपयोग करता है। अनुशंसित।
- टाइप 3 :MD5 हैश का उपयोग करता है और इसे हटा दिया जाता है क्योंकि MD5 बहुत असुरक्षित है।
रूबी में, आप uuidtools
. के माध्यम से UUIDs उत्पन्न कर सकते हैं रत्न रहस्यमय प्रकार 2 को छोड़कर, यह हर प्रकार का समर्थन करता है;
# Code stolen from the uuidtools readme. :)
require "uuidtools"
# Type 1
UUIDTools::UUID.timestamp_create
# => #<UUID:0x2adfdc UUID:64a5189c-25b3-11da-a97b-00c04fd430c8>
# Type 4
UUIDTools::UUID.random_create
# => #<UUID:0x19013a UUID:984265dc-4200-4f02-ae70-fe4f48964159>
# Type 3
UUIDTools::UUID.md5_create(UUIDTools::UUID_DNS_NAMESPACE, "www.widgets.com")
# => #<UUID:0x287576 UUID:3d813cbb-47fb-32ba-91df-831e1593ac29>
# Type 5
UUIDTools::UUID.sha1_create(UUIDTools::UUID_DNS_NAMESPACE, "www.widgets.com")
# => #<UUID:0x2a0116 UUID:21f7f8de-8051-5b89-8680-0195ef798b6a>
ULIDs पर आगे बढ़ना
नोट: इस ब्लॉग पोस्ट के मूल संस्करण में मैं यूएलआईडी स्पेक से लिंक करना भूल गया था। यही पर है। यह रूबी और अन्य भाषाओं में कार्यान्वयन के लिए लिंक प्रदान करता है।
यूएलआईडी अद्वितीय पहचानकर्ताओं पर एक उपयोगी नई पहल है। सबसे स्पष्ट अंतर यह है कि वे थोड़े अलग दिखते हैं:
01ARZ3NDEKTSV4RRFFQ69G5FAV
वे दो बेस32-एन्कोडेड संख्याओं से बने होते हैं; एक UNIX टाइमस्टैम्प के बाद एक यादृच्छिक संख्या। यहाँ संरचना है, जैसा कि विनिर्देश में परिभाषित किया गया है:
01AN4Z07BY 79KA1307SR9X4MV3
|----------| |----------------|
Timestamp Randomness
48bits 80bits
यह संरचना आकर्षक है! यदि आपको याद हो, UUIDs टाइमस्टैम्प या यादृच्छिकता पर निर्भर करते हैं, लेकिन ULID टाइमस्टैम्प और दोनों का उपयोग करते हैं यादृच्छिकता।
परिणामस्वरूप, यूएलआईडी में कुछ दिलचस्प गुण होते हैं:
- वे लेक्सिकोग्राफ़िक (अर्थात् वर्णानुक्रम में) क्रमबद्ध हैं।
- टाइमस्टैम्प मिलीसेकंड के लिए सटीक है
- वे यूयूआईडी से अधिक सुंदर हैं :)
ये कुछ अच्छी संभावनाएं खोलते हैं:
- यदि आप तिथि के अनुसार अपने डेटाबेस का विभाजन कर रहे हैं, तो आप सही विभाजन का चयन करने के लिए ULID में एम्बेडेड टाइमस्टैम्प का उपयोग कर सकते हैं।
- यदि मिलीसेकंड सटीकता स्वीकार्य है, तो आप एक अलग create_at कॉलम के बजाय ULID के आधार पर क्रमित कर सकते हैं।
कुछ संभावित कमियां भी हैं:
- यदि टाइमस्टैम्प को उजागर करना आपके आवेदन के लिए एक बुरा विचार है, तो यूएलआईडी सबसे अच्छा विकल्प नहीं हो सकता है।
sort by ulid
यदि आपको उप-मिलीसेकंड सटीकता की आवश्यकता है तो दृष्टिकोण काम नहीं कर सकता है।- इंटरनेट के अनुसार, कुछ ULID कार्यान्वयन बुलेटप्रूफ नहीं हैं।
निष्कर्ष
यूयूआईडी मानक हैं और रहेंगे। वे हमेशा के लिए रहे हैं, और पुस्तकालय कल्पनाशील हर भाषा में उपलब्ध हैं। हालाँकि, नए दृष्टिकोण विचार करने योग्य हैं, खासकर जब हम एक ऐसी दुनिया में प्रवेश करते हैं जो वितरित प्रणालियों द्वारा तेजी से चलाई जा रही है। नए अद्वितीय-आईडी दृष्टिकोण हमें उन समस्याओं को हल करने में मदद कर सकते हैं जो RFC4122 के प्रकाशन के समय प्रचलित नहीं थीं।