APACHE CASSANDRA: PHÂN BỐ DỮ LIỆU VÀ TẠO BẢN SAO DỮ LIỆU TRONG CLUSTER - PARTITIONER VÀ REPLICATION.

Thông thường, các cơ sở dữ liệu loại NoSQL có khả năng tự động phân bố dự liệu giữa các node trong cluster (data distribution) và tạo bản sao dữ liệu (data replication). Cassandra cũng thừa hưởng những tính năng này của NoSQL. Trong bài viết này chúng ta sẽ tìm hiểu về hai tính năng trên của Cassandra.

Data store

Trước hết, để có thể hiểu được cách phân bố và tạo bản sao dữ liệu trong cluster, chúng ta đi sẽ tìm hiểu về vấn đề dữ liệu được Cassandra lưu trữ như thế nào.Đối với những ai chưa từng sử dụng Cassandra, cách dữ liệu được phân chia có thể sẽ gây ra một số khó khăn ban đầu trong việc làm quen. Mô hình dữ liệu của Cassandra có thể được diễn giải như sau.

  1. Cassandra dựa trên mô hình key – value.

Dữ liệu bao gồm các column family. Một column family là một tập hợp cả các cặp key – value. Nếu so sánh với cơ sở dữ liệu liên kết, column family giống với table và cặp key – value giống với các record trong table.

  1. Cassandra mở rộng mô hình key – value với hai mức độ phân cấp dữ liệu.
  • Ở mức độ thứ nhất, giá trị của một record là một chuỗi các cặp key – value. Các cặp key – value được gọi là các column trong đó key chính là tên của column. Nói cách khác, record ở một column family có một key và bao gồm các column. Việc phân cấp ở mức độ này là bắt buộc, một record phải bao gồm ít nhất một column.

  • Ở mức độ thứ hai, là mức độ tuỳ chọn, value của một cặp key – value cũng có thể là một chuỗi của các cặp key – value. Khi dữ liệu được thể hiện theo mức độ này, những cặp key – value bao ngoài được gọi là các supercolumn với key là tên của super column và các cặp key – value bên trong được gọi là các column.

  1. Tên của các column và super column có thể được sử dụng theo hai cách: như tên hoặc value ( thường là các value trích dẫn)
  • Thứ nhất, các tên có thể đóng vai trò là tên của các attribute. Ví dụ, tên của một column trong một record của User có thể là Email. Đó là cách chúng ta nghĩ về column trong cơ sở dữ liệu liên kết.

  • Thứ hai, các tên có thể được sử dụng để lưu trữ các giá trị. Ví dụ, các tên column trong một record biểu hiện Blog có thể là trường nhận dạng của các post trong blog này và value tương ứng của nó chính là các post. Bạn thực sự có thể sử dụng tên của colum (hoặc super column) để lưu một vài giá trị vì trên lí thuyết không có giới hạn về số lượng các column (hoặc super column) cho mỗi record và tên chính là các byte array nên bạn có thể lưu mọi giá trị trong nó.

  1. Column và super colum được lưu trữ theo thư tự của các tên.

Bạn có thể chỉ định các sắp xếp bằng việc định nghĩa lại các Cassandra xử lý các tên của columns (super column) (nhớ rằng tên chỉ là một byte array). Tên có thể có kiểu Bytes, Long, Ascii, UTF8, Lexical UUID, Time UUID.

Chú ý: Trong trường hợp có super column thì các column bên trong nó sẽ không được sắp xếp theo tên. Giá trị của column có thể là rỗng nếu không cần thiết.

Phân bố dữ liệu (Data distribution)

Việc phân bố dữ liệu trong các node của cluster giúp tăng tốc độ truy nhập (đọc và ghi) dữ liệu.

Các record trong một column family được lưu trữ phân bố tại các node trong cluster. Việc node nào được sử dụng để lưu trữ một record được quyết định bằng cách tham chiếu khoá của nó tới token value và việc này được quyết định bởi partitioner.

Cassandra Partitioner

  • RandomPartitioner (Phân chia ngẫu nhiên): Lấy một giá trị hash MD5 của một key và sử dụng nó như token value. Nó sẽ được phân bố các record một cách đồng đều trên khắp cluster.

  • OrderPreservingPartitioner: Sử dụng key (một byte array) như một token value. Điều này tốt cho các query trong khoảng của các value. Tuy nhiên các token của server có thể cần được điều chỉnh để phân phối các vùng có nhiều dữ liệu (data hotspot) khắp các node. Loại partitioner này chỉ hỗ trợ các key với nội dung là UTF-8.

  • ByteOrderedPartitioner: Giống với OrderPreservingPartitioner nhưng key không nhất thiết phải chứa nội dung kiểu UTF-8.

  • CollatingOrderPreservingPartitioner: Giống với OrderPreservingPartitioner nhưng so sánh các key sử dụng luật EN,US.

  • Chú ý: Đối với query với khoảng dữ liệu (range query): sử dụng OrderPreservingPartitioner như partitioner cho column family.

    Lập trình viên có thể sử dụng các kiểu partitioner khác nhau cho mỗi column family để tham chiếu theo cách khác nhau.

