Sử dụng MySQL để thường xuyên tham gia nhiều cách trên các bảng trên 100 GB?


11

Bối cảnh :
Tôi đã tạo một ứng dụng web mà tôi muốn có khả năng mở rộng hợp lý. Tôi biết tôi không phải Google hay Twitter, nhưng ứng dụng của tôi sử dụng một lượng dữ liệu khá lớn cho mỗi người dùng và do đó có yêu cầu dữ liệu khá cao. Tôi muốn sẵn sàng mở rộng quy mô hợp lý mà không phải tái kiến ​​trúc mọi thứ sau này.

Tôi coi mình là một nhà phát triển phần mềm, không phải là một chuyên gia cơ sở dữ liệu. Đó là lý do tại sao tôi đăng bài ở đây. Hy vọng ai đó có nhiều chuyên môn về cơ sở dữ liệu có thể cho tôi lời khuyên.

Với số lượng người dùng tương đối lớn, nhưng không có gì giống như số Facebook, tôi hy vọng sẽ có một DB trông như thế này:

Một "Bàn lớn":

  • 250 triệu hồ sơ
  • 20 cột
  • Khoảng 100 GB dữ liệu
  • Có khóa ngoại được lập chỉ mục (20)
  • Có một cột var_id (500) được lập chỉ mục
  • Có cột "giá trị" int (11)

4 bảng khác:

  • 10 triệu hồ sơ mỗi
  • Khoảng 2 - 4 GB dữ liệu mỗi
  • mỗi bảng có 4 - 8 cột
  • một cột là datetime date_created
  • một cột là cột varar (500)
  • một hoặc hai cột từ mỗi bảng này sẽ được chọn trong một liên kết

Một trong những bảng này được sử dụng để lưu trữ trung bình - lược đồ của nó là bigint (20) id, varchar (20) string_id, datetime date_created, float Average_value

Những gì tôi muốn làm - hai truy vấn tương đối đắt tiền:

  1. Tính giá trị trung bình mới:

    • Sử dụng khóa ngoại, chọn tối đa vài triệu bản ghi riêng biệt từ bảng lớn.
    • Tính trung bình mới, nhóm theo chuỗi_id.
    • Chèn kết quả vào bảng trung bình.
    • Như hiện tại được xây dựng, truy vấn này sử dụng hai tham gia.
  2. Tạo các bản ghi không chuẩn hóa, chỉ đọc để phục vụ người dùng:

    • Sử dụng khóa ngoại để chọn bất kỳ nơi nào từ 1.000-40.000 bản ghi từ bảng lớn.
    • Tham gia với bốn bảng khác trong bản ghi mới nhất với cột id chuỗi.
    • Chèn kết quả vào bảng khử chuẩn.
    • Những bản ghi này được sử dụng bởi front-end để hiển thị thông tin cho người dùng.
    • Như hiện tại được xây dựng, truy vấn này sử dụng bốn tham gia.

Tôi dự định chạy từng truy vấn đắt tiền này trên cơ sở dữ liệu back-end hàng loạt sẽ đẩy kết quả của nó đến máy chủ DB mặt trước thời gian thực xử lý các yêu cầu từ người dùng. Các truy vấn này sẽ được chạy trong khoảng thời gian thường xuyên. Tôi đã không quyết định mức độ thường xuyên. Truy vấn trung bình có thể được thực hiện có lẽ một lần mỗi ngày. Truy vấn không chuẩn hóa sẽ cần thường xuyên hơn - có lẽ cứ sau vài phút.

Mỗi truy vấn này hiện đang chạy trong vài giây trong MySQL trên một máy rất cấp thấp với bộ dữ liệu có bản ghi 100K trong bảng lớn. Tôi lo ngại về cả khả năng mở rộng quy mô và chi phí nhân rộng.

Câu hỏi :

  1. Liệu cách tiếp cận này có vẻ âm thanh? Có bất cứ điều gì rõ ràng sai với nó từ một quan điểm bức tranh lớn?
  2. RDBMS có phải là công cụ phù hợp hay tôi nên xem xét các giải pháp "dữ liệu lớn" khác giống như một cái gì đó trong gia đình Hadoop? Xu hướng của tôi là sử dụng RDBMS vì dữ liệu được cấu trúc và phù hợp với mô hình quan hệ. Tuy nhiên, tại một thời điểm nhất định, tôi hiểu rằng tôi có thể không còn có thể sử dụng RDBMS nữa. Điều đó có đúng không? Khi nào thì công tắc này sẽ cần thiết?
  3. Nó sẽ làm việc chứ? Những truy vấn này có thể được chạy trong một khoảng thời gian hợp lý không? Tôi có thể đợi hàng giờ để truy vấn # 1, nhưng truy vấn # 2 sẽ kết thúc sau vài phút.
  4. Tôi nên xem xét gì từ góc độ phần cứng? RAM và CPU bị nghẽn cổ chai của tôi có khả năng là gì? Tôi cho rằng việc giữ các chỉ số trong RAM là quan trọng. Có điều gì khác tôi nên xem xét?
  5. Tại một số điểm tôi có thể sẽ phải phân vùng dữ liệu của mình và sử dụng nhiều máy chủ. Liệu trường hợp sử dụng của tôi có vẻ như đã có trong danh mục đó hay tôi sẽ có thể mở rộng một máy theo chiều dọc trong một thời gian? Điều này sẽ làm việc với 10 lần dữ liệu? 100x?

