Tóm tắt : Đối với khoảng 1 triệu người dùng hoạt động và 150 triệu hoạt động được lưu trữ, tôi giữ cho nó đơn giản:
- Sử dụng cơ sở dữ liệu quan hệ để lưu trữ các hoạt động duy nhất (1 bản ghi cho mỗi hoạt động / "điều đã xảy ra") Làm cho các bản ghi nhỏ gọn nhất có thể. Cấu trúc để bạn có thể nhanh chóng lấy một loạt các hoạt động bằng ID hoạt động hoặc bằng cách sử dụng một bộ ID bạn bè với các ràng buộc về thời gian.
- Xuất bản ID hoạt động lên Redis bất cứ khi nào bản ghi hoạt động được tạo, thêm ID vào danh sách "luồng hoạt động" cho mọi người dùng là bạn bè / người đăng ký sẽ thấy hoạt động.
Truy vấn Redis để lấy luồng hoạt động cho bất kỳ người dùng nào và sau đó lấy dữ liệu liên quan từ db khi cần. Quay trở lại truy vấn db theo thời gian nếu người dùng cần duyệt ngược thời gian (nếu bạn thậm chí cung cấp điều này)
Tôi sử dụng một bảng MySQL cũ đơn giản để xử lý khoảng 15 triệu hoạt động.
Nó trông giống như thế này:
id
user_id (int)
activity_type (tinyint)
source_id (int)
parent_id (int)
parent_type (tinyint)
time (datetime but a smaller type like int would be better)
activity_type
cho tôi biết loại hoạt động, source_id
cho tôi biết hồ sơ mà hoạt động đó có liên quan. Vì vậy, nếu loại hoạt động có nghĩa là "thêm yêu thích" thì tôi biết rằng source_id đề cập đến ID của một bản ghi yêu thích.
các parent_id
/parent_type
rất hữu ích cho ứng dụng của tôi - họ cho tôi biết những gì hoạt động có liên quan đến. Nếu một cuốn sách được yêu thích, thì Parent_id / Parent_type sẽ cho tôi biết rằng hoạt động liên quan đến một cuốn sách (loại) với một khóa chính (id) đã cho
Tôi lập chỉ mục (user_id, time)
và truy vấn cho các hoạt động được user_id IN (...friends...) AND time > some-cutoff-point
. Việc bỏ id và chọn một chỉ mục cụm khác nhau có thể là một ý tưởng hay - tôi chưa thử nghiệm điều đó.
Những thứ khá cơ bản, nhưng nó hoạt động, nó đơn giản và dễ dàng làm việc khi nhu cầu của bạn thay đổi. Ngoài ra, nếu bạn không sử dụng MySQL, bạn có thể thực hiện chỉ mục tốt hơn.
Để truy cập nhanh hơn vào các hoạt động gần đây nhất, tôi đã thử nghiệm với Redis . Redis lưu trữ tất cả dữ liệu trong bộ nhớ, vì vậy bạn không thể đặt tất cả các hoạt động của mình vào đó, nhưng bạn có thể lưu trữ đủ cho hầu hết các màn hình thường gặp trên trang web của mình. 100 gần đây nhất cho mỗi người dùng hoặc một cái gì đó như thế. Với Redis trong hỗn hợp, nó có thể hoạt động như thế này:
- Tạo hồ sơ hoạt động MySQL của bạn
- Đối với mỗi người bạn của người dùng đã tạo hoạt động, hãy đẩy ID vào danh sách hoạt động của họ trong Redis.
- Cắt từng danh sách cho các mục X cuối cùng
Redis rất nhanh và cung cấp một cách để truyền các lệnh trên một kết nối - vì vậy việc đẩy một hoạt động ra tới 1000 bạn bè mất một phần nghìn giây.
Để được giải thích chi tiết hơn về những gì tôi đang nói, hãy xem ví dụ Twitter của Redis: http://redis.io/topics/twitter-clone
Cập nhật tháng 2 năm 2011 Tôi có 50 triệu hoạt động tích cực vào lúc này và tôi không thay đổi gì cả. Một điều tuyệt vời khi làm một cái gì đó tương tự như thế này là nó sử dụng các hàng nhỏ gọn. Tôi đang lên kế hoạch thực hiện một số thay đổi sẽ liên quan đến nhiều hoạt động hơn và nhiều truy vấn hơn về các hoạt động đó và tôi chắc chắn sẽ sử dụng Redis để giữ mọi thứ nhanh chóng. Tôi đang sử dụng Redis trong các lĩnh vực khác và nó thực sự hoạt động tốt đối với một số loại vấn đề.
Cập nhật tháng 7 năm 2014 Chúng tôi có tới khoảng 700 nghìn người dùng hoạt động hàng tháng. Trong vài năm qua, tôi đã sử dụng Redis (như được mô tả trong danh sách gạch đầu dòng) để lưu trữ 1000 ID hoạt động cuối cùng cho mỗi người dùng. Thường có khoảng 100 triệu bản ghi hoạt động trong hệ thống và chúng vẫn được lưu trữ trong MySQL và vẫn có cùng bố cục. Những bản ghi này cho phép chúng tôi thoát khỏi bộ nhớ Redis ít hơn, chúng đóng vai trò là bản ghi dữ liệu hoạt động và chúng tôi sử dụng chúng nếu người dùng cần quay ngược thời gian để tìm thứ gì đó.
Đây không phải là một giải pháp thông minh hoặc đặc biệt thú vị nhưng nó đã phục vụ tôi rất tốt.