Làm việc với Large Data

Posted by MinhHungTrinh on 2021-01-17
Estimated Reading Time 13 Minutes
Words 2.2k In Total
Viewed Times

Đây là bài mình viết cũng đã trình bày trên blog kaopiz.kipalog của công ty.
Bản chất cá nhân mình cũng chưa được thực sự làm việc với một database được gọi là Large Data. Mình cũng đã từng join các dự án ban đầu cũng yêu cầu là thiết kế với số lượng user lớn, hay lượng data cập nhật lớn do logic. Nhưng bản chất đó chỉ là estimate kỳ vọng, không hẳn là thực tế. Nhưng sau quá trình tìm hiểu mình cũng muốn nói lên vài ý kiến cá nhân về việc lựa chọn, thiết kế và làm việc với nó. Để từ đó trao đổi cùng mọi người. Và rất mong được sự góp ý của mọi người để cùng nhau cải thiện.

Mở bát

  • Đầu tiên mình cũng hay gặp vài người thường bốp chát luôn NoSQL thôi, SQL hết thời rồi chẳng hạn. Hoặc cái gì cũng NoSQL, hoặc tôn sùng. Xem nào, mình cảm thấy mấy người này giống mấy người nói, cái ngôn ngữ này hết thời rồi… :( => mình nhận thấy đây là những quan điểm sai lầm
  • Cứ dữ liệu lớn là NoSQL thôi. => mình không đồng tình lắm.
  • Bài toán nào cũng thế, cũng chỉ chung tình với SQL chẳng hạn.
    Vậy lựa chọn làm việc với 1 database khủng như thế nào. Đánh giá cá nhân của mình là TUỲ.

Việc bạn sử dụng dữ liệu kiểu NoSql hay SQL nó có ý nghĩa quyết định rất lớn đến hiệu suất về kết quả của người dùng. Không thể phủ nhận tốc độ tối ưu hơn của NoSQL vì đơn giản bởi nó sinh ra để làm việc với những dữ liệu lớn, đa dạng và dễ dàng mở rộng dành cho lập trình viên.
Nhưng trong những bài toán phức tạp và yêu cầu về rằng buộc lớn thì SQL luôn là xu thế được ưu tiên hàng đầu.
Có vài ví dụ sau:

  • Chắc chắn là cách đây hơn chục năm trước, khi mà NoSQL chưa được áp dụng phổ biến thì các WebSite cũng đâu có chậm. Chắc chắn là dữ liệu cũng to chà bá rồi. Sau này thì đúng là NoSQL bùng nổ. Nhưng bạn có thấy tốc độ truy cập có khác nhiều không.
  • Một lý do nữa là các hệ thông của ngân hàng vẫn làm việc với combo Java + oracle. Vấn đề là sao họ không lựa chọn dùng NoSQL trên hệ thống đó, để đáp ứng được nhanh (Hệ thống ngân hàng thì database thực sự to rồi nhé).

Các giải pháp

  • Hybrid giữa NoSQL và SQL. Tận dụng ưu điểm của SQL phục vụ cho việc tính toán phức tạp và ràng buộc database. NoSQL là tốc độ và mở rộng. Từ đó database của hệ thống sẽ Hybrid giữa 2 thứ. Với những bảng có tốc độ gia tăng data lớn, yêu cầu tốc độ truy vấn, truy vấn thường xuyên, caching, tính toán sẵn. Thì chúng ta có thể sử dụng NoSQL (Ở đây ví dụ như bảng messages của comment, chat. Bảng order của đơn hàng, history, logging chẳng hạn. Những data của các bảng này gia tăng rất nhanh). Với những bảng mang tính chất ràng buộc quan hệ, yêu cầu logic tính toán, truy vấn phức tạp thì hẳn hiển nhiên là dùng SQL rồi.
  • Có thể sử dụng song song 2 thằng này theo thứ tự: NoSQL làm việc với các client user, còn SQL thì là nơi backup dữ liệu. Việc sử dụng qua lại 2 thằng đảm bảo cho hệ thống vừa đáp ứng được phản hồi tới EndUser và vừa ràng buộc chắc chắn về data. Hoặc có thể thao tác ghi thì qua SQL và thao tác đọc qua NoSQL.
  • Với hệ thống của bạn là chuyên biệt và có tính năng quan trọng thì nên sử dụng SQL. Cũng đừng lo quá.
  • Và với những hệ thống logic không có gì phức tạp thì ngần ngại gì mà không triển khai toàn bộ là NoSQL.
  • Việc lựa chọn SQL hay NoSQL thì cũng đều cần phải chú ý đến việc đánh index làm sao để phục vụ cho thao tác Select là nhanh nhất mà cũng không ảnh hưởng nhiều đến thao tác insert => tác động yêu cầu về logic. Việc tránh phải scan cả bảng hoặc 1 phần của bảng, mà truy vấn theo index có thể giúp tốc độ truy vấn tăng lên x3 lần chẳng hạn. Data lớn thì tỉ lệ này càng chênh luôn.
  • Một database khủng thường rất mong manh dễ vỡ vì chắc chắn nó phải chịu lượng requests rất nhiều. Nên hãy caching ngay khi nào cho phép nhé.
  • Một database khủng, để tăng hiệu suất đọc ghi, hãy áp dụng các kiến trúc như Mô hình Sharding, Partition, Cluster hoặc Replicate nhé. Để luôn cung cấp đủ tài nguyên cho database. Như thế thì database mới chạy mạnh khoẻ được nha.
  • Nếu có thể không nên lưu tập trung tất cả vào 1 database. Với các bảng có logic không liên quan nhau thì hãy tách ra là database riêng. Đảm nhiệm là 1 node trong microservice system giao tiếp quá REST API. Việc phân bổ không gây gánh nặng lên 1 server và tận dụng được ưu điểm của microservice.
  • Ngoài việc lựa chọn loại database, kết hợp các database thì việc thiết kế trong từng bảng cũng rất quan trọng. Đây là 1 cách mình thường xuyên sử dụng với việc đánh đổi bộ nhớ lưu trữ lấy tốc độ của hệ thống. Ví dụ như tính toán trước và lưu sẵn thêm 1 trường trong bảng chẳng hạn. Lúc cần thì chỉ cần select ra thôi. Giảm được đáng kể. Hiện giờ phần cứng rất phát triển nên ổ cứng rất rẻ và nhanh. Việc đánh đổi này có vẻ rất hợp lý.
  • Ngoài ra trong khi code bạn sử dụng việc thao tác dữ liệu cho từng trường hợp sẽ nhanh hơn việc thao tác dữ liệu để dùng chung cho mọi trường hợp.
  • Phân vùng những dữ liệu theo dạng Cũ - Mới, Thời gian, Địa lý, các thuộc tính đặc trưng,…. sử dụng where sẽ không làm cho tốc độ của bạn nhanh hơn thay vì thế hãy sử dụng bảng tạm để phân vùng dữ liệu (Tham khảo: https://www.red-gate.com/simple-talk/sql/database-administration/gail-shaws-sql-server-howlers/). Cái này cũng mang hơi hướng thiết kế database theo mô hình partition như ý ở trên.
  • Xóa dữ liệu cũ định kỳ: Dữ liệu cũ sẽ không thực sự bị xóa đi mà nó chỉ chuyển từ bảng A sang bảng History,.. Thực ra thì nó cũng mang định hướng partition.
  • Thực hiệu lưu file nhị phân các hình ảnh tệp tin thay vì nhị phân chúng và lưu vào CSDL,… Hoặc theo mình là không lưu luôn, chỉ lưu URL và lưu nó vào trong các Cloud Storage.
  • Với SQL, không nên lúc nào cũng chỉ tập trung vào 1 loại database như MySQL chẳng hạn. Hãy tìm hiểu cả loại khác. Mỗi cái đều có điểm mạnh yếu. Ví dụ so sánh với PostgreSQL chẳng hạn. Với 1 lượng data lớn, 1 sự khác biệt đơn giản như MySQL phù hợp lấy về 10 bản ghi đầu tiên chẳng hạn, trong ghi postgreSQL thì phù hợp hơn khi lấy số lượng lớn về. Hay sự khác nhau về thuật toán Join. Với so sánh PostgreSQL và MySQL bạn có thể tham khảo từ https://viblo.asia/p/8-diem-so-sanh-giua-mysql-va-postgresql-de-chon-lua-cai-nao-phu-hop-hon-OeVKB4NElkW, https://medium.com/@huyrom/postgresql-v%C3%A0-mysql-b%C3%A0i-to%C3%A1n-tri%E1%BB%87u-truy-v%E1%BA%A5n-19b75433b37.
  • Ngoài ra còn mấy cái nhỏ nhỏ những cũng ảnh hưởng như về lựa chọn kiểu dữ liệu. (Char hay Varchar cho trường hợp nào, Datetime hay Integer khi lưu trữ thời gian, String hay SmallInt khi dùng cho flag), độ dài của trường. Chúng ta cũng cần tối ưu nó.
  • Một phân liên quan đến thao tác với database dữ liệu lớn để được tối ưu. Khi thao tác chúng ta phải luôn để ý tới rằng nó bao gồm thời gian truy vấn + thời gian nạp data. Vì vậy chỉ tối ưu 1 trong 2 phần trên là chưa đủ. Vậy nên hãy lưu ý nhé.

Tổng kết

Cá nhân mình hiện tại tức thì chỉ nhớ vài cái gạch đầu dòng để viết thôi. Với từng usecase chắc chắn sẽ còn nhiều thứ để viết chỉ là bất chợt chưa nghĩ tới. Vì vậy mình sẽ bổ sung dần. :))
Cảm ơn mọi người đã đọc bài. Vì đây chỉ là ý kiến cá nhân nên rất mong được sự góp ý hoặc bổ sung. ^^


Đây là Blog cá nhân của MinhHungTrinh, nơi mình chia sẻ, lưu giữ kiến thức. Nếu các bạn có góp ý, thắc mắc thì vui lòng comment bên dưới cho mình biết nhé. Mình luôn là người lắng nghe và ham học hỏi. Các vấn đề đặc biệt hoặc tế nhị mọi người có thể gửi email tới minhhungtrinhvn@gmail.com. Cảm ơn Mọi Người đã đọc Blog của mình. Yolo!