Mysql
 sql >> Cơ Sở Dữ Liệu >  >> RDS >> Mysql

Phân vùng bảng dữ liệu bóng đá hàng tỷ hàng sử dụng ngữ cảnh dữ liệu

Trong bài viết này, bạn sẽ học cách sử dụng ngữ nghĩa đằng sau dữ liệu của mình khi bạn phân vùng cơ sở dữ liệu của mình. Điều này có thể cải thiện đáng kể hiệu suất ứng dụng của bạn. Và, quan trọng nhất, bạn sẽ phát hiện ra rằng bạn nên điều chỉnh tiêu chí phân vùng cho phù hợp với miền ứng dụng duy nhất của mình.

Tôi đã hợp tác với một công ty khởi nghiệp để phát triển một ứng dụng web cho các chuyên gia thể thao đưa ra quyết định và khám phá dữ liệu. Ứng dụng này hỗ trợ bất kỳ môn thể thao nào, nhưng chúng tôi có trụ sở tại Châu Âu - và người Châu Âu yêu bóng đá. Mỗi trong số hàng trăm trò chơi được chơi mỗi ngày trên toàn thế giới đều có hàng nghìn hàng. Chỉ trong vài tháng, bảng Sự kiện trong ứng dụng của chúng tôi đã đạt nửa tỷ hàng!

Bằng cách hiểu cách các chuyên gia bóng đá truy vấn dữ liệu của chúng tôi, chúng tôi có thể phân vùng cơ sở dữ liệu một cách thông minh. Thời gian cải thiện trung bình trên bảng mới này nhanh hơn từ 20 lần đến 40 lần. Thời gian cải thiện trung bình trên tất cả các truy vấn là 5 lần đến 10 lần.

Bây giờ chúng ta hãy đi sâu vào tình huống này và tìm hiểu lý do tại sao bạn không thể bỏ qua ngữ cảnh dữ liệu của mình khi phân vùng cơ sở dữ liệu.

Trình bày bối cảnh

Ứng dụng thể thao của chúng tôi cung cấp cả dữ liệu thô và dữ liệu tổng hợp, mặc dù các chuyên gia đã áp dụng nó thích cái sau hơn. Cơ sở dữ liệu bên dưới chứa hàng terabyte dữ liệu phức tạp, không có cấu trúc, không đồng nhất từ ​​một số nhà cung cấp. Vì vậy, thách thức lớn nhất là thiết kế một cơ sở dữ liệu đáng tin cậy, nhanh chóng và dễ khám phá.

Miền ứng dụng

Trong ngành này, nhiều nhà cung cấp cung cấp cho khách hàng quyền truy cập vào các sự kiện của các trận bóng quan trọng nhất. Cụ thể, họ cung cấp cho bạn dữ liệu liên quan đến những gì đã xảy ra trong một trận đấu, chẳng hạn như bàn thắng, đường kiến ​​tạo, thẻ vàng, đường chuyền và hơn thế nữa. Cho đến nay, bảng chứa dữ liệu này là bảng lớn nhất mà chúng tôi phải làm việc.

Thông số kỹ thuật, công nghệ và kiến ​​trúc của VPS

Nhóm của tôi đã và đang phát triển ứng dụng phụ trợ cung cấp các tính năng khám phá dữ liệu quan trọng nhất. Chúng tôi đã sử dụng Kotlin v1.6 chạy trên JVM (Máy ảo Java) làm ngôn ngữ lập trình, Spring Boot 2.5.3 làm khung và Hibernate 5.4.32. Cuối cùng là ORM (Ánh xạ quan hệ đối tượng). Lý do chính khiến chúng tôi chọn công nghệ này là tốc độ là một trong những yêu cầu kinh doanh quan trọng nhất. Vì vậy, chúng tôi cần một công nghệ có thể tận dụng quá trình xử lý đa luồng nặng và Spring Boot hóa ra là một giải pháp đáng tin cậy.

Chúng tôi đã triển khai chương trình phụ trợ của mình trên VPS 8CPU 16GB thông qua vùng chứa Docker do Dokku quản lý. Nó có thể sử dụng tối đa 15GB RAM. Điều này là do một GB RAM được dành riêng cho hệ thống bộ nhớ đệm dựa trên Redis. Chúng tôi đã thêm nó để cải thiện hiệu suất và tránh quá tải phần phụ trợ với các hoạt động lặp lại.

Cơ sở dữ liệu và cấu trúc bảng

