Web Scalability 101: Database và Microservices

trong danh mục Technology

mysql-database

Cũng gần một tháng kể từ bài đầu tiên trong loạt bài vỡ lòng về web scalability. Hôm nay mình tiếp tục chia sẻ một vấn đề khác cần quan tâm nếu bạn muốn scale hệ thống web tốt hơn đó là scale hệ thống cơ sở dữ liệu (database) và vì sao kiến trúc Microservices lại tốt cho database của bạn và không được bỏ qua kiến trúc này.

Như hầu hết các ứng dụng hiện nay, database là một phần không thể thiếu trong các ứng dụng và hầu như tính năng nào cũng sẽ kết nối đến một database để đọc, ghi dữ liệu phục vụ trong quá trình xử lý và phản hồi cho người dùng, và chính vì vậy, khi scale hệ thống thì database là một yếu tố phải được xếp ưu tiên cao.

Mình không sử dụng nhiều loại database và chủ yếu sử dụng MySQL hơn 10 năm qua nên bài này mình chủ yếu viết trên kinh nghiệm làm việc với MySQL, nhưng các kiến thức ở đây là ở tầng khái niệm và kiến trúc, do đó, hầu hết các công nghệ database hiện tại đều hỗ trợ.

Database cho người không biết gì

Như bài trước, trước khi scale một cái gì thì ít ra cũng phải biết được cách thức hoạt động và giới hạn của nó. Phần này mình sẽ giới thiệu nhanh để mọi người tiện theo dõi các mục bên dưới. Cơ sở dữ liệu thường là dữ liệu có cấu trúc, được lưu trữ dưới dạng tập tin trong ổ đĩa (HDD, SSD..) hoặc trong bộ nhớ (Memory – RAM). Các cơ sở dữ liệu hầu như đều có 1 cách thức, ngôn ngữ để truy xuất, ghi dữ liệu và cái này người ta gọi là câu truy vấn – Query.

Có 2 loại truy vấn chính là truy xuất dữ liệu (đọc) và ghi dữ liệu (thêm, sửa, xóa) và hệ quản trị cơ sở dữ liệu khi tiếp nhận truy vấn đọc dữ liệu sẽ tiến hành tìm kiếm trong các nơi đã lưu dữ liệu (file, memory), bởi vì quá trình này là truy xuất ngẫu nhiên nên thường chậm, do đó, các cơ sở dữ liệu sẽ có cơ chế Index để việc tìm kiếm nhanh hơn hoặc có một lớp đệm truy vấn giúp cache lại các truy vấn hay sử dụng để nhanh chóng trả về dữ liệu. Và một hệ thống quản lý làm việc với database và cung cấp các tiện ích này gọi là hệ quản trị cơ sở dữ liệu (DBMS) và MySQL là một hệ quản trị cơ sở dữ liệu quan hệ (RDBMS).

Tại sao cần quan tâm đến Database

Database là một hệ thống quan trọng và là một dịch vụ xương sống giúp toàn bộ hệ thống hoạt động, do đó, nó cũng trở thành điểm yếu trong quá trình mở rộng hệ thống. Khi mở rộng hệ thống, lượng truy cập vào các web server sẽ tăng lên, kéo theo các kết nối từ web server đến database sẽ tăng lên và khiến database quá tải và nó trở thành điểm yếu của toàn hệ thống.

Một số phương pháp scale Database

Nếu google về mảng này thì bạn sẽ có nhiều hướng dẫn về cách scale database. Mình giới thiệu nhanh để mọi người tiện nghiên cứu thêm.

Vertical scaling

Đây là cách thức scale database đơn giản nhất và trong phần lớn trường hợp nó mang lại hiệu quả nhất. Cách này đơn giản chỉ là nâng cấp database server lên một server có cấu hình mạnh hơn, việc nâng cấp này sẽ không thay đổi tầng application (code) của bạn, chỉ đơn giản là nâng cấp server.

Horizontal scaling – Clustering

