Thứ năm, 07/02/2019 | 00:00 GMT+7

Tìm hiểu database phân đoạn - Database Sharding

Bất kỳ ứng dụng hoặc trang web nào nhận thấy sự tăng trưởng đáng kể cuối cùng cần phải mở rộng quy mô để đáp ứng sự gia tăng lưu lượng truy cập. Đối với các ứng dụng và trang web theo hướng dữ liệu, điều quan trọng là việc mở rộng quy mô được thực hiện theo cách đảm bảo tính bảo mật và tính toàn vẹn của dữ liệu của chúng. Có thể khó dự đoán mức độ phổ biến của một trang web hoặc ứng dụng hoặc nó sẽ duy trì sự phổ biến đó trong bao lâu, đó là lý do tại sao một số tổ chức chọn kiến trúc database cho phép họ mở rộng database một cách linh hoạt.

Trong bài viết khái niệm này, ta sẽ thảo luận về một kiến trúc database như vậy: cơ sở dữ liệu phân đoạn . Sharding đã nhận được rất nhiều sự chú ý trong những năm gần đây, nhưng nhiều người không hiểu rõ nó là gì hoặc các kịch bản mà nó có thể có ý nghĩa khi phân chia database . Ta sẽ xem xét sharding là gì, một số lợi ích và nhược điểm chính của nó cũng như một vài phương pháp sharding phổ biến.

Sharding là gì?

Sharding là một mẫu kiến trúc database liên quan đến phân vùng ngang - thực hành tách các hàng của một bảng thành nhiều bảng khác nhau, được gọi là phân vùng. Mỗi phân vùng có cùng một schemas và các cột, nhưng cũng có các hàng hoàn toàn khác nhau. Tương tự như vậy, dữ liệu được giữ trong mỗi phân vùng là duy nhất và độc lập với dữ liệu được giữ trong các phân vùng khác.

Có thể hữu ích khi nghĩ về phân vùng theo chiều ngang về cách nó liên quan đến phân vùng dọc . Trong một bảng được phân vùng theo chiều dọc, toàn bộ các cột được tách ra và đưa vào các bảng mới, riêng biệt. Dữ liệu được giữ trong một vertical partitioning độc lập với dữ liệu trong tất cả các phân vùng khác và mỗi phân containers cả các hàng và cột riêng biệt. Sơ đồ sau minh họa cách một bảng có thể được phân vùng theo cả chiều ngang và chiều dọc:

Các bảng ví dụ hiển thị horizontal partitioning  và dọc

Sharding liên quan đến việc chia nhỏ dữ liệu của một người thành hai hoặc nhiều phần nhỏ hơn, được gọi là phân đoạn logic . Sau đó, các logical shards được phân phối trên các node database riêng biệt, được gọi là các physical shards , có thể chứa nhiều logical shards . Mặc dù vậy, dữ liệu được giữ trong tất cả các phân đoạn đại diện chung cho toàn bộ tập dữ liệu logic.

Các phân đoạn database thể hiện một kiến trúc không chia sẻ . Điều này nghĩa là các phân đoạn là tự trị; chúng không chia sẻ bất kỳ dữ liệu hoặc tài nguyên máy tính nào giống nhau. Tuy nhiên, trong một số trường hợp, có thể có ý nghĩa khi sao chép các bảng nhất định thành từng phân đoạn để dùng làm bảng tham chiếu. Ví dụ: giả sử có một database cho một ứng dụng phụ thuộc vào tỷ lệ chuyển đổi cố định cho các phép đo trọng lượng. Bằng cách sao chép một bảng chứa dữ liệu tỷ lệ chuyển đổi cần thiết vào từng phân đoạn, sẽ giúp đảm bảo tất cả dữ liệu cần thiết cho các truy vấn đều được lưu giữ trong mọi phân đoạn.

Thông thường, sharding được thực hiện ở cấp ứng dụng, nghĩa là ứng dụng bao gồm mã xác định phân đoạn nào để truyền đọc và ghi. Tuy nhiên, một số hệ thống quản lý database có tích hợp khả năng sharding, cho phép bạn triển khai sharding trực tiếp ở cấp database .

