Kiến trúc hệ thốngCơ sở dữ liệu (Database)

Cơ sở dữ liệu (Database)

Nội dung bài

Cơ sở dữ liệu (Database)

Chủ đề30 phút đọcThe System Design Primer - mục "Database"

Mục lục
  1. Nội dung gốc
  2. Ghi chú của người dịch

Cơ sở dữ liệu (Database)

Nội dung gốc

Sơ đồ mở rộng cơ sở dữ liệu khi hệ thống tăng trưởng
Nguồn: Scaling up to your first 10 million users

Hệ quản trị cơ sở dữ liệu quan hệ (RDBMS)

Một cơ sở dữ liệu quan hệ như SQL là một tập hợp các mục dữ liệu được tổ chức thành các bảng.

ACID là tập hợp các thuộc tính của giao dịch (transaction) trong cơ sở dữ liệu quan hệ.

Có nhiều kỹ thuật để mở rộng một cơ sở dữ liệu quan hệ: nhân bản master-slave, nhân bản master-master, federation, sharding, phi chuẩn hóa (denormalization) và tinh chỉnh SQL (SQL tuning).

Nhân bản master-slave (Master-slave replication)

Master phục vụ cả đọc lẫn ghi, đồng thời nhân bản các thao tác ghi sang một hoặc nhiều slave; các slave chỉ phục vụ đọc. Slave cũng có thể nhân bản tiếp sang các slave khác theo dạng cây. Nếu master ngừng hoạt động, hệ thống có thể tiếp tục chạy ở chế độ chỉ đọc cho tới khi một slave được nâng cấp thành master hoặc một master mới được cấp phát.

Sơ đồ nhân bản master-slave
Nguồn: Scalability, availability, stability, patterns
Nhược điểm: nhân bản master-slave

Nhân bản master-master (Master-master replication)

Cả hai master đều phục vụ đọc và ghi, và phối hợp với nhau khi ghi. Nếu một trong hai master ngừng hoạt động, hệ thống vẫn tiếp tục chạy với cả đọc lẫn ghi.

Sơ đồ nhân bản master-master
Nguồn: Scalability, availability, stability, patterns
Nhược điểm: nhân bản master-master
So sánh nhân bản master-slave và master-master Master-slave Master Slave Slave chỉ đọc, nhân bản từ master Master-master Master A Master B cả hai đọc + ghi, đồng bộ ghi hai chiều
Master-slave: master nhận mọi thao tác ghi và nhân bản sang các slave chỉ phục vụ đọc. Master-master: cả hai node cùng đọc và ghi, đồng bộ ghi với nhau và phải giải quyết xung đột khi hai bên cùng sửa một bản ghi.
Nhược điểm: nhân bản
Nguồn và đọc thêm: nhân bản

Federation

Sơ đồ federation - tách cơ sở dữ liệu theo chức năng
Nguồn: Scaling up to your first 10 million users

Federation (hay phân vùng theo chức năng - functional partitioning) tách cơ sở dữ liệu theo chức năng. Ví dụ, thay vì một cơ sở dữ liệu nguyên khối duy nhất, bạn có thể có ba cơ sở dữ liệu: forums, users và products, nhờ đó lưu lượng đọc và ghi vào mỗi cơ sở dữ liệu ít hơn, và vì vậy độ trễ nhân bản cũng thấp hơn. Cơ sở dữ liệu nhỏ hơn thì nhiều dữ liệu vừa trong bộ nhớ hơn, từ đó tăng tỉ lệ trúng cache (cache hit) nhờ tính cục bộ của cache (cache locality) tốt hơn. Vì không còn một master trung tâm duy nhất phải tuần tự hóa các thao tác ghi, bạn có thể ghi song song, tăng thông lượng (throughput).

Nhược điểm: federation
Nguồn và đọc thêm: federation

Sharding

Sơ đồ sharding - chia dữ liệu ra nhiều cơ sở dữ liệu
Nguồn: Scalability, availability, stability, patterns

Sharding phân tán dữ liệu ra nhiều cơ sở dữ liệu khác nhau sao cho mỗi cơ sở dữ liệu chỉ quản lý một tập con của dữ liệu. Lấy cơ sở dữ liệu người dùng làm ví dụ: khi số người dùng tăng, ta thêm nhiều shard hơn vào cụm (cluster).

Tương tự ưu điểm của federation, sharding giúp giảm lưu lượng đọc và ghi, giảm nhân bản và tăng tỉ lệ trúng cache. Kích thước chỉ mục (index) cũng giảm, thường giúp cải thiện hiệu năng với truy vấn nhanh hơn. Nếu một shard ngừng hoạt động, các shard khác vẫn chạy, dù bạn sẽ muốn thêm một hình thức nhân bản nào đó để tránh mất dữ liệu. Giống federation, không có master trung tâm duy nhất tuần tự hóa các thao tác ghi, nên bạn có thể ghi song song và tăng thông lượng.