Phương pháp này là xây dựng một hệ thống database như một thực thể, nhưng thực chất có nhiều database server phía sau. Và sử dụng cơ chế clusting để lưu trữ và chia tải trong quá trình truy xuất dữ liệu. Với bản chất không tin tưởng lắm vào các công nghệ clustering và thực sự khi có vấn đề thì sẽ khó kiếm được hướng xử lý, khôi phục dữ liệu nên mình không sử dụng phương pháp này.

Database replication

Replication là một kỹ thuật được nhiều hệ thống sử dụng. Trong kiến trúc này, database sẽ được clone (tự động) ra nhiều bản và đồng bộ tự động với nhau theo cơ chế của DBMS, các server này sẽ được phân thành 2 nhóm là Master và Slave.

Tất cả các truy vấn liên quan đến ghi dữ liệu (thêm, sửa, xóa) sẽ được kết nối và thực hiện trên Master database và sẽ được đồng bộ sang các slave database. Các truy vấn đọc dữ liệu sẽ được kết nối đến các slave database để tăng tốc độ truy xuất và chia tải nhiều hơn.
Replication
Kiến trúc thường thấy là có 1 Master và có nhiều Slave. Bởi khi có nhiều Master thì việc đồng bộ giữa các Master có thể dẫn đến sai sót dữ liệu liên quan đến auto-increment field.

Cách này có thể được điều hướng trong code của bạn, dựa vào loại câu truy vấn sẽ điều hướng đến các cụm database tương ứng. Ví dụ khi gặp câu truy vấn có dạng “SELECT…” thì điều hướng đến cụm database slave, và có thể sử dụng thuật toán round-robin trong code để chọn ngẫu nhiên 1 slave database trong cụm.

Load balancer

Load balancer không chỉ ở tầng web application, nó cũng có thể hỗ trợ ở layer 4, tức là ở tầng IP và port. Cách này bổ trợ cho việc load balancing database trong một farm như là master, hoặc slave. Code chỉ trỏ đến IP của một DB balancer và khi truy vấn đến port 3306 thì load balancer này sẽ tự động chia tải vào các database tương ứng.

Cách này sẽ giúp ở tầng code không quan tâm nhiều đến chi tiết của các kết nối database, code chỉ cần biết các cửa ngõ để truy vấn vào, chuyện còn lại để DB Load balancer lo. Ngoài ra, phương pháp sử dụng load balancer sẽ có thế tự động detect được các DB Server có vấn đề và remove khỏi hệ thống một cách tự động mà không can thiệp vào code của application.

Haproxy có hỗ trợ load balancing cho MySQL.

In-memory Database

Trong một số ngữ cảnh, việc lưu trữ trong ổ cứng (HD, SSD..) sẽ không mang lại hiệu suất cao nhất cho việc truy xuất dữ liệu, thì việc đưa database vào memory để truy xuất là một kiến trúc đáng xem xét. MySQL có một storage engine cho table là MEMORY, sẽ giúp toàn bộ dữ liệu 1 table của bạn lưu trong bộ nhớ và truy xuất rất nhanh, bạn có thể thử engine này của MySQL. Tuy nhiên, là một đặc tính cố hữu của memory, khi restart thì sẽ mất dữ liệu nên thường dữ liệu lưu trong memory là dữ liệu đã được tổng hợp hoặc tạm và có thể khôi phục lại.

Mình dùng In-memory database cho một số hệ thống report cần truy xuất với dữ liệu lớn và nhanh chóng. Ngoài ra, trên thế giới có nhiều In-Memory DBMS nổi tiếng như MemSQL (cựu kỹ sư facebook startup), Aerospike…

Bufferpool

MySQL engine INNODB có một cơ chế là bufferpool khá hay, cũng là một dạng in-memory để tăng tốc việc truy xuất dữ liệu, nhưng hoàn toàn tự động và dữ liệu của 1 table được cache tạm trong một vùng nhớ, và khi truy vấn dữ liệu liên quan đến table này thì sẽ kiểm tra dữ liệu trong bufferpool trước khi truy xuất trực tiếp xuống ở đĩa.