Với tổng quan chung về sharding, ta hãy xem xét một số mặt tích cực và tiêu cực liên quan đến kiến trúc database này.

Lợi ích của Sharding

Điểm hấp dẫn chính của việc sharding database là nó có thể giúp tạo điều kiện cho việc mở rộng quy mô theo chiều ngang , còn gọi là mở rộng quy mô . Horizontal partitioning là việc thực hiện thêm nhiều máy hơn vào một ngăn xếp hiện có để phân tán tải và cho phép nhiều lưu lượng truy cập hơn và xử lý nhanh hơn. Điều này thường trái ngược với mở rộng theo chiều dọc , còn gọi là mở rộng quy mô , liên quan đến việc nâng cấp phần cứng của một server hiện có, thường bằng cách thêm nhiều RAM hoặc CPU.

Tương đối đơn giản để có một database quan hệ chạy trên một máy duy nhất và mở rộng quy mô nó khi cần thiết bằng cách nâng cấp tài nguyên máy tính của nó. Tuy nhiên, cuối cùng thì bất kỳ database không phân tán nào cũng sẽ bị giới hạn về dung lượng lưu trữ và sức mạnh tính toán, vì vậy việc tự do mở rộng quy mô theo chiều ngang sẽ giúp cài đặt của bạn linh hoạt hơn nhiều.

Một lý do khác tại sao một số người có thể chọn kiến trúc database phân đoạn là để tăng tốc thời gian phản hồi truy vấn. Khi bạn gửi một truy vấn trên một database chưa được phân đoạn, nó có thể phải tìm kiếm mọi hàng trong bảng mà bạn đang truy vấn trước khi có thể tìm thấy tập kết quả bạn đang tìm. Đối với một ứng dụng có database lớn, nguyên khối, các truy vấn có thể trở nên chậm chạp. Tuy nhiên, bằng cách chia nhỏ một bảng thành nhiều, các truy vấn phải đi qua ít hàng hơn và tập hợp kết quả của chúng được trả về nhanh hơn nhiều.

Sharding cũng có thể giúp ứng dụng trở nên tin cậy hơn bằng cách giảm thiểu tác động của sự cố mất điện. Nếu ứng dụng hoặc trang web dựa trên một database không được cứng, sự cố ngừng hoạt động có khả năng làm cho toàn bộ ứng dụng không khả dụng. Tuy nhiên, với database được phân đoạn, sự cố ngừng hoạt động có thể chỉ ảnh hưởng đến một phân đoạn duy nhất. Mặc dù điều này có thể làm cho một số phần của ứng dụng hoặc trang web không khả dụng cho một số user , tác động tổng thể vẫn sẽ ít hơn nếu toàn bộ database bị lỗi.

Mặt hạn chế của Sharding

Mặc dù việc phân bổ database có thể giúp mở rộng quy mô dễ dàng hơn và cải thiện hiệu suất, nhưng nó cũng có thể đặt ra một số hạn chế nhất định. Ở đây, ta sẽ thảo luận về một số điều này và lý do tại sao chúng có thể là lý do để tránh dùng sharding hoàn toàn.

Khó khăn đầu tiên mà mọi người gặp phải với sharding là sự phức tạp tuyệt đối của việc triển khai đúng kiến trúc database phân mảnh. Nếu thực hiện không chính xác, có một nguy cơ đáng kể là quá trình sharding có thể dẫn đến mất dữ liệu hoặc bảng bị hỏng. Tuy nhiên, ngay cả khi được thực hiện đúng cách, sharding có thể có tác động lớn đến quy trình làm việc của group bạn. Thay vì truy cập và quản lý dữ liệu của một người từ một điểm nhập duy nhất, user phải quản lý dữ liệu trên nhiều vị trí phân đoạn, điều này có thể gây gián đoạn cho một số group .

