NoSQL DBMS - 1000 câu hỏi vì sao
NoSQL
6
Database
33
White

MasBeeju viết ngày 10/08/2019

Hẳn anh em ở đây không xa lạ gì với NoSQL DBMS lẫn thế mạnh của nó. Nhưng liệu chúng ta có thực sự hiểu nó? Trước tiên, ta cùng điểm qua những thế mạnh và điểm trừ của NoSQL DBMS đã nhé!

Những thế mạnh và điểm trừ của NoSQL DBMS

Thế mạnh

  • Flexible, Elastic Scalability
  • High Performance
  • Economical
  • Flexible Data Model*

Điểm trừ

  • Not mature, poor documentation
  • Less Support.

Đặt vấn đề

Vì sao NoSQL DMBS lại có elastic scalability?
Vì sao lại high performance?
Vì sao NoSQL DBMS lại có những thế mạnh này mà RDBMS không có?
Dựa vào đâu, cấu trúc xây dựng hay là cơ chế hoạt động?
Tại sao RDBMS không học theo NoSQL DBMS để có những thế mạnh này?
...
Bài viết của mình sẽ giải thích toàn bộ những vấn đề này. Nếu anh em nào biết rồi thì giúp mình improve bài viết này với nhé!

Giải thích về điểm yếu

Trước tiên, ta đi vào điểm yếu. Một điểm yếu chí mạng của NoSQL DBMS là less support? Tại sao lại less support? Ngay cả khi ta đồng ý chi tiền thì cũng vẫn không support mạnh được. Vì:

  • NoSQL DBMS tuổi đời chưa cao, số lượng dự án dùng chúng và developer hoạt động với chúng cũng không nhiều. Lý do này cũng giải thích điểm trừ thứ nhất của NoSQL DBMS - not mature, poor documentation luôn.
  • Vả lại, NoSQL DBMS lại có nhiều loại ( 4 loại chính), và cấu trúc lẫn cách hoạt động của các loại cũng khác ít nhiều nên số lượng người dùng lại càng chia nhỏ ra nữa. alt text