Microservices

Sử dụng kiến trúc microservice sẽ giúp scale hệ thống database một cách rất tự nhiên. Trong tất cả các phương pháp trên, hầu hết bạn xuất phát điểm là chỉ có 1 database server và chứa toàn bộ dữ liệu của hệ thống. Việc scale chủ yếu tập trung vào 3 phương pháp chính là nâng cấu hình, clone và caching. Còn một cách khác là chia để trị, và cách này đòi hỏi sự thay đổi ở mức kiến trúc tổng thể.
lean-enterprise-microservices-and-big-data-54-638
Thay vì hệ thống của bạn đang viết là monolithic và chỉ kết nối đến 1 database “bự” và chứa tất cả dữ liệu, bạn sẽ thay đổi kiến trúc thành microservice, chia dự án thành nhiều dự án nhỏ và mỗi dự án sẽ có database riêng. Với việc chia nhỏ như vậy, kết nối đến từng database nhỏ này chỉ ở phạm vi service đó và sẽ giảm tải rất nhiều cho database và cũng sẽ không gây ra tình trạng Single Point of Failure (Một điểm chết) cho Database. Chỉ có một bất tiện trong chia để trị là bạn sẽ quản lý nhiều database riêng cho từng service thay vì chỉ làm việc trên 1 database “bự” như cách thông thường.

Như vậy, việc chia nhỏ này sẽ biến mỗi dự án là một dịch vụ độc lập về database, và quá trình scale của database trong từng service cũng có thể áp dụng 1 trong bốn phương pháp kể trên: nâng cấu hình, clone, cache & chia để trị.

Việc thay đổi kiến trúc sang microservice là một quyết định mang tính chiến lược cao vì sẽ tốn công R&D, nhưng một khi đã chuyển sang kiến trúc này thì các bạn sẽ thấy việc scale database trở nên nhẹ nhàng và “tự tin” hơn để làm việc với các database cục bộ. Nếu quan tâm đến microservice, bạn có thể tìm hiểu thêm các slide chia sẻ của mình về lĩnh vực này tại https://www.slideshare.net/lonelywolf

—–

Trên đây là những chia sẻ của mình về những kỹ thuật giúp scale hệ thống database và kiến trúc microservice hỗ trợ thế nào trong việc scale này. Scale database có nhiều kỹ thuật khác chứ không phải chỉ gói gọn trong các nội dung mình chia sẻ. Tuy nhiên, dưới góc độ bài viết này thì mình chỉ chia sẻ những phương pháp mình đã áp dụng cho các hệ thống từ trước đến nay.

7 bình luận

  1. Phuoc says:

    Font Tiếng Việt khó đọc quá anh ơi T_T

  2. Hung says:

    khi gặp câu truy vấn có dạng “SELECT…” thì điều hướng đến cụm database slave, -> nếu vậy lại phát sinh thêm bước detect câu query có phải là chỉ đọc hay không.

  3. Thinh says:

    a Tuấn cho em hỏi trong kỹ thuật mysql replication,
    trường hợp insert vào DB trên con slave server thì nó có tự động đồng bộ đến các DB trên master và các slave server khác ko?

    • Vo Bien says:

      @Thinh, Theo mình hiểu thì việc insert, update, delete chỉ được thực hiện trên con master thôi bạn. Các con slave chỉ dùng cho các câu lệnh select.

  4. Tét tơ says:

    bài viết chẳng có gì, ngoài các keywords hay quá. Cảm ơn anh Tuấn

  5. Phan Ha says:

    @Phuoc, Trong the ban de nguyen font-family: Serif;. Minh cung bi hoi kho doc, F12 len sua font-family :p

  6. Tuyen Vu says:

    Hi anh
    Bài viết rất bổ ích, anh cố gắng viết thêm nhiều bài để em học hỏi với ạ.

    Thanks.

Gởi bình luận