2010-05-29 38 views
14

Tôi đang bắt đầu một dự án mà tôi nghĩ sẽ đặc biệt phù hợp với MongoDB do tốc độ và khả năng mở rộng mà nó chi phối.MongoDB Schema Design - Trò chuyện thời gian thực

Mô-đun mà tôi hiện đang quan tâm là thực hiện trò chuyện trong thời gian thực. Nếu tôi đã làm điều này trong một RDBMS truyền thống Tôi muốn chia nó ra thành:

  • Channel (Kênh có nhiều người sử dụng)
  • tài khoản (Một người sử dụng có một kênh nhưng nhiều thông điệp)
  • nhắn (Một tin nhắn có người dùng)

Mục đích của trường hợp sử dụng này, tôi muốn giả định rằng sẽ có 5 kênh hoạt động cùng một lúc, mỗi kênh xử lý tối đa 5 tin nhắn mỗi giây.

truy vấn

cụ thể mà cần phải được nhanh chóng:

  • Fetch tin nhắn mới
  • Đăng một tin nhắn tới một kênh
  • Xác nhận (dựa trên một bookmark, tem thời gian có thể, hoặc một quầy incrementing?) mà người dùng có thể đăng trong kênh

Hãy nhớ rằng giới hạn tài liệu với MongoDB là 4mb, bạn sẽ thiết kế lược đồ như thế nào? Bạn sẽ trông như thế nào? Có bất kỳ gotchas tôi nên xem ra cho?

Trả lời

3

Tôi đã sử dụng Redis, NGINX & PHP-FPM cho dự án trò chuyện của tôi. Không siêu thanh lịch, nhưng nó thực hiện thủ thuật. Có một vài phần trong câu đố.

  1. Có một tập lệnh PHP rất đơn giản nhận lệnh của khách hàng và đặt chúng trong một danh sách lớn. Nó cũng kiểm tra tất cả các DANH SÁCH trong phòng và DANH SÁCH riêng của người dùng để xem có tin nhắn nào phải cung cấp hay không. Điều này được bình chọn bởi một khách hàng được viết bằng jQuery & nó được thực hiện sau mỗi vài giây.

  2. Có một dòng lệnh PHP script hoạt động phía máy chủ trong một vòng lặp vô hạn, 20 lần mỗi giây, kiểm tra danh sách này và sau đó xử lý các lệnh này. Kịch bản xử lý ai nằm trong phòng và quyền nào trong bộ nhớ tập lệnh, thông tin này không được lưu trữ trong Redis.

  3. Redis có DANH SÁCH cho mỗi phòng & DANH SÁCH cho mỗi người dùng hoạt động dưới dạng hàng đợi riêng tư. Nó cũng có nhiều bộ đếm cho mỗi phòng người dùng đang ở. Nếu người dùng truy cập ít hơn tổng số tin nhắn trong phòng, thì nó sẽ nhận được sự khác biệt và gửi nó cho người dùng.

Tôi chưa thể kiểm tra giải pháp này, nhưng ít nhất từ ​​điểm chuẩn cơ bản, có thể xử lý hàng nghìn thư mỗi giây. Ngoài ra còn có cơ hội chuyển cổng này sang một cái gì đó như Node.js để tăng hiệu suất. Redis cũng đang trưởng thành và có một số tính năng thú vị như Pub/Subscribe lệnh, mà có thể được quan tâm, mà có thể sẽ loại bỏ bỏ phiếu trên phía máy chủ có thể.

Tôi đã xem xét các giải pháp dựa trên Comet, nhưng nhiều giải pháp phức tạp, kém tài liệu hoặc yêu cầu tôi học một ngôn ngữ hoàn toàn mới (ví dụ: Jetty-> Java, APE-> C), v.v. thông qua proxy đôi khi có thể là một vấn đề với Comet. Vì vậy, đó là lý do tại sao tôi đã bị mắc kẹt với bỏ phiếu.

