2012-11-01 8 views
8

Tôi đang nghĩ đến việc sử dụng Redis cho mục đích ghi nhật ký ứng dụng web. Tôi googled rằng có những người sử dụng phương pháp này bằng cách bán phá giá các bản ghi vào một hàng đợi Redis/danh sách, và sau đó một công nhân dự kiến ​​để ghi vào đĩa.redis để đăng nhập

http://nosql.mypopescu.com/post/8652869828/another-redis-use-case-centralized-logging

Tôi muốn tìm hiểu rằng tại sao không trực tiếp sử dụng Redis để tồn tại vào đĩa? Nếu tôi đã phân bổ một máy chủ nhỏ mà Redis sẽ ghi vào, tách ra khỏi cơ sở dữ liệu, máy chủ ứng dụng, có khả thi để sử dụng Redis để duy trì các bản ghi trực tiếp không?

Tôi cũng cần trợ giúp khi truy vấn Redis theo datetime, user, v.v. Ví dụ: mỗi nhật ký như sau.

datetime=>2012-03-24 17:45:12 
userid=>123 
message=>test message 
category=>my category 

Làm cách nào để truy vấn kết quả trong phạm vi ngày giờ, bởi một người dùng cụ thể, thuộc một danh mục cụ thể?

Cảm ơn!

Trả lời

19

Bạn cần lưu ý rằng Redis là cơ sở dữ liệu trong bộ nhớ (ngay cả khi nó có thể lưu dữ liệu vào đĩa). Dữ liệu bạn đưa vào Redis phải phù hợp với bộ nhớ.

Đề xuất trong bài viết bạn đề cập đến là sử dụng Redis làm hệ thống xếp hàng phân phối. Quy trình công nhân khử các mục và ghi chúng vào đĩa, do đó không có nhiều mục trong bộ nhớ Redis. Thiết kế này có một lỗ hổng: nếu các quy trình công nhân không thể ghi dữ liệu đủ nhanh vào đĩa, Redis sẽ tiêu thụ bộ nhớ - vì vậy nó phải bị giới hạn bởi cấu hình (tham số tối đa Redmemory) hoặc phần mềm (cắt hàng đợi tại thời gian chèn hoặc trống hàng đợi khi nó đầy).

Bây giờ đề xuất của bạn không thực sự hoạt động vì tất cả dữ liệu bạn viết trong Redis sẽ được lưu trong bộ nhớ (ngay cả khi chúng được lưu vào đĩa bởi chính Redis).

Một điểm khác là bạn không thể truy vấn Redis. Redis không phải là một cơ sở dữ liệu quan hệ, nó hỗ trợ không có cơ chế truy vấn đặc biệt, chỉ các lệnh liên quan đến các đường dẫn truy cập đã được định nghĩa trước đó. Nếu bạn muốn tìm kiếm dữ liệu với các tham số khác nhau, bạn phải dự đoán tất cả các tìm kiếm có thể và xây dựng các cấu trúc dữ liệu có liên quan (tập hợp, sắp xếp tập hợp, vv ...) tại thời điểm chèn.

Một cửa hàng khác (MongoDB hoặc cơ sở dữ liệu quan hệ) có thể phù hợp hơn cho trường hợp sử dụng của bạn.

+0

Tôi chỉ xem một bản demo Redis. Peter Cooper nói rằng Redis đã được thiết kế/thực hiện để khai thác gỗ (ông gần đủ để nguồn có thẩm quyền). Vì vậy, trong khi bình luận của bạn là đủ, một số đọc bổ sung là bắt buộc. – Richard

+3

Redis được thiết kế để hỗ trợ lloogg (http://lloogg.com/). Nhưng dịch vụ lloogg không phải là về việc giữ mọi thứ trong bộ nhớ và sau đó xử lý các truy vấn. Đó là về lưu trữ/tổng hợp dữ liệu on-the-fly trong các cấu trúc dữ liệu phù hợp cho phép dễ dàng truy cập dữ liệu. Đây không phải là điều tương tự. –

1

Redis nằm trong kho dữ liệu bộ nhớ. Sự tồn tại lâu dài của dữ liệu vào đĩa là có thể với lệnh Save hoặc BGSAVE. Persistence (RDB/AOF) là một tính năng ngoài việc lưu trữ trong bộ nhớ.

Yêu cầu được đề cập là lưu trữ nhật ký vào đĩa. Việc sử dụng bất kỳ hàng đợi thư nào (như RabbitMQ) thay vì kho dữ liệu trong bộ nhớ sẽ làm cho mọi việc trở nên đơn giản. (nhật ký sẽ không ăn bộ nhớ)

Nhật ký tạo ứng dụng có thể xuất bản chúng trên hàng đợi và với người tiêu dùng riêng biệt tiêu thụ thông điệp tường trình và ghi chúng vào đĩa.

Tôi làm cách nào để truy vấn kết quả trong phạm vi ngày giờ, bởi một người dùng cụ thể, thuộc một danh mục cụ thể?

Mỗi khối log nên được lưu lại dưới dạng một cấu trúc (ví dụ cho C/C++) một cái gì đó như thế này:

struct log{ 
    long datatime; 
    string userId; 
    string message; 
    string category; 
    }; 

Serialize cấu trúc này để chuỗi và lưu nó trong Redis như giá trị. Các khóa cho các giá trị như vậy sẽ như sau: khóa = người dùngId + DELIMITER + danh mục + DELIMITER + datatime

Bạn có thể có chức năng lấy tất cả khóa và chia chúng để lấy danh sách dữ liệu cho từ khóa cụ thể của bạn.

+0

Có thể phát hành các truy vấn phạm vi (trên datetime) bằng cách sử dụng phương pháp này không? – Legend

7

Bạn có thể lưu trữ các bản ghi với cấu trúc sau:

"logs:{category}:{userid}:{datetime}" = message 

Và sau đó yêu cầu nó như sau:

"logs:*:{userid}:{datetime}" 

Hoặc

"logs:{category}:*:{datetime}"