Computer >> บทช่วยสอนคอมพิวเตอร์ >  >> การเขียนโปรแกรม >> Ruby

เข้าใจ UUIDs vs. ULIDs: Deep Dive ไปยัง Unique Identifiers

อีกวันทีม HB คุยกัน และ Ben dev-ops master บอกว่าอยากใช้ ULIDs แทน UUIDs สำหระบบเฉพาะ

อย่างวิศวกรมืออาชีพ reaction ผมคือ mumble something non-committal แล้วขโมยไป Google หาว่า ULID คืออะไร

สองชั่วโมงต่อมา ผมออกมาพร้อม thousand-yard stare และการตระหนักว่าโลก unique identifiers ใหญ่และ wonderful กว่าที่ผมจินตนาการ

ก่อนเข้า ULIDs มากลับพื้นฐาน UUIDs ก่อน:

ปัญหาของ "regular" ids คืออะไร?

Web apps ใช้ databases ส่วนใหญ่ default numeric ids auto-increment ใน Rails อาจเห็น behavior แบบนี้:

p1 = Person.create!
p1.id # => 1
p2 = Person.create!
p2.id # => 2

Database generate sequential ids เพราะเก็บ counter increment on record creation

Pattern นี้เห็นนอก databases ด้วย บางครั้ง assign ids เอง อาจเก็บ custom counter ใน Redis instance

Sequential ids ง่ายสำหรับ low-volume แต่ problematic เมื่อ volume เพิ่ม:

  • สร้าง records concurrently ไม่ได้ เพราะแต่ละ insert ต้องรอคิวรับ id
  • Request sequential id อาจต้อง network round trip slower performance
  • ยาก scale out data stores ที่ให้ sequential ids ต้องกังวล counters บน servers ต่างๆ out of sync
  • Node ที่มี counter กลายเป็น single point of failure ได้ง่าย

Sequential ids ยัง leak data อาจเป็นปัญหาบางกรณี:

  • เดา ids ของ resources ที่อาจไม่ใช่ของคุณได้ง่าย
  • สร้าง user id 20 = รู้ว่า service มี 20 users

UUIDs are web-scale

UUIDs ดูต่าง sequential ids เป็น 128-bit numbers ปกติ expressed as 32 hexadecimal digits:

123e4567-e89b-12d3-a456-426655440000

UUIDs สร้างด้วย algorithms ใน RFC 4122 พยายามแก้ปัญหา sequential ids:

  • Generate UUIDs บน nodes หลายตัวได้โดยไม่ shared state หรือ coordination
  • Guess ยากกว่า sequential ids (รายละเอียดหลัง)
  • ไม่ divulge dataset size

Catch คือ มีโอกาสน้อยที่ nodes สองตัว generate same id independently เรียกว่า "collision"

หลายรสของ UUID

มี 5 types UUID algorithms ใน RFC 4122 แบ่ง 2 categories:

  • Time and randomness-based algorithms เราพูดถึง สร้าง UUID ใหม่ทุก run
    • Type 4: randomly-generated id น่าจะ best bet สำหรับโค้ดใหม่
    • Type 1: ID มี host's MAC address และ current timestamp Deprecated เพราะเดาง่ายเกิน
    • Type 2: ดู uncommon purpose-built สำหรับ RPC แบบเก่า
  • Name based algorithms ต่างหน่อย ให้ UUID เดียวกันสำหรับ input set เดียวกัน
    • Type 5: ใช้ SHA-1 hash generate UUID แนะนำ
    • Type 3: ใช้ MD5 hash deprecated เพราะ MD5 insecure

ใน Ruby generate UUIDs ผ่าน uuidtools gem รองรับทุก type ยกเว้น mysterious type 2:

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

Note: ต้นฉบับผมลืม link ULID spec นี่คือมัน มี links ไป implementations ใน Ruby และภาษาอื่นๆ

ULIDs เป็น useful new take on unique identifiers ความแตกต่างชัดเจนคือดูต่างกัน:

01ARZ3NDEKTSV4RRFFQ69G5FAV

ประกอบด้วย 2 base32-encoded numbers: UNIX timestamp ตามด้วย random number โครงสร้างใน spec:

01AN4Z07BY 79KA1307SR9X4MV3
|----------| |----------------|
Timestamp    Randomness
48bits       80bits

โครงสร้างนี้น่าสนใจ! UUIDs ใช้ timestamp หรือ randomness แต ULIDs ใช้ ทั้ง timestamp และ randomness

ผลคือ ULIDs มี properties น่าสนใจ:

  • Lexicographically (alphabetically) sortable
  • Timestamp accurate ถึง millisecond
  • สวยกว่า UUIDs :)

เปิดโอกาส cool possibilities:

  • Partition database by date ใช้ timestamp ใน ULID select partition ที่ถูกต้อง
  • Sort by ULID แทน created_at column ถ้า millisecond precision พอ

Downside อาจมี:

  • ถ้า expose timestamp ไม่ดีสำหรับแอป ULIDs อาจไม่ใช่ตัวเลือกดี
  • sort by ulid อาจไม่ work ถ้าต้อง sub-millisecond accuracy
  • ตามอินเทอร์เน็ต บาง ULID implementations ไม่ bulletproof

สรุป

UUIDs เป็นและจะยังคงเป็น standard อยู่มานาน libraries มีทุกภาษา แต new approaches คุ้มค่าพิจารณา โดยเฉพาะเข้าโลกที่ run by distributed systems มากขึ้น New unique-id approaches อาจช่วยแก้ปัญหาที่ไม่ prevalent ตอน RFC4122