Một vấn đề mà user đôi khi gặp phải sau khi phân chia database là các phân đoạn cuối cùng trở nên mất cân bằng. Ví dụ: giả sử bạn có một database với hai phân đoạn riêng biệt, một dành cho những khách hàng có họ bắt đầu bằng chữ A đến M và một dành cho những người có tên bắt đầu bằng các chữ cái từ N đến Z. Tuy nhiên, ứng dụng của bạn phục vụ một lượng lớn của những người có họ bắt đầu bằng chữ G. Theo đó, phân đoạn AM dần dần tích lũy nhiều dữ liệu hơn phân đoạn NZ, khiến ứng dụng chạy chậm và ngừng hoạt động đối với một phần đáng kể user của bạn. Phân đoạn AM đã trở thành cái được gọi là điểm phát sóng database .Trong trường hợp này, bất kỳ lợi ích nào của việc sharding database sẽ bị hủy bỏ bởi sự chậm chạp và sự cố. Database có thể cần được sửa chữa và nâng cấp để cho phép phân phối dữ liệu đồng đều hơn.

Một nhược điểm lớn khác là một khi database đã bị chia nhỏ, có thể rất khó để đưa database đó trở về kiến trúc không cứng của nó. Bất kỳ bản backup nào của database được thực hiện trước khi nó bị chia nhỏ sẽ không bao gồm dữ liệu được ghi kể từ khi phân vùng. Do đó, việc xây dựng lại kiến trúc không cứng ban đầu sẽ yêu cầu hợp nhất dữ liệu được phân vùng mới với các bản backup cũ hoặc cách khác, chuyển đổi DB được phân vùng trở lại thành một DB duy nhất, cả hai đều sẽ tốn kém và mất thời gian.

Một bất lợi cuối cùng cần xem xét là sharding không được hỗ trợ bởi mọi công cụ database . Ví dụ: PostgreSQL không bao gồm tính năng tự động sharding , mặc dù có thể phân mảnh database PostgreSQL theo cách thủ công. Có một số nhánh của Postgres bao gồm tính năng tự động phân bổ, nhưng chúng thường đi sau bản phát hành PostgreSQL mới nhất và thiếu một số tính năng khác. Một số công nghệ database chuyên biệt - như MySQL Cluster hoặc một số sản phẩm dịch vụ database như MongoDB Atlas - có bao gồm tính năng tự động mài sắc nét như một tính năng, nhưng các version vani của các hệ thống quản lý database này thì không. Do đó, sharding thường đòi hỏi một cách tiếp cận "tự làm". Điều này nghĩa là tài liệu về sharding hoặc mẹo khắc phục sự cố thường rất khó tìm.

Tất nhiên, đây chỉ là một số vấn đề chung cần xem xét trước khi sharding. Có thể có nhiều nhược điểm tiềm ẩn hơn đối với việc sharding database tùy thuộc vào trường hợp sử dụng của nó.

Bây giờ ta đã đề cập đến một số nhược điểm và lợi ích của sharding, ta sẽ xem xét một vài kiến trúc khác nhau cho database phân đoạn.

Kiến trúc Sharding

Khi bạn đã quyết định chia nhỏ database của bạn , điều tiếp theo bạn cần tìm hiểu là bạn sẽ làm như thế nào. Khi chạy truy vấn hoặc phân phối dữ liệu đến các bảng hoặc database được phân đoạn, điều quan trọng là nó phải đến đúng phân đoạn. Nếu không, nó có thể dẫn đến mất dữ liệu hoặc truy vấn chậm một cách đáng tiếc. Trong phần này, ta sẽ xem xét một số kiến trúc sharding phổ biến, mỗi kiến trúc sử dụng một quy trình hơi khác nhau để phân phối dữ liệu trên các phân đoạn.

Mài dựa trên chính

Sharding dựa trên khóa , còn gọi là sharding dựa trên băm , liên quan đến việc sử dụng một giá trị được lấy từ dữ liệu mới được ghi - chẳng hạn như số ID của khách hàng, địa chỉ IP của ứng dụng client , mã ZIP, v.v. - và cắm nó vào hàm băm để xác định dữ liệu sẽ chuyển đến phân đoạn nào. Hàm băm là một hàm nhận làm đầu vào một phần dữ liệu (ví dụ: email của khách hàng) và xuất ra một giá trị rời rạc, được gọi là giá trị băm . Trong trường hợp sharding, giá trị băm là một ID phân đoạn được sử dụng để xác định phân đoạn nào mà dữ liệu đến sẽ được lưu trữ. Nhìn chung, quá trình trông giống như sau:

Sơ đồ ví dụ về sharding dựa trên chính