Đây là một khó khăn để trả lời kỹ lưỡng. Có lẽ bạn nên nghiên cứu về các đặc điểm hiệu năng truy vấn của MySQL nói chung để bạn biết những gì bạn có thể mong đợi.; Tất nhiên, một điều mà bạn luôn có thể làm là đặt 20 đĩa vào máy chủ để bạn có thể đọc với tốc độ 3 GB / giây. Nhưng tôi nghĩ rằng bạn đang ở sau một câu trả lời kỹ lưỡng chỉ phần mềm.
usr

Câu trả lời:


4

Bạn đã thử chồng nhiều dữ liệu và điểm chuẩn chưa? Hàng 100K là không quan trọng. Hãy thử 250M hoặc 500M như bạn mong đợi, bạn sẽ cần xử lý và xem các nút thắt cổ chai ở đâu.

Một RDBMS có thể làm rất nhiều thứ nếu bạn chú ý cẩn thận đến các hạn chế và thử và làm việc với các điểm mạnh của hệ thống. Họ đặc biệt giỏi một số thứ, và khủng khiếp với những thứ khác, vì vậy bạn sẽ cần phải thử nghiệm để chắc chắn rằng nó phù hợp.

Đối với một số công việc xử lý hàng loạt, bạn thực sự không thể đánh bại các tệp phẳng, tải dữ liệu vào RAM, phá vỡ nó bằng cách sử dụng một loạt các vòng lặp và các biến tạm thời và loại bỏ kết quả. MySQL sẽ không bao giờ có thể phù hợp với loại tốc độ đó, nhưng nếu được điều chỉnh đúng và sử dụng đúng cách, nó có thể đi theo một thứ tự cường độ.

Những gì bạn sẽ muốn làm là điều tra làm thế nào dữ liệu của bạn có thể được phân vùng. Bạn có một bộ dữ liệu lớn với quá nhiều liên kết chéo để có thể phân tách dữ liệu hoặc có những nơi tự nhiên để phân vùng không? Nếu bạn có thể phân vùng nó, bạn sẽ không có một bảng với cả đống hàng, nhưng có khả năng nhiều bảng nhỏ hơn đáng kể. Các bảng nhỏ hơn, với các chỉ mục nhỏ hơn nhiều, có xu hướng hoạt động tốt hơn.

Từ góc độ phần cứng, bạn sẽ cần kiểm tra để xem nền tảng của bạn hoạt động như thế nào. Đôi khi trí nhớ là điều cần thiết. Lần khác, nó là đĩa I / O. Nó thực sự phụ thuộc vào những gì bạn đang làm với dữ liệu. Bạn sẽ cần hết sức chú ý đến việc sử dụng CPU của mình và tìm kiếm mức IO cao để chờ xem vấn đề nằm ở đâu.

Bất cứ khi nào có thể, hãy phân chia dữ liệu của bạn trên nhiều hệ thống. Bạn có thể sử dụng MySQL Cluster nếu bạn cảm thấy dũng cảm hoặc đơn giản là tạo ra nhiều phiên bản độc lập của MySQL trong đó mỗi phần lưu trữ một phần tùy ý của tập dữ liệu hoàn chỉnh bằng cách sử dụng một số lược đồ phân vùng hợp lý.


@tadman Cảm ơn lời khuyên của bạn. Tôi nhận ra không có sự thay thế cho việc thực sự thử nó. Tôi chưa đánh giá nó với 250M hàng vì trước tiên tôi muốn chắc chắn rằng không có gì sai rõ ràng về cách tiếp cận của tôi. Có vẻ như không có. Ngoài ra, có được nhiều dữ liệu đó và thực hiện theo cách hơi thực tế là một thách thức tôi chưa tìm ra cách giải quyết. Tôi có một số cách tiềm năng để phân vùng dữ liệu. Tôi đoán tiếp theo tôi sẽ thử kiểm tra dữ liệu của mình và xem nó hoạt động như thế nào tại các điểm kiểm tra khác nhau - 1M, 10M, 100M, v.v.
xnickmx