Đối với cơ sở dữ liệu, chúng tôi quyết định chọn MySQL 8. Một VPS 8GB và 2 CPU hiện đang lưu trữ máy chủ cơ sở dữ liệu, hỗ trợ tối đa 200 kết nối đồng thời. Ứng dụng phụ trợ và cơ sở dữ liệu nằm trong cùng một trang web máy chủ để tránh chi phí liên lạc. Chúng tôi đã thiết kế cấu trúc cơ sở dữ liệu để tránh trùng lặp và lưu ý đến hiệu suất. Chúng tôi quyết định sử dụng cơ sở dữ liệu quan hệ vì chúng tôi muốn có một cấu trúc nhất quán để chuyển đổi dữ liệu nhận được từ các nhà cung cấp. Bằng cách này, chúng tôi chuẩn hóa dữ liệu thể thao, giúp việc khám phá và trình bày cho người dùng cuối dễ dàng hơn.

Cơ sở dữ liệu chứa hàng trăm bảng tại thời điểm viết bài và tôi không thể trình bày tất cả chúng vì NDA mà tôi đã ký. May mắn thay, một bảng là đủ để phân tích kỹ lưỡng lý do tại sao chúng tôi kết thúc việc sử dụng phân vùng dựa trên ngữ cảnh dữ liệu mà bạn sắp thấy. Thử thách thực sự đến khi chúng tôi bắt đầu thực hiện các truy vấn nặng trên bảng Sự kiện. Nhưng trước khi đi sâu vào vấn đề đó, hãy xem bảng Sự kiện trông như thế nào:

Như bạn thấy, nó không liên quan đến nhiều cột, nhưng hãy nhớ rằng tôi đã phải bỏ qua một số trong số chúng vì lý do bảo mật. Nhưng những gì thực sự vấn đề ở đây là parameterIdgameId cột. Chúng tôi sử dụng hai khóa ngoại này để chọn một loại thông số (ví dụ:bàn thắng, thẻ vàng, đường chuyền, quả phạt đền) và các trận đấu mà nó đã xảy ra.

Các vấn đề về hiệu suất

Bảng Sự kiện đạt nửa tỷ hàng chỉ trong vài tháng. Như chúng tôi đã trình bày sâu trong bài đăng blog này, vấn đề chính là chúng tôi cần thực hiện các hoạt động tổng hợp bằng cách sử dụng các truy vấn IN chậm. Điều này là do những gì xảy ra trong một trò chơi không quá quan trọng. Thay vào đó, các chuyên gia thể thao muốn phân tích dữ liệu tổng hợp để tìm ra xu hướng và đưa ra quyết định dựa trên chúng.

Ngoài ra, mặc dù họ thường phân tích toàn bộ mùa giải hoặc 5 hoặc 10 trận gần nhất, người dùng thường muốn loại trừ một số trò chơi cụ thể khỏi phân tích của họ. Điều này là bởi vì họ không muốn một trận đấu diễn ra đặc biệt kém hoặc tốt để phân cực kết quả của họ. Chúng tôi không thể tạo trước dữ liệu tổng hợp vì chúng tôi sẽ phải thực hiện việc này trên tất cả các kết hợp có thể có, điều này không khả thi. Vì vậy, chúng tôi phải lưu trữ tất cả dữ liệu và tổng hợp dữ liệu đó một cách nhanh chóng.

Hiểu vấn đề về hiệu suất

Bây giờ, hãy đi sâu vào khía cạnh trung tâm dẫn đến các vấn đề về hiệu suất mà chúng tôi phải đối mặt.

Bảng triệu hàng chậm

Nếu bạn đã từng xử lý các bảng chứa hàng trăm triệu hàng, bạn biết rằng chúng vốn dĩ rất chậm. Bạn thậm chí không thể nghĩ đến việc chạy các JOIN trên các bảng lớn như vậy. Tuy nhiên, bạn có thể thực hiện các truy vấn CHỌN trong một khoảng thời gian hợp lý. Điều này đặc biệt đúng khi các truy vấn này liên quan đến các điều kiện WHERE đơn giản. Mặt khác, chúng trở nên chậm kinh khủng khi sử dụng các hàm tổng hợp hoặc mệnh đề IN. Trong những trường hợp này, chúng có thể dễ dàng mất tới 80 giây, đơn giản là quá nhiều.

Chỉ mục không đủ

Để cải thiện hiệu suất, chúng tôi quyết định xác định một số chỉ mục. Đây là cách tiếp cận đầu tiên của chúng tôi để tìm ra giải pháp cho các vấn đề về hiệu suất. Nhưng, thật không may, điều này dẫn đến một vấn đề khác. Các chỉ mục cần có thời gian và không gian. Điều này nói chung là không đáng kể, nhưng không đáng kể khi xử lý các bảng lớn như vậy. Hóa ra việc xác định các chỉ mục phức tạp dựa trên các truy vấn phổ biến nhất mất vài giờ và hàng GB dung lượng. Ngoài ra, các chỉ mục cũng hữu ích nhưng không phải là ma thuật.

Phân vùng cơ sở dữ liệu dựa trên ngữ cảnh dữ liệu như một giải pháp