Để đảm bảo các mục nhập được đặt đúng phân đoạn và theo cách nhất quán, các giá trị được nhập vào hàm băm phải đến từ cùng một cột.Cột này được gọi là khóa phân đoạn . Nói một cách dễ hiểu, khóa phân đoạn tương tự như khóa chính ở chỗ cả hai đều là các cột được sử dụng để cài đặt một mã định danh duy nhất cho các hàng riêng lẻ. Nói chung, khóa phân đoạn phải tĩnh, nghĩa là nó không được chứa các giá trị có thể thay đổi theo thời gian. Nếu không, nó sẽ làm tăng dung lượng công việc dành cho các hoạt động cập nhật và có thể làm chậm hiệu suất.

Mặc dù sharding dựa trên khóa là một kiến trúc sharding khá phổ biến, nhưng nó có thể khiến mọi thứ trở nên phức tạp khi cố gắng thêm hoặc xóa động các server bổ sung vào database . Khi bạn thêm server , mỗi server cần một giá trị băm tương ứng và nhiều mục nhập hiện có của bạn, nếu không phải tất cả chúng, cần được ánh xạ lại thành giá trị băm mới, chính xác của chúng và sau đó được chuyển sang server thích hợp. Khi bạn bắt đầu cân bằng lại dữ liệu, cả hàm băm mới và cũ sẽ không hợp lệ. Do đó, server của bạn sẽ không thể ghi bất kỳ dữ liệu mới nào trong quá trình di chuyển và ứng dụng của bạn có thể phải chịu thời gian chết.

Điểm hấp dẫn chính của chiến lược này là nó được dùng để phân phối dữ liệu một cách đồng đều nhằm ngăn chặn các điểm nóng. Ngoài ra, bởi vì nó phân phối dữ liệu theo thuật toán, không cần phải duy trì bản đồ về vị trí của tất cả dữ liệu, cũng như cần thiết với các chiến lược khác như phân bổ theo phạm vi hoặc dựa trên folder .

Sharding dựa trên phạm vi

Sharding dựa trên phạm vi liên quan đến sharding dữ liệu dựa trên phạm vi của một giá trị nhất định. Để minh họa, giả sử bạn có một database lưu trữ thông tin về tất cả các sản phẩm trong danh mục của nhà bán lẻ. Bạn có thể tạo một vài phân đoạn khác nhau và chia nhỏ thông tin của từng sản phẩm dựa trên phạm vi giá của chúng, như sau:

Sơ đồ ví dụ về sharding dựa trên phạm vi

Lợi ích chính của sharding dựa trên phạm vi là nó tương đối đơn giản để thực hiện. Mỗi phân đoạn chứa một tập hợp dữ liệu khác nhau nhưng chúng đều có một schemas giống hệt nhau, cũng như database ban đầu. Mã ứng dụng chỉ đọc dữ liệu thuộc phạm vi nào và ghi dữ liệu đó vào phân đoạn tương ứng.

Mặt khác, phân bổ theo phạm vi không bảo vệ dữ liệu khỏi bị phân phối không đồng đều, dẫn đến các điểm nóng database nói trên. Nhìn vào sơ đồ ví dụ, ngay cả khi mỗi phân đoạn chứa một lượng dữ liệu bằng nhau, tỷ lệ cược là các sản phẩm cụ thể sẽ nhận được nhiều sự chú ý hơn các sản phẩm khác. Đến lượt chúng, các đoạn tương ứng của chúng sẽ nhận được số lần đọc không tương xứng.

Sharding dựa trên folder

Để triển khai sharding dựa trên folder , người ta phải tạo và duy trì một bảng tra cứu sử dụng khóa phân đoạn để theo dõi phân đoạn nào chứa dữ liệu nào. Tóm lại, bảng tra cứu là một bảng chứa một tập hợp thông tin tĩnh về nơi có thể tìm thấy dữ liệu cụ thể. Sơ đồ sau đây cho thấy một ví dụ đơn giản về sharding dựa trên folder :

Sơ đồ ví dụ về sharding dựa trên folder