Tôi tưởng tượng bạn có thể làm điều gì đó tương tự với MongoDB. Một bộ sưu tập cho mỗi phòng, một bộ sưu tập cho mỗi người dùng & sau đó một bộ sưu tập duy trì quầy. Bạn vẫn sẽ cần phải viết một daemon back-end hoặc kịch bản để xử lý manging nơi các tin nhắn này đi. Bạn cũng có thể sử dụng "bộ sưu tập hạn chế" của MongoDB, giữ các tài liệu được sắp xếp & cũng tự động xóa các thông báo cũ ra, nhưng điều đó có thể phức tạp trong việc duy trì các bộ đếm thích hợp.

3

Tại sao sử dụng mongo cho hệ thống nhắn tin? Cho dù lưu trữ tĩnh nhanh đến mức nào (và mongo rất nhanh), cho dù là mongo hay db, bắt chước hàng đợi thông báo, bạn sẽ phải sử dụng một số loại bỏ phiếu, không phải là rất dễ mở rộng hoặc hiệu quả. Cấp cho bạn không làm bất cứ điều gì khủng khiếp dữ dội, nhưng tại sao không chỉ sử dụng đúng công cụ cho đúng công việc? Sử dụng hệ thống nhắn tin như Rabbit hoặc ActiveMQ.

Nếu bạn phải sử dụng mongo (có thể bạn chỉ muốn chơi với nó và dự án này là một cơ hội tốt để làm điều đó?) Tôi tưởng tượng bạn sẽ có một bộ sưu tập cho người dùng (trong đó mỗi đối tượng người dùng có một danh sách hàng đợi mà người dùng nghe). Đối với tin nhắn, bạn có thể có một bộ sưu tập cho mỗi hàng đợi, nhưng sau đó bạn sẽ phải thăm dò ý kiến ​​mỗi hàng đợi bạn quan tâm cho tin nhắn. Tốt hơn là nên có một bộ sưu tập như một hàng đợi, vì dễ dàng trong việc làm "truy vấn" trong một bộ sưu tập duy nhất, vì vậy sẽ dễ dàng thực hiện những việc như "nhận tất cả thư mới hơn X trong bất kỳ hàng đợi nào có hàng đợi .name trong danh sách [a, b, c] ". Bạn cũng có thể xem xét việc thiết lập bộ sưu tập của mình dưới dạng bộ sưu tập giới hạn mongo, điều này chỉ có nghĩa là bạn nói với mongo khi bạn thiết lập bộ sưu tập mà bộ sưu tập của bạn chỉ nên chứa số lượng x số byte hoặc số mục X. Thêm các mục bổ sung có hành vi First-In, First-Out khá lý tưởng cho hàng đợi tin nhắn. Nhưng một lần nữa, nó không thực sự là một hệ thống nhắn tin.

+1

Tôi sẽ không đề xuất rằng các giải pháp MQ có thực sự tốt hơn nhiều so với một số giải pháp NoSQL ngoài kia. Rất nhiều công nghệ MQ có vẻ phức tạp và được thiết kế quá mức, cộng với hiệu năng không phải lúc nào cũng tuyệt vời, ổn định và tính di động cũng có thể bị hy sinh. Xem: http://bhavin.directi.com/rabbitmq-vs-apache-activemq-vs-apache-qpid/ – Klinky

+1

Có những giải pháp MQ phong nha ngoài kia, tôi chỉ thấy chúng là những cái không có nhiều tính năng , ZeroMQ và Kestrel đều tốt cho mục đích của họ. ActiveMQ mặt khác là khủng khiếp. – Michael

+0

@Klinky Tôi đặt cược hầu như bất kỳ giải pháp MQ cụ thể nào (đặc biệt là ActiveMQ) sẽ xử lý vấn đề nhắn tin tốt hơn so với giải pháp tùy chỉnh dựa trên NoSQL của loại không xác định (ý của bạn là DB hoặc khóa tài liệu) - bởi vì các giải pháp MQ được thiết kế cho vấn đề đó, và, FTN ActiveMQ sử dụng lưu trữ dữ liệu hiệu năng cao được tối ưu hóa của riêng nó để duy trì hàng đợi. –

1

1) ape-project.org

2) http://code.google.com/p/redis/

3) sau khi bạn thông qua tất cả điều này - bạn có thể dữ liệu câm vào MongoDB cho khai thác gỗ và lưu trữ dữ liệu phù hợp (người dùng, các kênh truyền hình) như well

Các vấn đề liên quan