Schemaless trực quan hoávisualized

Uber Engineering · Kho dữ liệu chuyến điUber Engineering · Trip Datastore

Schemaless

Cách Uber lưu trữ lượng chuyến đi khổng lồ trên MySQL thông thường — chia thành hàng nghìn phần, sao chép qua nhiều trung tâm dữ liệu, và không bao giờ ghi đè.How Uber stores a planet's worth of trips on plain MySQL — split thousands of ways, copied across data centers, and never overwritten.

4096 shardshards 3 bản sao mỗi shardcopies each 0 lần ghi đèoverwrites
01Vấn đềThe problem

Một cuốn sổ là không đủOne notebook breaks

Hãy hình dung mọi chuyến đi Uber ghi trong một cuốn sổ. Khi lớn lên, ba vấn đề xảy ra:Picture every Uber trip written in a single notebook. Three things go wrong as it grows:

!

Hết chỗRuns out of room

Một máy chạm giới hạn dung lượng và tốc độ.One machine hits its limit on space and speed.

×

Điểm chết đơn lẻSingle point of failure

Lỡ đổ cà phê là mất sạch chuyến đi.Spill coffee once and every trip is gone.

⇄

Ghi đè lẫn nhauWriters collide

Hai lần sửa cùng một dòng cùng lúc gây loạn.Two edits to the same line at once cause chaos.

02Ý tưởng cốt lõiThe core idea

Cell: dữ liệu không bao giờ ghi đèThe cell: data you never overwrite

Đơn vị nhỏ nhất là cell — ghi chú không sửa được, tìm bằng ba khoá. Để “cập nhật”, bạn không xoá; bạn xếp chồng phiên bản mới với ref_key lớn hơn. Mới nhất thắng, cũ vẫn còn.The smallest unit is a cell — an immutable note found by three keys. To “update”, you don't erase; you stack a new version with a higher ref_key. Newest wins, old ones stay.

Thử xem. Mỗi thao tác thêm một phiên bản mới — không gì phía trên biến mất.Try it. Each action appends a new version — nothing above ever disappears.

Cùng row_key + column_name, ref_key cao hơn = phiên bản mới. Vì lệnh ghi chỉ thêm vào, gửi lại một lệnh là vô hại — nhờ vậy Schemaless retry an toàn (idempotent).Same row_key + column_name, higher ref_key = a new version. Because writes only ever add, re-sending one is harmless — that's why Schemaless can safely retry (idempotent).

ĐỌC trả về ref_key cao nhấtREAD returns the highest ref_key
03Kiến trúcArchitecture

Worker định tuyến, storage lưu giữWorkers route, storage keeps

Hai loại máy chủ, tách riêng để mỗi loại tự mở rộng. Worker định tuyến request; storage giữ dữ liệu gồm một master và hai minion ở các trung tâm dữ liệu khác. Tắt master để xem cơ chế dự phòng.Two server types, separated so each scales alone. Workers route requests; storage holds data as one master plus two minions in other data centers. Flip the master off to see the failover.

Client Worker node routes & retries one shard · 1 master + 2 minions Master accepts writes Minion · DC-2 read replica Minion · DC-3 read replica

04ShardingSharding

4096 ngăn kéo, mỗi khoá một chỗ4096 drawers, one home per key

Dữ liệu chia thành 4096 shard. Một row_key luôn băm về cùng một shard, nên dữ liệu của một chuyến đi nằm cùng chỗ. Nhập một khoá và định tuyến:Data is split into 4096 shards. A row_key always hashes to the same shard, so one trip's data stays together. Type a key and route it:

04095
05Độ bềnDurability

Buffered writes: không mất gìBuffered writes: lose nothing

MySQL sao chép sang bản dự phòng sau khi báo “đã lưu”. Nếu master sập sau đó, lệnh ghi mất. Cách khắc phục: ghi vào hai cluster; chỉ báo thành công khi cả hai cùng thành công.MySQL copies to backups after saying “saved”. If the master then dies, the write is lost. The fix: write to two clusters; report success only if both work.

Worker node one write Secondary cluster buffer table · safety net Primary cluster where reads look Background job clears buffer when confirmed

06Schema dữ liệuData schema

Bên trong một shard: bảng entityInside one shard: the entity table

Mỗi cell là một hàng MySQL. Trường body linh hoạt là phần “schemaless” — client tự quyết hình dạng dữ liệu, MySQL không đổi.Every cell is one MySQL row. The flexible body blob is the “schemaless” part — the client controls the shape, MySQL never changes.

CộtColumn KiểuType Mục đíchPurpose
added_idint auto-incKhoá chính. Khiến MySQL ghi hàng tuần tự trên đĩa (nhanh); cũng là con trỏ theo thứ tự.Primary key. Makes MySQL write rows linearly on disk (fast); also an ordered pointer.
row_keyuuidĐối tượng nào — vd: một chuyến đi.Which thing — e.g. a trip.
column_namestringTrường nào.Which field.
ref_keyintPhiên bản nào (cao hơn = mới hơn).Which version (higher = newer).
bodyblobNội dung JSON, được nén (MessagePack + ZLib).The JSON content, compressed (MessagePack + ZLib).
created_atdatetimeThời điểm cell được chèn.When the cell was inserted.
07Trong thực tếIn practice

Khi nào nên dùngWhen to reach for it

Rất phù hợpGreat fits

  • Bản ghi chuyến đi / đơn hàngTrip / order records — lượng ghi lớn, cần lịch sử, không được mất dữ liệu.high write volume, needs history, must never lose data.
  • Nhật ký sự kiện & auditEvent logs & audit trails — append-only tạo ra log có thứ tự tự nhiên.append-only gives a natural ordered log.
  • Hồ sơ / cài đặt người dùngUser profiles / settings — JSON linh hoạt thích nghi khi trường thay đổi.flexible JSON adapts as fields change.
  • Bản ghi kiểu tài chínhFinancial-style records — versioning + buffered writes = độ bền cao.versioning + buffered writes = strong durability.

Đánh đổi phải chấp nhậnTrade-offs to accept

  • Dung lượng tăngStorage grows — phiên bản cũ được giữ, không xoá.old versions are kept, not deleted.
  • Minion có thể cũMinions can be stale — nhân bản bất đồng bộ trễ dưới một giây.async replication lags ~subsecond.
  • Dữ liệu đệm chưa đọc đượcBuffered data isn't readable yet — đã lưu khi sập, nhưng chờ cluster chính hồi phục.saved on crash, but not until the primary recovers.
  • Không hợp join phức tạpNot for complex joins — truy vấn quan hệ ad-hoc hợp RDBMS truyền thống hơn.ad-hoc relational queries fit a classic RDBMS better.
Schemaless mở rộng dữ liệu của Uber bằng cách chia thành hàng nghìn shard MySQL được nhân bản, append-only — đạt quy mô lớn và khả năng chống sập từ những thành phần đơn giản, đã kiểm chứng, kết hợp khéo léo.Schemaless scales Uber's data by splitting it into thousands of replicated, append-only MySQL shards — earning huge scale and crash-resistance from simple, proven parts combined cleverly.