Mở rộng cơ sở dữ liệu

Jeremiah Peschka

Mở rộng hệ thống theo chiều dọc(tăng cường phần cứng, tối ưu code để sử dụng tối đa tài nguyên) là khó, mở rộng theo chiều ngang(triển khai thêm nhiều bản sao của các hệ thống con trên các server khác) thậm chí còn khó hơn. Mọi hệ thống thông tin đều phải duy trì mục tiêu là toàn vẹn(consistent). DB, nơi lưu giữ trạng thái của ứng dụng, căn cơ của sự toàn ven trong hệ thống thông tin. Việc mở rộng hệ thống, phải bắt đầu với kế hoạch mở rộng DB. Chúng ta đều biết rằng chúng ta có thể mở rộng DB với việc mở rộng khả năng đọc bằng cách tăng thêm một số bản sao (hoặc bản sao chỉ đọc) của cơ sở dữ liệu. Tăng bản sao kết hợp với  sử dụng thêm một lớp bộ nhớ đệm(cache) giúp giải quyết được việc mở rộng khả năng đọc. Nhưng điều gì sẽ xảy ra khi chúng ta phải mở rộng ghi?

Xem xét ngữ cảnh của 1 siêu thị, một cơ sở dữ liệu có quy mô hiệu quả cho việc đọc sẽ giống như siêu thị có bãi đậu xe rộng rãi, lối đi rộng và đủ ánh sáng, có rất nhiều xe đẩy có sức chứa cao dành cho mọi người sử dụng mua sắm. Thậm chí còn có 20 quầy thanh toán. Vấn đề là hàng hóa chỉ vào cửa hàng thông qua một băng tải có sức chứa của một chiếc xe tải. Người mua sắm có thể vào hoặc ra khỏi siêu thị một cách nhanh chóng, nhưng việc đưa hàng hóa mới lên được các giá hàng, tới tay người tiêu dùng lại gặp khó khăn.


Nếu chúng ta thiết kế lại siêu thị để có thể bán được nhiều hàng hơn, chúng ta cần đặt ra câu hỏi:
  • Bao lâu thì chúng ta có hàng mới về? . Các lô hàng đến hoặc việc phân bổ hàng lên giá có sảy ra cùng một lúc không?
  • Hàng mới về cần phải đi tới đâu trong cửa hàng?
  • Chúng ta có thể đặt các loại hàng hóa tương tự nhau trên 1 băng tải không?

Mở rộng để phục vụ nhiều hơn

Để có thể ghi nhiều dữ liệu hơn vào db, tất nhiên chúng ta cần mở rộng khả năng ghi. Với giới hạn vật lý khi mà chúng ta không thể tăng khả năng ghi dữ liệu thì việc có tăng thêm phần cứng cũng không thể giải quyết được vấn đề. Việc ghi có thể gặp khó khăn hoặc treo với bất kỳ 1 câu lệnh hoặc 1 giao dịch vượt ra khỏi năng lực thực tế của server.
Chúng ta có thể tiếp cận vấn đề theo một vài cách:
  • Ghi cho một máy chủ và đọc từ một máy chủ khác
  • Ghi cho nhiều máy chủ và đọc từ nhiều máy chủ

Master-Slave

Master – thực hiện ghi. Slave – thực hiện đọc
Đây là giải pháp đúng cho việc mở rộng khả năng đọc.
Tuy nhiên, thay vì đọc ghi trên 1 máy chủ, phải xử lí tập trung với các vấn đề về locking và blocking; việc tách đọc và ghi ra các server đơn lẻ phải đối mặt với hàng loạt vấn đề mới. Các vấn đề locking và blocking không mất đi đối với Master-Slave. Việc duy trì giải pháp này bao gồm phải xử lí vấn đề moving data từ server ghi sang các server đọc và hàng loạt vấn đề locking và blocking đi kèm.
Giải pháp này rất thích hợp với trường hợp tỉ lê đọc/ghi > 4 – ví dụ trang tin tức

Master-Master