Vì chúng tôi không thể giải quyết vấn đề hiệu suất với các chỉ mục được xác định tùy chỉnh, chúng tôi quyết định thử một cách tiếp cận mới. Chúng tôi đã nói chuyện với các chuyên gia khác, tìm kiếm giải pháp trực tuyến, đọc các bài báo dựa trên các tình huống tương tự và cuối cùng quyết định rằng phân vùng cơ sở dữ liệu là cách tiếp cận phù hợp để làm theo.

Tại sao phân vùng truyền thống có thể không phải là cách tiếp cận phù hợp

Trước khi phân vùng tất cả các bảng lớn nhất của chúng tôi, chúng tôi đã nghiên cứu chủ đề này cả trong tài liệu chính thức của MySQL và trong các bài báo thú vị. Mặc dù tất cả chúng tôi đều đồng ý rằng đây là cách để thực hiện, nhưng chúng tôi cũng nhận ra rằng việc áp dụng phân vùng mà không tính đến miền ứng dụng cụ thể của chúng tôi sẽ là một sai lầm. Cụ thể, chúng tôi đã hiểu tầm quan trọng của việc tìm ra các tiêu chí thích hợp khi phân vùng cơ sở dữ liệu. Một số chuyên gia về phân vùng đã dạy chúng tôi rằng cách tiếp cận truyền thống là phân vùng theo số hàng. Nhưng chúng tôi muốn tìm thứ gì đó thông minh hơn và hiệu quả hơn thế.

Đi sâu vào miền ứng dụng để tìm tiêu chí phân vùng

Chúng tôi đã học được một bài học quan trọng bằng cách phân tích miền ứng dụng và phỏng vấn người dùng của chúng tôi. Các chuyên gia thể thao có xu hướng phân tích dữ liệu tổng hợp từ các trò chơi trong cùng một cuộc thi. Ví dụ:một cuộc thi trong bóng đá có thể là một giải đấu, một giải đấu hoặc một trận đấu duy nhất mà bạn có thể giành được một chiếc cúp. Có hàng ngàn cuộc thi khác nhau. Những giải đấu quan trọng nhất ở châu Âu là Champions League, Premier League, La Liga, Serie A, Bundesliga, Eredivisie, Liga 1 và Primeira Liga.

Điều này có nghĩa là người dùng của chúng tôi rất hiếm khi tính đến dữ liệu đến từ các cuộc thi khác nhau. Ngoài ra, họ thích khám phá dữ liệu theo mùa. Nói cách khác, họ hiếm khi rời khỏi bối cảnh được đại diện bởi một cuộc thi thể thao diễn ra trong một mùa giải cụ thể. Cấu trúc cơ sở dữ liệu của chúng tôi thể hiện khái niệm này bằng một bảng có tên là SeasonCompetition , có mục tiêu là liên kết một cuộc thi với một mùa cụ thể. Vì vậy, chúng tôi nhận ra rằng một cách tiếp cận tốt sẽ là phân vùng các bảng lớn hơn của chúng tôi thành các bảng con liên quan đến một SeasonCompetition cụ thể ví dụ.

Cụ thể, chúng tôi đã xác định định dạng tên sau cho các bảng mới này:<tableName>_<seasonCompetitionId> .

Do đó, nếu chúng ta có 100 hàng trong SeasonCompetition bảng, chúng tôi sẽ phải chia Events lớn bảng thành Events_1 nhỏ hơn , Events_2 ,…, Events_100 những cái bàn. Dựa trên phân tích của chúng tôi, cách tiếp cận này sẽ dẫn đến hiệu suất tăng đáng kể trong trường hợp trung bình, mặc dù giới thiệu một số chi phí trong trường hợp hiếm hoi nhất.

Khớp các tiêu chí với các truy vấn phổ biến nhất

Trước khi mã hóa và khởi chạy các tập lệnh để thực thi hoạt động phức tạp và có khả năng không trả lại này, chúng tôi đã xác thực các nghiên cứu của mình bằng cách xem xét các truy vấn phổ biến nhất được thực hiện bởi ứng dụng phụ trợ của chúng tôi. Nhưng làm như vậy, chúng tôi phát hiện ra rằng phần lớn các truy vấn chỉ liên quan đến các trò chơi được chơi trong SeasonCompetition. Điều này thuyết phục chúng tôi rằng chúng tôi đã đúng. Vì vậy, chúng tôi đã phân vùng tất cả các bảng lớn trong cơ sở dữ liệu bằng cách tiếp cận vừa được xác định.


SELECT AVG('value') as 'value', SUM('minutes') as 'minutes'
FROM 'Events'
WHERE 'parameterId' = 15 AND 'gameId' IN(223,241,245,212,201,299,187,304,187,205)
GROUP BY 'teamId'