Cách phổ biến để shard một bảng người dùng là theo chữ cái đầu của họ (last name) người dùng hoặc theo vị trí địa lý của người dùng.

So sánh federation và sharding Federation (theo chức năng) App Forums Users Products Sharding (cùng bảng, chia theo khóa) App Shard 1 (họ A–M) Shard 2 (họ N–Z)
Federation tách theo chức năng (forums/users/products mỗi thứ một DB). Sharding chia cùng một bảng thành nhiều phần theo một khóa, ví dụ chữ cái đầu của họ.
Nhược điểm: sharding
Nguồn và đọc thêm: sharding

Phi chuẩn hóa (Denormalization)

Phi chuẩn hóa cố gắng cải thiện hiệu năng đọc với cái giá là giảm một phần hiệu năng ghi. Các bản sao dư thừa của dữ liệu được ghi vào nhiều bảng để tránh các phép join tốn kém. Một số RDBMS như PostgreSQL và Oracle hỗ trợ khung nhìn cụ thể hóa (materialized view), đảm nhận việc lưu thông tin dư thừa và giữ các bản sao dư thừa nhất quán với nhau.

Khi dữ liệu đã được phân tán bằng các kỹ thuật như federation và sharding, việc quản lý join xuyên trung tâm dữ liệu càng làm tăng độ phức tạp. Phi chuẩn hóa có thể giúp tránh phải thực hiện những phép join phức tạp như vậy.

Trong hầu hết hệ thống, số lượt đọc có thể áp đảo số lượt ghi theo tỉ lệ 100:1, thậm chí 1000:1. Một lượt đọc dẫn tới phép join phức tạp trong cơ sở dữ liệu có thể rất tốn kém, tiêu tốn đáng kể thời gian cho các thao tác đĩa.

Nhược điểm: phi chuẩn hóa
Nguồn và đọc thêm: phi chuẩn hóa

Tinh chỉnh SQL (SQL tuning)

Tinh chỉnh SQL là một chủ đề rộng và đã có nhiều cuốn sách được viết để làm tài liệu tham khảo.

Điều quan trọng là phải đo hiệu năng (benchmark) và phân tích hiệu năng (profile) để mô phỏng và phát hiện nút thắt cổ chai (bottleneck).

Benchmark và profile có thể dẫn bạn tới các tối ưu sau.

Siết chặt lược đồ (Tighten up the schema)
Dùng chỉ mục tốt (Use good indices)
Tránh các phép join tốn kém
Phân vùng bảng (Partition tables)
Tinh chỉnh query cache
Nguồn và đọc thêm: tinh chỉnh SQL

NoSQL

NoSQL là tập hợp các mục dữ liệu được biểu diễn trong một kho khóa - giá trị (key-value store), kho tài liệu (document store), kho cột rộng (wide column store) hoặc cơ sở dữ liệu đồ thị (graph database). Dữ liệu được phi chuẩn hóa, và các phép join thường được thực hiện trong code ứng dụng. Hầu hết các kho NoSQL không có giao dịch ACID thực sự và ưu tiên nhất quán cuối cùng (eventual consistency).

BASE thường được dùng để mô tả các thuộc tính của cơ sở dữ liệu NoSQL. So với định lý CAP, BASE chọn tính sẵn sàng thay vì tính nhất quán.

Ngoài việc chọn giữa SQL hay NoSQL, cũng nên hiểu loại cơ sở dữ liệu NoSQL nào phù hợp nhất với (các) trường hợp sử dụng của bạn. Phần tiếp theo sẽ điểm qua kho khóa - giá trị, kho tài liệu, kho cột rộng và cơ sở dữ liệu đồ thị.

Kho khóa - giá trị (Key-value store)

Trừu tượng hóa: bảng băm (hash table)

Một kho khóa - giá trị thường cho phép đọc và ghi trong O(1), và thường được lưu trên bộ nhớ hoặc SSD. Kho dữ liệu có thể giữ các khóa theo thứ tự từ điển (lexicographic order), cho phép truy xuất hiệu quả một dải khóa. Kho khóa - giá trị có thể cho phép lưu siêu dữ liệu (metadata) đi kèm giá trị.

Kho khóa - giá trị cho hiệu năng cao và thường được dùng cho các mô hình dữ liệu đơn giản hoặc dữ liệu thay đổi nhanh, chẳng hạn một tầng cache trong bộ nhớ. Vì chúng chỉ cung cấp một tập thao tác hạn chế, độ phức tạp bị đẩy sang tầng ứng dụng nếu cần thêm thao tác.

Kho khóa - giá trị là nền tảng cho các hệ thống phức tạp hơn như kho tài liệu, và trong một số trường hợp là cả cơ sở dữ liệu đồ thị.

Nguồn và đọc thêm: kho khóa - giá trị

Kho tài liệu (Document store)