Ở đây, cột Khu vực giao hàng được xác định là một khóa phân đoạn. Dữ liệu từ khóa phân đoạn được ghi vào bảng tra cứu cùng với bất kỳ phân đoạn nào mà mỗi hàng tương ứng sẽ được ghi vào.Điều này tương tự như phân đoạn dựa trên phạm vi, nhưng thay vì xác định dữ liệu của khóa phân đoạn rơi vào phạm vi nào, mỗi khóa được gắn với phân đoạn cụ thể của riêng nó. Tính năng phân đoạn dựa trên folder là một lựa chọn tốt hơn tính năng phân đoạn dựa trên phạm vi trong trường hợp khóa phân đoạn có số lượng ít và không có ý nghĩa khi phân đoạn lưu trữ một loạt các khóa. Lưu ý nó cũng khác biệt với tính năng mài sắc nét dựa trên khóa ở chỗ nó không xử lý khóa phân đoạn thông qua một hàm băm; nó chỉ kiểm tra khóa dựa trên bảng tra cứu để xem dữ liệu cần được ghi vào đâu.

Điểm hấp dẫn chính của sharding dựa trên folder là tính linh hoạt của nó. Các kiến trúc phân bổ theo phạm vi giới hạn bạn chỉ định các phạm vi giá trị, trong khi các kiến trúc dựa trên khóa giới hạn bạn sử dụng một hàm băm cố định, như đã đề cập trước đây, có thể cực kỳ khó thay đổi sau này. Mặt khác, sharding dựa trên folder cho phép bạn sử dụng bất kỳ hệ thống hoặc thuật toán nào bạn muốn để gán các mục nhập dữ liệu cho các phân đoạn và tương đối dễ dàng để thêm các phân đoạn động bằng cách sử dụng phương pháp này.

Mặc dù sharding dựa trên folder là phương pháp linh hoạt nhất trong số các phương pháp sharding được thảo luận ở đây, nhu cầu kết nối với bảng tra cứu trước mọi truy vấn hoặc ghi có thể có tác động bất lợi đến hiệu suất của ứng dụng. Hơn nữa, bảng tra cứu có thể trở thành một điểm lỗi duy nhất: nếu nó bị hỏng hoặc bị lỗi, nó có thể ảnh hưởng đến khả năng ghi dữ liệu mới hoặc truy cập dữ liệu hiện có của họ.

Tôi có nên Shard?

Việc có nên triển khai một kiến trúc database phân đoạn hay không hầu như luôn là một vấn đề tranh luận. Một số coi sharding là một kết quả không thể tránh khỏi đối với database đạt đến một kích thước nhất định, trong khi những người khác lại coi đó là một vấn đề đau đầu nên tránh trừ khi thực sự cần thiết, do sự phức tạp trong hoạt động mà sharding thêm vào.

Do sự phức tạp tăng thêm này, nên sharding thường chỉ được thực hiện khi xử lý lượng dữ liệu rất lớn. Dưới đây là một số tình huống phổ biến trong đó việc chia nhỏ database có thể có lợi:

  • Số lượng dữ liệu ứng dụng tăng lên vượt quá khả năng lưu trữ của một nút database duy nhất.
  • Dung lượng ghi hoặc đọc vào database vượt quá những gì mà một nút đơn hoặc các bản sao đọc của nó có thể xử lý, dẫn đến thời gian phản hồi hoặc thời gian chờ bị chậm lại.
  • Băng thông mạng mà ứng dụng yêu cầu lớn hơn băng thông có sẵn cho một nút database và bất kỳ bản sao đọc nào, dẫn đến thời gian phản hồi hoặc thời gian chờ bị chậm lại.

