Chương 4. QUẢN LÝ VÀ TRUY XUẤT DỮ LIỆU
4.1. Hiểu về ghi trong Cassandra
Cassandra được tối ưu để việc ghi dữ liệu luôn có sự sẵn sàng cao và nhanh chóng. RDBMS có cấu trúc dữ sao cho dữ liệu dư thừa là ít nhất. Nhiều mẩu thông tin cần cho câu truy vấn được lưu trữ ở nhiều bảng có quan hệ với nhau. Bởi cái cách lưu trữ dữ liệu như thế nên việc ghi dữ liệu tốn nhiều chi phí. Server database phải thực hiện thêm nhiều tác vụ để đảm bảo toàn vẹn dữ liệu thông qua nhiều bảng quan hệ. Vì vậy RDBMS thường có hiệu suất không cao trong viết
Cassandra viết lần đầu tiên vào commit log (đảm bảo durability). Và sau đó là viết vào cấu trúc bảng trong bộ nhớ gọi là memtable. Tác vụ viết là thành công khi nó viết vào commit log và vào memory. Vì vậy có rất ít tác vụ đĩa tại thời điểm đọc ghi dữ liệu. Việc ghi được thực hiện định kì vào đĩa cho một cấu trúc bảng nhất quán gọi là SSTable. Memtable và SSTable được bảo trì theo column family. Memtable được tổ chức bằng việc sắp xếp theo row key và được đẩy xuống SSTable một cách tuần tự
SSTable là inmutable (không thay đổi). Chúng không được viết lại sau khi đã flush. Có nghĩa rằng một row được lưu trữ thông qua nhiều file trong SSTable. Tại thời điểm đọc, Một dòng phải được combine từ tất cả các SSTable trên đĩa để sinh ra dữ liệu được yêu cầu. Để tối ưu process này Cassandra đãdùng một cấu trúc trong bộ nhớ gọi là bloom filter. Mỗi SSTable có một bloom filter kết hợp với nó. Nó dùng để
kiểm tra nếu một row key được yêu cầu tồn tại trong SSTable trước khi làm tác vụ tìm kiếm trên đĩa
4.1.1. Hiểu về Compaction
Trong background, Cassandra trộn các bảng SSTable định kì với nhau thành một bảng SSTable lớn dùng một process gọi là compaction. Compaction trộn những mảnh của dòng lại với nhau, remove cột tombstone và xây dựng lại khóa chính, khóa thứ cấp. VÌ SSTable được sắp xếp theo row key nên tác vụ merge hiệu quả. Một lần mà SSTable được merge hoàn thành, Input SSTable được đánh dấu xóa bởi Gabage collection. Mặc dầu vậy trong suốt quá trình compaction, có một không gian đĩa tăng đột biến tạm thời
Tác vụ này thực hiện việc đọc theo 2 cách. Trong khi nó đang chạy, nó tăng việc sử dụng đĩa và tác vụ I/O tạm thời. Cái này tác động đến hiệu suất đọc mà ko sử dụng cache. Mặc dầu vậy sau khi tác vụ này hoàn thành. Hiệu suất đọc ko cache được cải thiện khi có ít bảng SSTable hơn trên đĩa cần được kiểm tra để hoàn thành yêu cầu đọc
4.1.2. Quản lý giao tác và truy suất đồng thời
Không giống với RDBMS, Cassandra ko hỗ trợ đầy đủ các tính năng trong ACID không có locking hay độc lập giao tác khi update nhiều dòng hoặc column family
ACID là từ viết tắt dùng để miêu tả 4 hành vi mà transaction phải đạt được trong RDBMS:
o Atomic: Mọi thứ trong transaction đó phải thành công hoặc tất cả phải đc roll back
o Consistent: Một transaction không thể để DB ở trạng tháng thiếu nhất quán
o Isolated: Transaction này phải độc lập với những transaction khác o Durable: Phải bền bỉ với các hiện tượng hư hỏng của server
Cassandra đánh đổi giữa isolation và atomic để cho khả năng đáp ứng cao thực hiện việc ghi nhanh. Trong Cassandra, việc ghi là một tác vụ atomic ở cấp độ dòng, nghĩa là update hay insert column của một row key được xem như là một tác
vụ đọc. Cassandra ko hỗ trợ transaction của một update trên nhiều dòng => nó sẽ không roll back khi mà một tác vụ thành công trên một bảng sao nhưng lại trên một bản sao khác. Có thể trong Cassandra phải viết một report hỏng hóc cho client nhưng vẫn còn tồn tại việc ghi vào bản sao đó
Ví dụ nếu sử dụng tác vụ ghi cho có consistency level là QUORUM với replication factor là 3 cassandra sẽ gửi tác vụ ghi cho 2 bản sao. Nếu ghi fail trên một trong số những bản sao và thành công cho những cái còn lại, Cassandra sẽ report vấn đề này cho người dùng. Mặt dàu vậy tác vụ roll back không tự động thực hiện trên những bản sao kia
Cassandra sử dụng timestamp để quyết đinh update gần đây nhất của column.
Timestamp được hỗ trợ bởi ứng dụng client. Timestamp cuois cùng luôn được chọn có request data. Vì thế nếu nhiều phân vùng cùng update lên cũng một cột, update gần nhất sẽ đc chọn
Ghi trong Cassandra là durable. Tất cả tác vụ ghi vào một bản sao được ghi lại trong bộ nhớ và trong commit log trước khi chúng được biết như là một sự thành cộng. Nếu có crash hay server bị hỏng trước khi bảng bộ nhớ được đẩy xuống đĩa.
Commit log được dùng để recover tác vụ ghi 4.1.3. Hiểu về Inserts và Updates
Một vài cột có thể được insert tại cùng một thời điểm. Khi insert hay update column trong column family, ứng dụng người dùng đặc tả rowkey để nhận dạng cột nào được update. Rowkey tương tự như primary key, phải là duy nhất trong mỗi dòng của column family. Mặc dầu vậy không giống như primary key, insert một duplicate row key sẽ không báo lỗi như primary key. Nó đơn giản xem cái này như là một tác vụ update.
Column được viết đè nếu timestamp trong version mới của column gần hơn so với timestamp hiện tại. Vì thế timestamp chính xác là cần thiết nếu việc update xảy ra thường xuyên. Timestamp hỗ trợ bởi client.
4.1.4. About Deletes
Khi delete một dòng hay một cột trong Cassandra, có một vài thứ mà bạn phải biết
khác so với RDBMS
• Tác vụ xóa không remove dữ liệu trên đĩa ngay lập tức. Dữ liệu được insert vào Cassandra được tồn tại trong SSTable trên đĩa. Một lần SSTable được viết, nó không thay đổi (file không được update bởi DML). Có nghĩa rằng cột bị xóa không bị xóa ngay lập tức. Insert một maker gọi là tombstone được viết để chỉ ra trạng thái của cột mới. Cột được đánh dấu bởi maker tồn tại trong khoảng thời gian được cấu hình trước, sau đó mới xóa vĩnh viễn bởi tác vụ compaction sau khi thời gian cấu hình bị quá hạn
• Cột bị xóa có thể xuất hiện lại nếu routine node ko chạy. Đánh dấu cột bị xóa bằng tombstone đảm bảo rằng một bản sao được đưa xuống tại thời điểm xóa sẽ bị xóa cuối cùng khi nó back up trở lại. Mặc dầu vậy, nếu một node down lâu hơn thời điểm cấu hình để giữ tombstone thì node có thể mất dữ liệu bị xóa hoàn toàn, và nhân bản dữ liệu bị xóa 1 lần khi nó được back up trở lại. Để ngăn dữ liệu bị xóa xuất hiện lại, admin phải điều chỉnh sửa chữa mỗi node
Row key cho row bị xóa vẫn còn xuất hiện trong range query result. Khi bạn xóa một dòng trong Cassandra, nó đánh dấu tất cả các cột cho row key đó bằng tombstone.
Cho đến khi nó bị xóa bởi compation bạn có một empty row key (1 row ko có column). Những key bị xóa có thể được show trong get_range_slices(). Nếu ứng dụng client của bạn thực hiện câu truy vấn range lên row. Bạn có thể cũng cần phải filter đi những row ko có cột nào
4.1.5. Hiểu về ghi vào Hinted Handoff
Hinted handoff là một tính năng nổi bật của Cassandra để giảm thời gian restore một node bị hỏng trở nên nhất quán. Nó cũng có thể được dùng để sẵn sang viết cho những ứng dụng không chịu được lỗi do ghi sai nhưng chịu được lỗi do đọc không nhất quán
Khi một tác vụ ghi được tạo, Cassandra nỗ lực viết vào tất cả các bản sao cho những row bị ảnh hưởng. Nếu một bản sao bị down tại thời điểm ghi, một bản sao sống tương ứng sẽ lưu trữ một hint. Hint bao gồm thông tin về vị trí cũng như dữ liệu được viết.
Nếu tất cả các bản sao của những row bị tác động đều down. Nó vẫn có thể viết
thành công nếu cùng consistent level ANY. Dưới ngữ cảnh này, dữ liệu được ghi và dữ liệu hint được lưu trữ trên node coordinator nhưng sẽ không sẵn sang để đọc cho đến khi hint ghi vào bản sao thật sự sở hữu row đó. ANY hỗ trợ absolute write availability. Cái này không đảm bảo dữ liệu được viết sẽ sẵng sang được đọc. ANY cũng có thể tăng khả năng load cho cluster, khi coordinator phải lưu trữ tạm những row bất cứ khi nào bản sao không sẵn sang để ghi
Mặc định hint chỉ lưu một giờ trước khi chúng bị drop. Nếu tất cả các bản sao bị down tại thời điểm ghi và chúng vẫn còn down dài hơn max_hint_window_in_ms thì có thể có khả năng mất dữ liệu
Hints không thể cấu hình consistent level khác ANY. Ví dụ nếu là ONE và tất cả các bản sao cho dòng được viết đều down thì việc ghi đều thất bại bất kể là hint được ghi hay không