Anh em có thể check ở DB-Engines Ranking để thấy chênh lệch giữa NoSQL DBMS và RDBMS. NoSQL DBMS phát triển rất nhanh nhưng vẫn còn rất nhỏ bé so với RDBMS. Vì vậy khi ta gặp vấn đề cần support thì rất hiếm người giải đáp (stackoverflow can't help you :laughing:), nên tốt nhất ta nên nắm rõ cơ chế hoạt động và bản chất của nó, nắm được rồi sẽ không ngại vấn đề gì cả. Hơn nữa, nếu ta nắm rõ được các điều đó thì những thế mạnh của NoSQL DBMS sẽ được ta tận dụng triệt để, hợp lý nhất.

Mình đã giải thích về điểm trừ, còn thế mạnh thì không dễ để giải thích như điểm trừ đâu. Mình sẽ nói về architecture tổng thể và mechanism của NoSQL DBMS trước. Anh em nên có kiến thức về Distributed system sương sương để dễ dàng hiểu hơn nha! Sau đây là architecture tổng thể của NoSQL DBMS (mình lấy của 1 NoSQL DBMS khá nổi hiện giờ là MongoDB, cấu trúc của các NoSQL DBMS sẽ tương tự như thế này thôi, cũng đều handle replicationing và sharding)

alt text

Replication

Có nhiều thể loại, tuỳ vào DBMS, thường thì là Primary-Secondary (tương tự như Master-Slave). Có một số DBMS như MongoDB thì lại có thêm kiểu Replica Set nhưng bản chất vẫn là Master-Slave thôi, chỉ là support thêm tính năng như automatic failover (xử lý trường hợp master lỗi).
alt text
Cơ chế hoạt động và những lợi ích mang lại của replication thì anh em cũng biết rồi, mình cũng đã giải thích ở đây: availability, request latency, read bandwidth, solve bottle neck-deadlock, backup, geographic location. Lợi ích quan trọng nhất vẫn là availability và back-up.
Song song với cách implement thì luôn luôn có các vấn đề cần giải quyết, nổi trội nhất vẫn là consistency, ngoài ra còn các vấn đề khác nữa như Master có vấn đề (Slave có vấn đề thì đơn giản rồi ). Lúc đó DBMS sẽ phải chọn Master mới trong số những Replication còn lại để có thể handle các request write, có thể dựa vào Arbiter. Anh em nên để ý những case này nghen, nếu DBMS không support thì phải tự handle, nếu DBMS support rồi thì thơm nhưng anh em nên hiểu rõ nó để control được 100%.

Sharding

Cấu trúc

Là horizontal partitioning (trái ngược vertical partitioning - chia theo column). Sharding làm một việc là distribute những document ra trên các shard riêng. Anh em nhìn hình dưới nè:
alt text
1 collection (tương đương 1 indices trong Elasticsearch, tuỳ cách đặt tên của các DBMS thôi) tương đương với table trong RDBMS, là tập hợp những document có đặc điểm chung với nhau. Riêng vụ tên của các DBMS thôi đã thấy đau đầu rồi anh em :laughing:, indices với index chả biết đường nào mà lần.
Cứ như vậy, hàng trăm DBMS lại đặt tên khác nhau, có cú pháp khác nhau, thành ra mình nên nắm được bản chất chứ cũng đừng quan tâm quá nhiều vào những cái tên, cú pháp làm gì cho mệt:yum: !

Cơ chế

Insert

Khi ta insert một document vào thì document mới này sẽ được distribute vào 1 trong các shard hiện thời.
Tuỳ theo cơ chế của DBMS và mối liên hệ với các document khác( NoSQL DBMS không phải là hoàn toàn không có relationship, vẫn tồn tại document link với document khác nha anh em, chỉ là không có ràng buộc khoá ngoại mạnh mẽ như RDBMS thôi) mà router sẽ distribute những document ấy vào cùng 1 shard. Mục tiêu ở đây là performance.

Query

alt text
Khi xử lý một câu query, thì router sẽ chuyển query cho các shard. Sau đó, các shard thực hiện query riêng lẻ và responds kết quả về router. Lúc này router server có nhiệm vụ merge các kết quả lại và trả về cho người dùng.
Hiện nay thì nền công nghiệp của mình đã hiện đại hơn xưa rất nhiều rồi, máy tính giờ con nào con nấy 8 core 16 core hết, thậm chí còn nhiều processor nữa, nên 1 máy tính sẽ có nhiều thread. Vì NoSQL DBMS implement sharding, nên mỗi thread handle 1 request cho mỗi shard. Vậy thì lợi ích quá rõ ràng rồi: performance.

Lợi ích

Như nãy giờ giải thích, high performance là mục tiêu lớn nhất của sharding.
Nữa, anh em hãy đối chiếu với distributed system, có thể thấy sharding sẽ rất thuận tiện cho scalability. Lúc dữ liệu quá nhiều, thì partitioning sẽ là cần thiết. Đối với RDBMS, việc partitioning sẽ khó hơn rất nhiều so với NoSQL DBMS. Lý do là data trong RDBMS có ràng buộc, liên kết với nhau nên khi partition thì sẽ phải làm sao cho những data có liên quan với nhau vào 1 part, nếu không thì sẽ ảnh hưởng đến performance. Việc này cực khó khăn và cực kỳ tổn hại đến performance lúc write, nên gần như RDBMS hiện tại không hỗ trợ, nếu muốn thì ta sẽ phải tự handle, việc này có chi phí về economic lẫn performance không nhỏ. Nên ta mới nói, NoSQL support automatically sharding sẽ đơn giản rất nhiều việc, không phải handle manual nhiều, thuê DevOps này kia nhiều nữa.

Segment

Là unit chứa các information cần thiết của data, được dùng trong in-memory buffer và disk.

Hẳn là anh em có nghe đến in-memory của NoSQL DBMS rồi đúng không? Nó là để cải thiện performance? Đúng, nhưng bằng cách nào?

Trong một số NoSQL DBMS hỗ trợ mạnh về in-memory( ví dụ như Redis, Memcached trong Key-value Store, Elasticsearch trong Search Engine), muốn search/get thì ta phải đánh index cho các field của document lúc document đó lúc được insert. Anh em có thể tìm hiểu thêm về cách đánh index của DBMS anh em đang xài.

Near-realtime

Khi insert 1 document vào thì DBMS sẽ không insert vào disk ngay, mà sẽ lưu ở memory buffer. Có lúc nào anh em insert 1 document, sau khi DBMS trả về response thông báo thành công, nhưng khi get/search thì anh em lại không thấy document này trong result mà sau một thời gian mới có. Lúc đó anh em mình sẽ dè ra chửi "Nó ngu gì đâu ý! Cứ chậm chậm thế nào!"
Thực ra, những data mới của anh em đã được lưu ở memory buffer, chứ không insert vào disk ngay. Thứ nhất, việc này sẽ done request sớm hơn. Thứ 2, việc insert nhỏ lẻ vào disk là một việc rất tốn tài nguyên và ảnh hưởng đến performance. Khi data trên segment đã đủ lớn (hoặc thời gian đủ dài, việc này anh em có thể config được), DBMS sẽ flush, ghi tất cả data trên tất cả segment vào dish và memory buffer được clear ngay.

Nếu mất điện hoặc xảy ra vấn đề lúc data chưa đứa insert xuống disk thì sao?
Đã có transaction log lo, khi có data mới thì đồng thời lưu ở in-memory buffer và append vào transaction log luôn, khi mất điện thì dữ liệu trong memory sẽ mất hết, nhưng transaction log thì không mất, lúc hệ thống hoạt động lại thì translog sẽ được check và insert toàn bộ data trong nó vào disk.
Tất cả những việc này gọi là near-realtime hay near-persistent, đổi lại là performance.
alt text
Khi insert data
alt text
Khi đã flush data

Immutable

Khi search/get thì DBMS cũng sẽ cache lại trong memory, mục đích ở đây vẫn là tăng performance.
Nhưng để có được điều đó, ta phải giải quyết vài vấn đề. Vấn đề nan giải nhất là phải giữ in-memory buffer luôn luôn đáng tin và không xảy ra exception, nghĩa là những inverted index trong memory đừng có sai. Nếu data trên memory và disk khác nhau thì sẽ ăn hành ngay! Thử tưởng tượng trong memory có document A nhưng trong disk thì document A đã bị update hoặc delete xem nghen:laughing:.
Để giải quyết vấn đề này thì inverted index trên disk phải immutable, nghĩa là đã insert vào rồi thì không bao giờ thay đổi. Đồng thời nếu implement immutable data thì sẽ không cần lock data (thử tưởng tượng inverted index bị update thì sẽ xảy ra chuyện locking, blocking như RDBMS vậy). Cách giải quyết:

  • Khi delete document thì sẽ không xóa document đó đi mà đánh dấu là "is deleted".
  • Tương tự khi update document thì đánh dấu document đó trong disk là "is deleted" và insert vào version mới của document.

Bằng cách này, data của ta sẽ luôn immutable. Còn anh em đừng sợ lúc query thì ta phải mất công quét qua những document đã bị đánh dấu là "is deleted", vì đã được đánh index nên việc query rất nhanh, lúc tổng hợp kết quả thì DBMS chỉ cần xóa những document được đánh dấu là "is deleted" là xong.

Ủa, làm đủ thứ như vậy để làm gì :confused:??
Cuối cùng vẫn là để support cho in-memory buffer mà thôi :smile:!
Mà in-memory để làm gì :confused:??
Improve Performance :smile:!

Trả lời câu hỏi

Chúng ta đã cùng nhau đi qua gian khó trong bài này rồi, giờ là lúc để kiểm chứng lại và clear hết những nghi vấn, thắc mắc từ đầu đến giờ nha anh em!

  • Tại sao NoSQL DBMS hỗ trợ elastic scalability?

Trả lời: Vì NoSQL DBMS support sharding rất dễ dàng và tự động. Tưởng tượng data nhiều thì ta lại config thành nhiều shard hơn, distribute trên nhiều machine.

  • Tại sao NoSQL DBMS high performance?

Trả lời:

  • Write request:
    • Flexible data model: lúc insert sẽ chẳng check gì cả. Lúc insert thì DBMS sẽ đơn giản là lấy body của request làm value, còn key sẽ tự generate(có thể explicit key nhưng sẽ bị performance vì DBMS phải check toàn bộ key có sẵn để tránh trùng).
    • In-memory: không ghi disk ngay mà ghi ở memory trước.
  • Query request:

    • Less relationship: không phải retrieve data ở nhiều chỗ.
    • Shard: thực hiện concurrency.
    • In-memory: nếu đã cache thì trả data về, không cần đọc ở disk.
  • Tại sao NoSQL DBMS high availability?

Trả lời: Replication.

  • Tại sao NoSQL DBMS Economical?

Trả lời: NoSQL DBMS support sharding lẫn replicationing tự động và có cơ chế handle những case cần thiết (như chọn master mới lúc master node bị lỗi), rất dễ dàng nên không cần DevOps nhiều lẫn chi phí những extra tool để làm những việc này. Nữa là rất nhiều NoSQL DBMS là Open-source nên ta sẽ giảm được chi phí chi trả cho lisences.

Tiếp theo là một số câu hỏi của anh em trong "ngành" đã đưa ra

  • Mình hơi thắc mắc về sự phối hợp giữa replication với sharding trong NoSQL DBMS

Trả lời: Cấu trúc và cơ chế của replica và shard thì anh em đã nắm rõ rồi, mình không giải thích lại nữa. Còn sự phối hợp thì mỗi shard trong NoSQL DBMS sẽ có thể là primary-shard (master) hoặc là secondary-shard (slave). Mình mượn cái hình của 1 NoSQL DBMS khá nổi hiện giờ là MongoDB.
alt text
Anh em nhìn thêm hình architecture của MongoDB ở phần Đặt vấn đề để tưởng tượng lại cơ chế hoạt động nha.
Architecture của các NoSQL DBMS sẽ khác đôi chút, ví dụ là Elasticsearch là có thêm sự tồn tại của node (đóng vai 1 server trong distributed system) và cluster. Nhưng về structure cơ bản, mechanism lẫn lợi ích của replica và shard thì không thay đổi nên anh em chỉ cần nắm rõ được bản chất thì DBMS nào cũng không ngán.

  • Sharding có phải là mỗi shard luôn luôn nằm trên từng server riêng lẻ không?

Trả lời: Trên local machine của mình thì tất cả shard nằm chung. Nhưng trong môi trường thực tế yêu cầu data lớn thì DevOps sẽ implement shard nằm riêng trên từng server.Anh em có thể xem thêm ở đây để nắm rõ hơn.

  • RDBMS (SQL DBMS) có support distribution, partition data không? Ví dụ như microservice thì nó lại có chia nhỏ data ra riêng.

Trả lời: RDBMS không support partitioning data tự động. Và việc partition data trong RDBMS thì thường là vertical partitioning chứ không phải horizontal partitioning như NoSQL DBMS (lý do thì là tại relationship), và việc partition data manual cũng khó khăn.
“Microservice chia nhỏ data ra riêng”: việc distribute data đó là do architecture, không phải do RDBMS.
alt text
Trên thực tế, mỗi service có thể dùng NoSQL DBMS hay là RDBMS tuỳ thích. Người ta sẽ lấy những data cần thiết và có mô hình dữ liệu khác nhau (tuỳ bounded context) cho từng service riêng, như hình trên, chứ không phải distribute data ra nhỏ lẻ theo kiểu horizontal partitioning (chia toàn bộ document của collection ra trên nhiều shard nhỏ lẻ).
Ngoài lề 1 xíu, distribution khác với replication. Và RDBMS chả support những việc này automatic mà tất cả là manual, do architecture và các engine khác định đoạt.

  • Mọi NoSQL DBMS khi update với delete document đều là soft delete chứ không xoá hẳn hả?

Trả lời: Không, cơ chế đó là chỉ để support in-memory feature. Tuỳ NoSQL DBMS mà sẽ có cách handle khác nhau đôi chút, mình không tìm hiểu tất cả NoSQL DBMS được, nhưng cũng tương tự nhau mà thôi. Nếu không handle kiểu như mình nói thì trường hợp 1 là database sẽ có một vài thời điểm data không reliable, trường hợp 2 là NoSQL DBMS đó chả support in-memory feature luôn.

  • Mấy cơ chế của NoSQL DBMS nêu nãy giờ là nó implement hết hả, hay ta phải tự implement?

Trả lời: Các NoSQL DBMS đã implement hết rồi, ta chỉ cần hiểu rõ cấu trúc và cơ chế hoạt động nữa để xài cho chuẩn thôi. Còn một số thứ advanced như scale database ra trên mỗi server thì phải lấn sân qua DevOps 1 xíu.

  • Chia bao nhiêu shard là do mình cấu hình, hay nó sẽ tự động chia số lượng shard hợp lý? Replica nữa?

Trả lời: Đã có default sẵn, nhưng có thể custom config lại được. Ví dụ như trong Elasticsearch thì là 5 shard, và 1 replica cho mỗi shard => tính ra là 10 shard (link). Tóm lại, ta muốn thì có thể config số lượng của replica và shard, mọi việc còn lại như distribute data, distribute query... thì để DBMS lo, quá sướng.

Kết bài

Bài viết này nói về cấu trúc tổng quan và cơ chế hoạt động của NoSQL DBMS mà anh em nên biết.

Để viết một bài viết vừa đáp ứng có sự tổng quát cho mọi NoSQL DBMS, lại vừa cụ thể để có thể dễ dàng hiểu được thì có khả năng cao là mình đã bỏ sót chỗ nào đó, hoặc là có chỗ nào đó hơi khác so với một vài DBMS, thì anh em thông cảm cho mình nhé! Hi vọng anh em cũng góp ý cho mình để bài chia sẻ này được tốt hơn!

Hi vọng bài viết này sẽ giúp anh em thấu hiểu DBMS anh em đang xài hơn, không "chửi feature" và có thể tận dụng được sức mạnh của các NoSQL DMBS một cách triệt để, hợp lý nhé :smile:!

Bình luận


White
{{ comment.user.name }}
Bỏ hay Hay
{{comment.like_count}}
Male avatar
{{ comment_error }}
Hủy
   

Hiển thị thử

Chỉnh sửa

White

MasBeeju

4 bài viết.
71 người follow
Kipalog
{{userFollowed ? 'Following' : 'Follow'}}
Cùng một tác giả
White
24 6
Chào những người anh em Trong thời đại công nghệ hiện nay, có rất nhiều hướng để giải quyết một bài toán. Database (chính xác là DBMS database mana...
MasBeeju viết 3 tháng trước
24 6
White
10 10
Chào anh em web developer Hiện nay để một hệ thống web application có thể thành công, nổi tiếng thì sẽ trải qua rất nhiều gian nan. Hệ thống của c...
MasBeeju viết 3 tháng trước
10 10
White
9 13
Chào anh em (Link) của Hiểu và chọn database trong NoSQL DBMS mình đã phân tích về các loại NoSQL DBMS, part 2 này mình sẽ đi đến CAP theorem(định ...
MasBeeju viết 3 tháng trước
9 13
Bài viết liên quan
White
0 1
1, Cài đặt MongoDB. Đầu tiên các bạn truy cập vào địa chỉ website https://www.mongodb.com//downloadcenter?jmp=nav Và làm theo hình ảnh dưới đây (l...
Thanh Tài viết 2 năm trước
0 1
White
38 10
Mình biết đến (Link) cách đây khoảng 2 năm, tại thời điểm mà giá bitcoin tăng khủng khiếp ấy. Khi đó không biết mọc ở đâu lắm thầy phán bitcoin qu...
nooptr viết 4 tháng trước
38 10
{{like_count}}

kipalog

{{ comment_count }}

bình luận

{{liked ? "Đã kipalog" : "Kipalog"}}


White
{{userFollowed ? 'Following' : 'Follow'}}
4 bài viết.
71 người follow

 Đầu mục bài viết

Vẫn còn nữa! x

Kipalog vẫn còn rất nhiều bài viết hay và chủ đề thú vị chờ bạn khám phá!