Thay vì viết vào một máy chủ duy nhất, chúng ta thiết kế để ghi vào nhiều máy chủ. SQL Server hỗ trợ peer-to-peer replication, MySQL phân tải ghi thông qua driver, PostgreSQL có dự án Postgres-XC và các cơ sở dữ liệu khác có các giải pháp riêng của họ. Rõ ràng đây là một vấn đề mà mọi loại db đều đã có giải pháp đã tiếp cận riêng.
Một khó khăn lớn với trong việc peer-to-peer replication giữa các server, đó là xác định nơi để ghi dữ liệu. Thông thường điều này được thực hiện thông qua một cột đặc biệt(username, email, ..) trong bảng, 1 thuộc tính đặc biệt của 1 thực thể. Cột đặc biệt giúp chúng ta có thể quyết định được server nào là server sẽ nhận dữ liệu. Việc phân bổ dữ liệu ghi dựa trên thuật toán phân khối bảng chữ cái, với việc sử dụng ký tự tiền tố trong xâu gía trị. Giải pháp này có thể không đảm bảo được sự phân tải đồng đều ghi dữ liệu do mỗi loại ngôn ngữ khác nhau, việc phân bổ tỉ lệ dữ liệu theo tiền tố là khác nhau.
Một cách khác là phân vùng dữ liệu ngẫu nhiên để ghi. Chúng ta có thể sử dụng một thuật toán tạo số ngẫu nhiên làm đầu vào cho việc quyết định nơi mà dữ liệu  được ghi, nhưng các số ngẫu nhiên có thể không hoàn toàn ngẫu nhiên. Mặc dù vậy, một số chứng minh đã chỉ ra với việc sử dụng các thuật tóan băm đồng nhất(consistent hashing), dữ liệu có thể được phân bố đều tới các server được ghi.

Chúng ta chia tải ở đâu?

Việc triển khai kết hợp băm đồng nhất với peer-to-peer replication không dễ dàng. Quyết định định tuyến ghi phải được thực hiện ở đâu đó.
  • Trong ứng dụng Một lớp mã được viết để xác định cách ghi sẽ được định tuyến.
  • Sử dụng bộ định tuyến chuyên dụng Thay vì định tuyến ghi trong ứng dụng, dữ liệu ghi được gửi đến máy chủ thích hợp đóng vai trò bộ định tuyến, máy chủ định tuyến thực hiện điều hướng ghi dữ liệu thông qua thuật toán băm.
Cả hai cách tiếp cận đều có giá trị của chúng. Định tuyến trong ứng dụng có thể dễ dàng triển khai với một tệp DLL hoặc cấu hình tùy chỉnh. Việc thêm db ghi mới đồng nghĩa với nâng cấp bộ định tuyến, cập nhật phân vùng ghi phù hợp. Với bộ định tuyến chuyên dụng, việc định tuyến này trở nên trong suốt đối với bất kỳ ứng dụng ghi nào – không cần cập nhật mã nguồn để thêm mới các cơ sở dữ liệu. Các thay đổi cấu hình bộ định tuyến có thể phải thực hiện để đáp ứng yêu cầu mới, nhưng việc thay đổi được thực hiện nhanh chóng và độc lập với ứng dụng.

Kho chuyên dụng

Cũng giống như có những cửa hàng chuyên dụng trong thế giới thực, chúng ta có thể chia tách dữ liệu bằng việc tạo ra các kho dữ liệu cho mục đích chuyên biệt . Điều này thường được gọi là sharding, là một cách tiếp cận khác để phân tải. Thay vì đặt mục tiêu tất cả các cơ sở dữ liệu là bản sao của nhau, sharding hướng tới dữ liệu có thể được phân tách giữa các máy chủ với sharding key. Trong các ứng dụng  không có báo cáo tổng hợp trên nhiều phân hệ dữ liệu, sharding có thể là một hướng dễ dàng để mở rộng khả năng đọc và ghi. Các máy chủ bổ sung được thêm vào và dữ liệu mới có thể được ghi độc lập. Vấn đề phát sinh khi một phân hệ trở nên nặng nề và dữ liệu cần phải được tái cấu trúc.
Kho chuyên dụng thường chỉ là giải pháp tốt ở thời điểm nhất định, đối với các hệ thống ít có biến động về kiến trúc. Việc sử dụng giải pháp này cần có kế hoạch cẩn thận và chuyên gia có kinh nghiệm.

Vậy tách ở đâu?

Việc mở rộng không hề đơn giản, có nhiều yếu tố cần phải xem xét và lựa chọn giải pháp phù hợp với thiết kế kiến ​​trúc tổng thể ứng dụng.

Nhận xét

Bài đăng phổ biến từ blog này

Open Source CMS Ecommerce in .Net Core

What is an Application Specialist?

Sharding, Snowflake Instagram trong bài toán đối soát dữ liệu