Viblo Code
+4

Tản mạn về NoSQL

Thế giới đang thay đổi. Trước đây IBM, Oracle ra lệnh cho các quy tắc, các chuẩn công nghệ. Nhưng giờ đây những ông lớn như Google, Facebook, Amazon đã đưa các quy tắc, các công nghệ của họ tiến lên phía trước. Các công ty này tạo ra hàng terabytes dữ liệu và nhận hàng triệu request trong thời gian ngắn, và chúng vẫn đang phát triển mỗi ngày. Câu hỏi là tại sao họ có thể mở rộng quy mô và xử lý một khối lượng dữ liệu cao và nhiều request như vậy? Thực tế là chưa ai từng gặp vấn đề này trước đây kể cả IBM hay Oracle. Vì vậy họ phải tạo ra các giải pháp riêng của họ để có thể mở rộng quy mô và xử lý các vấn đề của họ.

Khi nói đến data persistence, các công ty đã làm:

  • Facebook tạo ra Cassandra
  • Google tạo ra Bigtable
  • Amazon tạo ra DynamoDB

Data persistance đề cập đến khả năng giữ dữ liệu được lưu trữ và sãn dùng cho truy xuất và quan trọng nhất là dữ liệu không bị bay hơi - bị mất 😄
Ngày nay, mọi ứng dụng "new-generation" (thế hệ mới) phải được thiết kế để phát triến trên những:

  • Điện toán đám mây (Cloud computing)
  • Big data / analytíc
  • Mobile
  • Mạng xã hội (Social networking)

Một vài năm trước đây, các lựa chọn khi phát triển ứng dụng chỉ là về ngôn ngữ lập trình và các loại CSDL quan hệ sẽ dùng. Nhưng ngày nay, các ứng dụng sử dụng data persistence là hoàn toàn quan trọng.

Có nhiều trường hợp trong đó các ứng dụng hiện cầ phải tuân thủ ACID properties, và do đó một CSDL như MySQL là cần thiết. Trên thực tế, việc sử dụng công nghệ NoSQL không có nghĩa là ta không còn cần CSDL quan hệ. Phần lớn các CSDL NoSQL được thiết kế với khả năng mở rộng theo chiều ngang.

Điều quan trọng cần lưu ý là trong kỷ nguyên 'Polyglot persítence2', về cơ bản điều này có nghĩa là ta nên áp dụng công nghệ thích hợp cho từng kịch bản.

Cũng tiện nói luôn, khả năng mở rộng theo chiều ngang là khi ta thêm các node vào cụm máy xử lý (cluster of machines). Khả năng mở rộng theo chiều dọc là khi tăng sức mạnh phần cứng của máy xử lý.

Thiết kế CSDL NoSQL dựa trên các hệ thống phân tán. Hiểu đơn giản là chúng được thiết kế để hoạt động như một cụm, nghĩa là một tập các node (machines), cái mà được dùng để kết nối và giao tiếp qua mạng để giải quyết vấn đề cụ thể (trường hợp này là vấn đề về dữ liệu).

Về cơ bản, CSDL NoSQL được phân thành 4 loại:

  • Key - value : Lưu trữ các giá trị thông qua khóa ( ex, Redis, Memcached, Elasticsearch)
  • Document: Lưu trữ toàn bộ tài liệu (ex, MongoDB, CouchDB, Riak)
  • Column family: Lưu trữ dữ liệu dưới dạng các cột thay vì các hàng; được thiết kế cho khối lượng dữ liệu lớn, hiệu suất đọc và ghi (ex, Cassandra, HBase)
  • Graph: Lưu trữ thông tin về mạng (ex, Neo4J, HyperGraphDB)

Một đặc điểm quan trọng nữa về CSDL NoSQL là chúng được lược giản, tinh gọn. Không có một lược đồ cứng nhắc như CSDL quan hệ.

Modeling in NoSQL

Khi sử dụng NoSQL, ta nên nghĩ khác đi khi nói đến mô hình hóa, thực thể hóa. Sẽ không có chuẩn hóa gì ở đây như csdl quan hệ vì ta đang quan tâm đến hiệu suất (tránh sử dụng các phép join). Hãy nhớ rằng, storage is cheap compared to CPU power and memory. Khi mô hình hóa trong NoSQL, ta cần suy nghĩ chính xác dữ liệu nào ta muốn truy xuất và lập mô hình "storage unit" (đơn vị lưu trữ) để truy xuất dữ liệu đó.

Ví dụ, giả sử ta cần truy xuất thư cho người dùng trong một phòng chat. Nếu sử dụng csdl quan hệ, ta sẽ cần một bảng 'user', một bảng 'chat_room', một bảng 'message', và các khóa ngoại giữa các bảng. Trong Cassandra khóa ngoại không tồn tại. Vì vậy ta sẽ suy nghĩ khác đi. Trong Cassandra, ta sẽ tạo ra một 'column family' (tương tự như một bảng trong csdl quan hệ) và lưu mọi thông tin ở đó với Id phòng chat, thông tin người dùng và tin nhắn. Nhắc lại một lần nữa rằng, sẽ không có chuẩn hóa ở đây.

Cassandra Overview