Trừu tượng hóa: kho khóa - giá trị với giá trị là các tài liệu

Kho tài liệu xoay quanh các tài liệu (XML, JSON, nhị phân, v.v.), trong đó một tài liệu lưu toàn bộ thông tin của một đối tượng. Kho tài liệu cung cấp API hoặc ngôn ngữ truy vấn để truy vấn dựa trên cấu trúc bên trong của chính tài liệu. Lưu ý: nhiều kho khóa - giá trị có tính năng làm việc với siêu dữ liệu của giá trị, khiến ranh giới giữa hai kiểu lưu trữ này trở nên mờ nhạt.

Tùy vào cách hiện thực bên dưới, tài liệu được tổ chức theo bộ sưu tập (collection), thẻ (tag), siêu dữ liệu hoặc thư mục. Dù các tài liệu có thể được tổ chức hoặc nhóm lại với nhau, chúng vẫn có thể có những trường hoàn toàn khác nhau.

Một số kho tài liệu như MongoDB và CouchDB cũng cung cấp một ngôn ngữ giống SQL để thực hiện các truy vấn phức tạp. DynamoDB hỗ trợ cả khóa - giá trị lẫn tài liệu.

Kho tài liệu mang lại tính linh hoạt cao và thường được dùng để làm việc với dữ liệu thỉnh thoảng thay đổi.

Nguồn và đọc thêm: kho tài liệu

Kho cột rộng (Wide column store)

Sơ đồ cấu trúc kho cột rộng
Nguồn: SQL & NoSQL, a brief history

Trừu tượng hóa: map lồng nhau ColumnFamily<RowKey, Columns<ColKey, Value, Timestamp>>

Đơn vị dữ liệu cơ bản của kho cột rộng là một cột (cặp tên/giá trị). Các cột có thể được nhóm thành họ cột (column family, tương tự một bảng SQL). Siêu họ cột (super column family) lại nhóm các họ cột với nhau. Bạn có thể truy cập từng cột độc lập bằng khóa hàng (row key), và các cột có cùng khóa hàng tạo thành một hàng. Mỗi giá trị kèm một dấu thời gian (timestamp) dùng để quản lý phiên bản và giải quyết xung đột.

Google giới thiệu Bigtable là kho cột rộng đầu tiên, có ảnh hưởng tới HBase mã nguồn mở (thường dùng trong hệ sinh thái Hadoop) và Cassandra của Facebook. Các kho như BigTable, HBase và Cassandra giữ khóa theo thứ tự từ điển, cho phép truy xuất hiệu quả các dải khóa được chọn.

Kho cột rộng mang lại tính sẵn sàng cao và khả năng mở rộng cao. Chúng thường được dùng cho các tập dữ liệu rất lớn.

Nguồn và đọc thêm: kho cột rộng

Cơ sở dữ liệu đồ thị (Graph database)

Ví dụ đồ thị thuộc tính trong cơ sở dữ liệu đồ thị
Nguồn: Graph database

Trừu tượng hóa: đồ thị (graph)

Trong cơ sở dữ liệu đồ thị, mỗi nút (node) là một bản ghi và mỗi cung (arc) là một quan hệ giữa hai nút. Cơ sở dữ liệu đồ thị được tối ưu để biểu diễn các quan hệ phức tạp với nhiều khóa ngoại (foreign key) hoặc nhiều quan hệ nhiều - nhiều (many-to-many).

Cơ sở dữ liệu đồ thị cho hiệu năng cao với các mô hình dữ liệu có quan hệ phức tạp, chẳng hạn một mạng xã hội. Chúng còn tương đối mới và chưa được dùng rộng rãi; có thể khó tìm công cụ phát triển và tài liệu hơn. Nhiều cơ sở dữ liệu đồ thị chỉ có thể truy cập qua REST API.

Nguồn và đọc thêm: đồ thị

Nguồn và đọc thêm: NoSQL

SQL hay NoSQL

So sánh chuyển đổi từ RDBMS sang NoSQL
Nguồn: Transitioning from RDBMS to NoSQL

Lý do chọn SQL:

Lý do chọn NoSQL:

Dữ liệu mẫu rất phù hợp với NoSQL:

Lược đồ cố định của SQL so với tài liệu linh hoạt của NoSQL SQL — lược đồ cố định id tên email NoSQL — linh hoạt 2 trường 4 trường 1 trường
Bảng SQL buộc mọi hàng theo đúng cột đã định sẵn; trong kho tài liệu NoSQL, mỗi tài liệu có thể có số trường khác nhau.

Nguồn và đọc thêm: SQL hay NoSQL


Nguồn: The System Design Primer - mục "Database" — Donne Martin và cộng đồng đóng góp

Giấy phép: CC BY 4.0 (nguyên bản: Donne Martin, The System Design Primer)

Xem bản gốc

Bài tiếp theoBộ nhớ đệm (Cache)