1

Bảng tóm tắt.

Mỗi ngày, tính toán thông tin tổng hợp cho dữ liệu của ngày. Đặt nó trong bảng "tóm tắt". Làm các truy vấn của bạn chống lại họ. Dễ dàng nhanh gấp 10 lần.

Để thảo luận thêm, xin vui lòng cung cấp

  • HIỂN THỊ TẠO BẢNG (như bây giờ)
  • Kích thước bảng (mà bạn đã đề cập)
  • Đề xuất CHỌN

Một số điều hiển nhiên ...

  • BIGINT hiếm khi được bảo hành. Phải mất 8 byte. INT UNSIGNED mất 4 và cho phép các giá trị 0..4 tỷ. Và có MEDIUMINT, v.v.
  • Nhiều chỉ mục trên bảng 'thực tế' thường là một vấn đề hiệu suất nghiêm trọng, đặc biệt là đối với các CHERTN. Bạn đang có một vấn đề ở đó?
  • DATETIME là 8 byte; THỜI GIAN là 4
  • CÔNG CỤ TUYỆT VỜI NGOẠI TỆ là tốt, nhưng tốn kém
  • THAM GIA có thể hoặc không thể là một vấn đề hiệu suất; cần phải xem CHỌN và TẠO.
  • 100GB là một kích thước đẹp cho cơ sở dữ liệu MySQL 'lớn'; Tôi nghi ngờ nó có thể được tạo ra để hoạt động mà không có Hadoop, v.v. Bây giờ tôi xử lý một db như vậy - hầu hết các trang UI phản hồi trong một giây mặc dù dữ liệu khá liên quan.
  • Bạn sẽ được 'thanh trừng' dữ liệu tại một số điểm? (Điều này dẫn đến trường hợp sử dụng chính cho THAM GIA.)

"Nhỏ hơn -> dễ nhớ hơn -> nhanh hơn


0

Để phục vụ dữ liệu giao diện người dùng của bạn, trừ khi luôn có những tiếng gob và gobs chèn, bạn thực sự không thể đánh bại bằng cách sử dụng các trình kích hoạt để chèn vào các khung nhìn cụ thể được giữ đồng bộ với mặt sau nhưng được tối ưu hóa để phục vụ dữ liệu. Tất nhiên, bạn cần giữ cho các phép nối, v.v., ở mức tối thiểu trong các kích hoạt này. Một chiến lược tôi đã sử dụng là xếp hàng các chèn / cập nhật này vào một bảng trung gian và sau đó gửi chúng sau mỗi phút hoặc lâu hơn. Gửi một bản ghi dễ dàng hơn nhiều so với 4 GB bản ghi. 4 GB dữ liệu cần một thời gian dài để phát trực tiếp ngay cả khi bạn có thể tìm thấy các bản ghi mà bạn đang tìm kiếm một cách nhanh chóng.

Tôi đồng ý với tadman. Tốt nhất là lập hồ sơ với loại dữ liệu bạn đang mong đợi trên loại hệ thống bạn muốn.


Như tôi đã đề cập trong bài đăng của mình, các lượt xem phụ thuộc vào truy vấn sử dụng bốn phép nối trên các bảng với hàng chục triệu bản ghi, vì vậy tôi không thực sự thấy cách xem cụ thể hóa sẽ giúp ích như thế nào.
xnickmx

Kích hoạt có thể không đủ nhanh cho cơ sở dữ liệu kích thước này. Có bao nhiêu INSERT mỗi giây đang xảy ra?
Rick James

1
@xnickmx Nếu không có quá nhiều thao tác chèn / cập nhật, trình kích hoạt giúp bạn dễ dàng / thực hiện để đồng bộ hóa dữ liệu không chuẩn hóa. Nếu nó cần phải đi nhanh hơn để chèn / cập nhật, hãy xếp hàng chúng với thứ gì đó như thế này: blog.shlomoid.com/2008/04/ / hoặc nướng bánh của riêng bạn. Bằng cách này, bạn không phải tham gia vào các bảng hàng 100 triệu hiện có để có được dữ liệu mới kể từ khi kích hoạt kích hoạt, bạn tận dụng thực tế là bạn biết dữ liệu mới ngay lúc đó và chỉ có thể chuẩn hóa dữ liệu đó như một phần của tx hoặc xếp hàng để chuẩn hóa sau này.
wes.stueve

@RickJames Đồng ý. Bạn phải tính đến số lượng chèn cho loại chiến lược này và tốc độ chúng phải xử lý.
wes.stueve
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.