Cassandra được sử dụng ở Apple. Cụm này (this cluster) có hơn 75000 node và lưu trữ hơn 10PG dữ liệu. Lớn thứ hai là Netflix với hơn 2500 node và lưu trữ hơn 420TB dữ liệu và hơn 1 nghìn tỷ request mỗi ngày. Những con số ấn tượng.

Cassandra được dựa trên Bigtable của Google và DynamoDB của Amazon và được chủ yếu tạo ra bởi Facebook. Cassandra là csdl NoSQL thuộc loại 'column family'. Nó có khả năng đọc, ghi trên giây và khả năng mở rộng tuyến tính khi thêm các node vào vào một Cassandra cluster. Cassandra cũng cung cấp khả năng sao chép tự động đáng tin cậy tại các trung tâm phân tán dữ liệu theo địa lý.

Cassandra là hệ thống phân tán theo kiến trúc peer-to-peer. Nó sử dụng giao thức lan truyền (gossip protocol) để thực hiện giao tiếp nội bộ. Mỗi node có thể xử lý cả đọc và viết.
Cassandra là một lựa chọn tuyệt vời khi cần xử lý dữ liệu mà dữ liệu đó lớn dần theo thời gian, điều này phổ biến trong Internet Of Things (nhật ký số liệu sẽ lớn dần lên, ..) và vấn đề nhất quán không phải là tối quan trọng. Tính nhất quán của việc đọc dữ liệu (read consistency) là khi mỗi node trả về cùng một kết quả cho cùng một truy vấn tại một thời gian nhất định. Nhưng cần nhớ rằng một hệ thống phân tán chạy trên một mạng có độ trễ, vì vậy việc ghi dữ liệu vào một node cụ thể, và việc sao chép sẽ bắt đầu diễn ra, sau đó mất vài mili giây để đồng bộ dữ liệu trên các node khác. Trong những mili giây này, nếu một request tới các node khác, thì chúng sẽ trả về dữ liệu cũ. Mức độ nhất quán cho cả việc đọc và viết là hoàn toàn có thể điều chỉnh được trong Cassandra.

Redis Overview

Redis là một csdl NoSQL cực kỳ nhanh trong họ key-value. Nghĩa là ta có thể lưu trữ một giá trị và liên kết nó với một khóa duy nhất.

Redis vs. Memcached

Giả sử trong trang web của ta có những thành phần ít khi thay đổi, ví dụ như trong ứng dụng chat thì danh sách các phòng chat sẽ là thành phần ít thay đổi. Ứng dụng chat là một trang có lượng truy cập cao. Nếu dùng csdl quan hệ để lưu trữ danh mục phòng chat và load nó ra để hiện thị, thì đây quả là một hoạt động tốn kém tài nguyên và do ta đang xử lý trang web có lượng truy cập cao thì rất có thể sẽ dẫn tới vấn đề về hiệu suất nữa. Trong trường hợp này ta có thể sử dụng Redis làm máy chủ bộ nhớ cache để khi máy khách truy cập trang, dữ liệu sẽ được nạp tìm từ Redis một cách nhanh chóng vì chúng lưu trữ trong RAM, tránh truy cập vào đĩa. OK, quá NGON đúng không nhỉ? 😄

Memcached cũng là một lựa chọn tốt ở đây. Nhưng về cơ bản Memcached chỉ được sử dụng cho bộ nhớ đệm, trong khi Redis làm được nhiều điều hơn nữa. Memcached chỉ hỗ trợ strings, integers trong cấu trúc lưu trữ data, trong khi Redis hỗ trợ nhiều loại dữ liệu phức tạp như strings, hashes, lists, sets, sorted sets .... Ngoài ra, Redis có thể lưu dữ liệu vào đĩa để đảm bảo độ bền, còn Memcached thì không.

Redis Use Cases

Do cấu trúc dữ liệu phong phú của nó, Redis có thể được sử dụng cho nhiều trường hợp khác nhau:

  • Caching
  • Bộ đếm số lượt truy cập trang
  • Kiểu lưu trữ hàng đợi cần hiệu suất cao
  • Biên soạn số liệu thống kê
  • Lưu trữ Hypertext Transfer Protocol (HTTP) sessions

... và rất nhiều trường hợp khác.

Giả sử trong ứng dụng chat, với tính năng "add friend" ta sẽ lưu trữ danh sách bạn bè trong một set. Sau đó ta có thể có một set khác chứa tất cả người dùng đang online. Và bây giờ ta có thể trích xuất dữ liệu là giao của 2 set này sẽ ra được danh sách bạn bè đang online trong thời gian độ phức tạp là O(m* n). Quả là Amazing! 😮

Kiến trúc phân tán của Redis dựa trên mô hình master-slave.

Không giống như Cassandra, không thể điều chỉnh mức độ nhất quá. Đó là vì khi có một request ghi dữ liệu tới Redis, node master sẽ ghi dữ liệu lên chính nó trước, và "ngay lập tức" trả thông báo thành công cho máy khách. Sau đó sao chép vào các node slave mới thực hiện (quá trình này bất đồng bộ). Điều gì sẽ xảy ra nếu node master bị treo trước khi sao chép dữ liệu đến các node slave. Khi đó, khách hàng đã nhận được thông báo thành công nhưng thực chất là dữ liệu đã mất.


All Rights Reserved