Bây giờ, chúng ta hãy nghiên cứu những ưu và nhược điểm của quyết định này.

Ưu điểm

  • Chạy các truy vấn trên một bảng chứa nhiều nhất nửa triệu hàng hiệu quả hơn nhiều so với thực hiện trên một bảng nửa tỷ hàng, đặc biệt là khi nói đến các truy vấn tổng hợp.
  • Các bảng nhỏ hơn dễ quản lý và cập nhật hơn. Việc thêm một cột hoặc chỉ mục thậm chí không thể so sánh được với trước đây về thời gian và không gian. Thêm vào đó, mỗi SeasonCompetition là khác nhau và yêu cầu các phân tích khác nhau. Do đó, nó có thể yêu cầu các cột và chỉ mục đặc biệt và cách phân vùng đã nói ở trên cho phép chúng tôi giải quyết vấn đề này một cách dễ dàng.
  • Nhà cung cấp có thể sửa đổi một số dữ liệu. Điều này buộc chúng tôi phải thực hiện các truy vấn xóa và cập nhật, nhanh hơn vô cùng trên các bảng nhỏ như vậy. Thêm vào đó, họ luôn chỉ quan tâm đến một số trò chơi của một SeasonCompetition cụ thể , vì vậy bây giờ chúng tôi chỉ cần thao tác trên một bảng duy nhất.

Nhược điểm

  • Trước khi thực hiện truy vấn trên các bảng con này, chúng ta cần biết seasonCompetitionId liên quan đến các trò chơi quan tâm. Điều này là do seasonCompetitionId giá trị được sử dụng trong tên bảng. Do đó, chương trình phụ trợ của chúng tôi cần truy xuất thông tin này trước khi chạy truy vấn bằng cách xem các trò chơi trong phân tích, thể hiện một khoản chi phí nhỏ.
  • Khi truy vấn liên quan đến một tập hợp trò chơi có nhiều SeasonCompetitions , ứng dụng phụ trợ phải chạy một truy vấn trên mỗi bảng con. Vì vậy, trong những trường hợp này, chúng ta không thể tổng hợp dữ liệu ở cấp cơ sở dữ liệu nữa, và chúng ta phải làm điều đó ở cấp ứng dụng. Điều này giới thiệu một số phức tạp trong logic phụ trợ. Đồng thời, chúng ta có thể thực hiện song song các truy vấn này. Ngoài ra, chúng tôi có thể tổng hợp dữ liệu đã truy xuất một cách hiệu quả và song song.
  • Việc quản lý một cơ sở dữ liệu với hàng nghìn bảng không phải là điều dễ dàng và có thể khó khăn để khám phá trong một ứng dụng khách. Tương tự, việc thêm một cột mới hoặc cập nhật một cột hiện có trong mỗi bảng rất phức tạp và yêu cầu một tập lệnh tùy chỉnh.

Ảnh hưởng của phân vùng dựa trên ngữ cảnh dữ liệu đến hiệu suất

Bây giờ chúng ta hãy xem xét sự cải thiện về thời gian đạt được khi thực hiện một truy vấn trong cơ sở dữ liệu được phân vùng mới.

  • Cải thiện thời gian trong trường hợp trung bình (truy vấn chỉ liên quan đến một SeasonCompetition ):từ 20x đến 40x
  • Cải thiện thời gian trong trường hợp chung (truy vấn liên quan đến một hoặc nhiều SeasonCompetitions ):từ 5x đến 10x

Suy nghĩ cuối cùng

Phân vùng cơ sở dữ liệu của bạn chắc chắn là một cách tuyệt vời để cải thiện hiệu suất, đặc biệt là trên các cơ sở dữ liệu lớn. Tuy nhiên, làm điều đó mà không xem xét miền ứng dụng cụ thể của bạn có thể là một sai lầm hoặc dẫn đến một giải pháp không hiệu quả. Thay vào đó, dành thời gian của bạn để nghiên cứu miền bằng cách phỏng vấn các chuyên gia và người dùng của bạn và bằng cách xem xét các truy vấn được thực thi nhiều nhất là rất quan trọng để hình thành tiêu chí phân vùng hiệu quả cao. Bài viết này đã chỉ cho bạn cách thực hiện điều này và chứng minh kết quả của cách tiếp cận như vậy thông qua một nghiên cứu điển hình trong thế giới thực.


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Cách nhận dữ liệu một tháng trước trong MySQL

  2. Làm thế nào để xem các tệp nhật ký trong MySQL?

  3. Ví dụ về PERIOD_DIFF () - MySQL

  4. MySQL CONVERT_TZ ()

  5. Trình kích hoạt MySQL không thể cập nhật các hàng trong cùng một bảng mà trình kích hoạt được chỉ định. Cách giải quyết được đề xuất?