Trước khi sharding, bạn nên sử dụng hết các tùy chọn khác để tối ưu hóa database của bạn . Một số tối ưu hóa bạn có thể cần xem xét bao gồm:

  • Cài đặt database từ xa . Nếu bạn đang làm việc với một ứng dụng nguyên khối, trong đó tất cả các thành phần của nó nằm trên cùng một server , bạn có thể cải thiện hiệu suất database của bạn bằng cách chuyển nó sang máy của chính nó. Điều này không làm phức tạp thêm nhiều như sharding vì các bảng của database vẫn còn nguyên vẹn. Tuy nhiên, nó vẫn cho phép bạn mở rộng database của bạn theo chiều dọc ngoài phần còn lại của cơ sở hạ tầng.
  • Thực hiện bộ nhớ đệm . Nếu hiệu suất đọc của ứng dụng là nguyên nhân khiến bạn gặp rắc rối, thì bộ nhớ đệm là một chiến lược có thể giúp cải thiện nó.Bộ nhớ đệm bao gồm việc lưu trữ tạm thời dữ liệu đã được yêu cầu trong bộ nhớ, cho phép bạn truy cập dữ liệu đó nhanh hơn nhiều sau này.
  • Tạo một hoặc nhiều bản sao đã đọc . Một chiến lược khác có thể giúp cải thiện hiệu suất đọc, điều này liên quan đến việc sao chép dữ liệu từ một server database ( server chính ) sang một hoặc nhiều server phụ . Sau đó, mọi bản ghi mới sẽ được chuyển đến bản chính trước khi được sao chép sang các bản thứ hai, trong khi các lần đọc được thực hiện riêng cho các server thứ cấp. Việc phân phối các lần đọc và ghi như thế này giúp cho bất kỳ máy nào không phải chịu quá nhiều tải, giúp tránh bị chậm và treo máy. Lưu ý việc tạo bản sao đọc liên quan đến nhiều tài nguyên máy tính hơn và do đó tốn nhiều tiền hơn, đây có thể là một hạn chế đáng kể đối với một số người.
  • Nâng cấp lên server lớn hơn . Trong hầu hết các trường hợp, việc mở rộng server database của một người thành một máy có nhiều tài nguyên hơn đòi hỏi ít nỗ lực hơn so với sharding. Giống như việc tạo bản sao đọc, một server được nâng cấp với nhiều tài nguyên hơn có thể sẽ tốn nhiều tiền hơn. Do đó, bạn chỉ nên thực hiện việc thay đổi kích thước nếu nó thực sự trở thành lựa chọn tốt nhất của bạn.

Lưu ý nếu ứng dụng hoặc trang web phát triển vượt quá một thời điểm nhất định, không có chiến lược nào trong số này sẽ đủ để tự cải thiện hiệu suất. Trong những trường hợp như vậy, sharding có thể là lựa chọn tốt nhất cho bạn.

Kết luận

Sharding có thể là một giải pháp tuyệt vời cho những người muốn mở rộng database của họ theo chiều ngang. Tuy nhiên, nó cũng thêm nhiều phức tạp và tạo ra nhiều điểm lỗi tiềm ẩn cho ứng dụng của bạn. Sharding có thể cần thiết đối với một số người, nhưng thời gian và nguồn lực cần thiết để tạo và duy trì một kiến trúc phân mảnh có thể lớn hơn lợi ích cho những người khác.

Bằng cách đọc bài viết khái niệm này, bạn sẽ hiểu rõ hơn về những ưu và nhược điểm của sharding. Về sau, bạn có thể sử dụng thông tin chi tiết này để đưa ra quyết định sáng suốt hơn về việc kiến trúc database phân đoạn có phù hợp với ứng dụng của bạn hay không.


Tags:

Các tin liên quan

Cách thiết lập database từ xa để tối ưu hóa hiệu suất trang web với MySQL trên Ubuntu 18.04
2018-11-28
Cách quản lý database SQL
2018-09-26
Cách cải thiện tìm kiếm database với tìm kiếm toàn văn bản (Full Text Search) trong MySQL 5.6 trên Ubuntu 16.04
2017-10-30
Cách thiết lập database đồ thị Titan với Cassandra và ElasticSearch trên Ubuntu 16.04
2017-06-27
Cách thiết lập database từ xa để tối ưu hóa hiệu suất trang web với MySQL trên Ubuntu 16.04
2017-06-05
Cách gỡ lỗi WordPress "Lỗi thiết lập kết nối database"
2017-04-21
Cách bảo mật database OrientDB của bạn trên Ubuntu 16.04
2017-03-24
Cách backup, khôi phục và di chuyển database MongoDB trên Ubuntu 14.04
2016-04-15
Cách nhập và xuất database MongoDB trên Ubuntu 14.04
2016-04-15
Cách chạy database cụm đa node với Cassandra trên Ubuntu 14.04
2016-03-31