Distributed Hash Table Algorithm (DHT)

Cassandra sử dụng một thuật toán Distributed Hash Table (DHT) trong việc quyết định dữ liệu nào với token value cho trước sẽ được lưu trữ ở node nào. Mỗi server Cassandra (node) được thiết lập với một token với giá trị Initial_token của nó được đặt bằng:

i*(2**127)/number_of_nodes with i starts from 0 to (number_of_nodes - 1)

Giá trị 2 mũ 127 biểu thị namespace 128bit DHT được sử dụng bởi Cassandra.

Các token value của server được sắp xếp và đặt xung quanh để tạo thành một ring. Mỗi server có trách nhiên lưu trữ các record với token value trong khoảng từ token value của server trước tới token value của server đó. Ví dụ, server thứ hai của ring sẽ có trách nhiệm đối với các record có token value từ 0 cho tới (2**127)/số_lượng_node.

Ví dụ với một cluster có 4 node.

Key Map to Server 0 Init_token Range responsible
0 0 2**127/4*3 .. 0
“key nào đó” 45678845 1 2**127/4 0 .. 2**127/4
2 2**127/4*2 2127/4 .. 2127/4*2
3 2**127/4*3

Load balancing

Nếu bạn thêm một số node vào cluster, việc phân phối dữ liệu trong ring của bạn sẽ bị mất cân bằng và cách để lấy lại sự cân bằng là tính toán lại có token value cho mỗi node và gán các token value đó một cách thủ công.

Cassandra Replication

  1. Tính năng tạo bản sao dữ liệu của cluster cho phép truy nhập dữ liệu của cluster kể cả khi có một node nào đó bị hỏng hóc (no single point of value).
  2. Cassandra Replication được điều chỉnh bằng replication_factor. Giá trị mặc định 1 có ý nghĩa rằng dữ liệu được ghi ở chỉ một node trong ring ( không có dữ liệu trùng lặp ).
  3. Replication factor được định nghĩa khi định nghĩa Keyspace (sau này có thể thay đổi).
create keyspace Keyspace1
with replication_factor = 1
and placement_strategy = 'org.apache.cassandra.locator.SimpleStrategy';
  • Replication factor phản ánh số lượng các replica
  • Giá trị bằng 1 có ý nghĩa một record chỉ được lưu trữ ở duy nhất một node (không có dư liệu trùng lặp)
  • Giá trị lớn hơn 1 cung cấp dữ liệu dư thừa để đề phòng trừ hợp một node gặp vấn đề
  • Giá trị bằng 3 có nghĩa mỗi record được lưu trữ trên 3 node khác nhau
  • Giá trị bằng 3 có nghĩa mỗi node sẽ xử lý như một replica cho 3 khoảng khác nhau của token
  1. Thay đổi Cassandra Replication Factor cho cluster:

Với mỗi server trong cluster

  • Thay đổi thiết lập thành replication_factor mong muốn
  • Khởi động lại Cassandra
  • Chạy nodetool repair cho từng keyspace riêng rẽ
Nodetool có thể hơi khó kiểm soát. Nên chờ cho một node thực hiện xong trước khi bắt đầu chạy nodetool với node khác.

Cassandra Placement Strategies

Replica placement strategy quyết định những node nào khác ngoài node được chọn bởi token sẽ được lựa chọn để làm replica.

Các loại Replica Placement Strategies

  1. SimpleStrategy (mặc định): trả về các node liên tiếp cạnh nhau ở trong ring.
  2. NetworkTopologyStrategy: Thiết lập số lượng các replica ở mỗi trung tâm dữ liệu (data center) như được xác định ở strategy_options
  • Chiến lược sắp đặt này dung cho cluster chạy với nhiều data center
  • Cập nhật replication factor sử dụng cho hai data center khác nhau là DC1 và DC2 theo 2 trường hợp.
    1. Data center thứ nhất dùng cho load balance theo vị trí địa lý
    2. Data center thứ hai chỉ dung cho việc phục hồi trong trường hợp mất mát dữ liệu
  1. OldNetworkTopologyStrategy: Đặt một replica trong một data center trong khi những replica còn lại đặt trong các rack khác nhau ở data center hiện tại.