2013-04-15 37 views
7

Tôi đã có một dự án nơi các cảm biến vật lý gửi dữ liệu đến máy chủ. Dữ liệu được gửi bất thường - sau khi một cái gì đó kích hoạt một cảm biến, nhưng không ít thường xuyên hơn mỗi 20 phút. Trên dữ liệu máy chủ được lưu trữ trong cơ sở dữ liệu Posgresql.Phân tích dữ liệu dựa trên thời gian với Python

cấu trúc dữ liệu trông giống như:

Sensor Table 
    sensor name - string 
    sensor serial no - string 
    sensor type - foreign key to types table 

Sensor Data Table 
    sensor - foreign key 
    timestamp 
    value 1 - boolean 
    value 2 - boolean 
    value 3 - integer 
    value 4 - float 
    ... 

Nó dự kiến ​​sẽ không quá tổng số 100 yêu cầu/giây. Hồ sơ dữ liệu trong cơ sở dữ liệu nên được lưu giữ trong 90 ngày và thậm chí nhiều hơn trong một số trường hợp (không chỉ 2 tuần như tôi đã nghĩ trước đó). Vì vậy, tổng số lượng hồ sơ sẽ không quá 120 960 000/14 ngày. Đây là ước lượng "an toàn". Trong thực tế nó có thể là 10 lần ít hơn (10 req/giây, 12 960 000 hồ sơ).

tôi cần phải làm một số phân tích về dữ liệu, như:

  1. Do something khi một kỷ lục mới đến và đó là "giá trị 2" là đúng
  2. Do something khi "giá trị 2" cảm biến X là đúng hơn thời gian khai báo lâu hơn (50 phút, 1 giờ hoặc nhiều lần khác)
  3. Làm điều gì đó khi tổng thời gian thực của X cho "giá trị 2" trong 24 giờ là nhiều hơn thời gian đã khai báo
  4. Làm điều gì đó khi cảm biến "Giá trị 3" của X là đúng lâu hơn một số thời gian đã khai báo và không có cảm biến nào khác của loại XYZ đã hoạt động trong khoảng thời gian này ...

"Thời gian đã khai báo" ở trên lớn hơn hoặc bằng 1 giây.

Toàn bộ phần máy chủ được phát triển ở Django (và django-rest-framework để thu thập dữ liệu).

Các câu hỏi là làm thế nào để phân tích dữ liệu hiệu quả, giả sử rằng phải có thời gian thực hoặc gần với thời gian thực (1 giây) theo dõi dữ liệu và khoảng thời gian để kích hoạt hành động mong muốn.

những suy nghĩ của tôi:

  1. Chạy quá trình đó sẽ truy vấn cơ sở dữ liệu mỗi giây cho các hồ sơ đáp ứng tiêu chí và gọi hành động cụ thể (nó có lẽ sẽ phải mất hơn 1 giây)

  2. Run số riêng quy trình (eventlet?) một cho mỗi loại phân tích và sau đó truy vấn cơ sở dữ liệu sau mỗi 1 giây và kích hoạt các hành động cụ thể.

  3. Chạy một quy trình cho mỗi bộ cảm biến liên tục báo cáo cho người đăng ký: Tôi là đúng trên "giá trị 2" dài hơn x giây, vv .. Quá trình được đặt lại sau khi dữ liệu mới cho cảm biến đó đến. Một số giải pháp đăng ký xuất bản như zeromq có thể được sử dụng ở đây?

  4. Sử dụng một số khác/giải pháp nhanh hơn

    • MongoDB - vấn đề có thể là file của MongoDB mà không phải là đầm sau khi số liệu được lấy ra (2 tuần).
    • Hadoop - không quá lớn và quá phức tạp đối với loại sự cố này?
    • Pandas và một số lưu trữ HDF5 - vấn đề có thể là liệu nó có khả năng thực hiện phân tích mà tôi đã mô tả ở trên và có lẽ cũng có thể ghi vào tệp. Nhưng .. có thể làm việc với mongo quá.

Gợi ý?

Cập nhật.

Hiện nay các giải pháp mà có vẻ là đơn giản và hiệu quả với tôi là:

  1. sau khi dữ liệu đến trên cảm biến Một chạy tất cả các xét nghiệm và
  2. kết quả cửa hàng thử nghiệm ở một số "bài kiểm tra" bảng (hoặc redis) trong một cách mà nói: "còn cảm biến mở hơn"
    • today at 1:15 chạy action
    • today at 1:30 chạy action "cảm biến mở lâu hơn trong giai đoạn 24h" ...
  3. liên tục quét bảng "kiểm tra" ở trên và khi ngày hôm nay 1:15 chiều, sau đó chạy hành động mong muốn, v.v.
  4. khi tín hiệu mới đến cảm biến A sau đó chạy lại tất cả thử nghiệm và cũng đặt lại dữ liệu "kiểm tra" bảng.

Điều này đòi hỏi tôi phải thử nghiệm mỗi khi có yêu cầu đến một cảm biến cụ thể, nhưng ở phía bên kia tôi sẽ chỉ quét bảng "kiểm tra", cứ sau 1 giây.

Cập nhật PyTables 2

tôi đã phát hiện ra (http://www.pytables.org/moin/PyTables), trông nó khá thích hợp cho trường hợp sử dụng của tôi như là một lưu trữ dữ liệu.

Trả lời

2

đâm đầu tiên của tôi ở đây sẽ là để tạo ra một chỉ số nhiều cột trên "Sensor Data Table", của những thứ tương tự:

sensor->timestamp->value1 //Index 1 
sensor->timestamp->value2 //Index 2 
sensor->timestamp->value3 //Index 3 
sensor->timestamp->value4 //Index 4 

Xem nếu truy vấn SQL của bạn là đủ nhanh. Bạn có thể truy vấn nó thông qua eventlets hoặc cron. Từ góc độ hiệu suất, việc bạn sử dụng truy vấn này đủ nhanh đến mức nào cũng không quan trọng, rất có thể đó là nút cổ chai của bạn.

Một đề xuất khác là thử các bảng bộ nhớ MySQL, hoặc số lượng bài đăng tương đương (In-memory table in PostgreSQL).

Một đề xuất khác là thử Redis. Bạn có thể lưu trữ "Dữ liệu cảm biến" dưới dạng tập hợp các bộ được sắp xếp; Một bộ được sắp xếp cho mỗi trường id và giá trị cảm biến và sắp xếp dữ liệu theo dấu thời gian.

ZADD sensor_id:value1 timestamp value 
ZADD sensor_id:value2 timestamp value 

Redis sẽ yêu cầu một số logic ứng dụng để tích lũy dữ liệu, nhưng sẽ rất nhanh nếu nó phù hợp với RAM.

Re: MongoDB. Bạn có thể nhận được sự hoàn hảo tốt. miễn là dữ liệu có thể truy vấn của bạn + chỉ mục có thể vừa với RAM và không có quá nhiều khóa ghi. Mặc dù đó là một gánh nặng hành chính (và mã hóa) để chạy 2 cơ sở dữ liệu có trọng lượng nặng cung cấp các tính năng chồng chéo. Cho rằng, nén chặt không thực sự là một vấn đề. Bạn có thể tạo chỉ mục TTL trên dữ liệu cảm biến và mongo sẽ xóa dữ liệu cũ hơn trong chuỗi bg. Kích thước tệp sẽ vẫn không đổi sau một thời gian.

Hope this helps

+0

Cảm ơn, đây là những giải pháp thực sự có giá trị. Tôi sẽ đi với sql đầu tiên và xem nó nhanh như thế nào. – eXt

+0

Quá nhanh với nhận xét trước, vì vậy: Tôi sẽ đi với sql đầu tiên và xem nhanh như thế nào. Các bảng trong bộ nhớ sẽ nhanh nhưng tôi phải lưu giữ dữ liệu. Redis ... thú vị nhưng tôi không chắc liệu nó có phù hợp với: 1. lưu trữ quá nhiều dữ liệu ở đó (nó phải được duy trì) 2. lọc dữ liệu này, ví dụ tôi phải tính tổng thời gian của bất hoạt trong 24 giờ (tôi cũng thực hiện một số phân tích khác về dữ liệu thu thập được, nhưng điều này không xảy ra thường xuyên) Mongo. Sẽ 100 req/giây là enought gây ra viết khóa? Tôi có lẽ sẽ phải kiểm tra nhanh như thế nào mongo và so sánh nó với kết quả từ sql db. – eXt

+0

Siêu! Vui mừng bạn đánh giá cao nó. Redis, không giống như Memcache, lưu trữ dữ liệu liên tục. Nó lưu trữ nhiều như nó có thể trong RAM và các trang vào/ra khi cần. Cho rằng, có vẻ như với tôi yêu cầu của bạn là phù hợp hơn cho SQL. Re: Mongo. # của Reqs. không có gì để làm với ổ khóa. Mongo rất tuyệt vời ở chế độ chỉ đọc, chỉ ghi tốt, không tốt với đọc-ghi vì viết khóa chặn toàn bộ cơ sở dữ liệu (không có lần đọc/ghi nào khác có thể xảy ra) vì vậy viết quá nhiều sẽ khiến bạn mất thời gian chờ. Nếu dữ liệu của bạn + chỉ mục phù hợp với RAM, nó sẽ dễ chịu. Như bạn đã nói, bạn sẽ chỉ biết nếu bạn cố gắng. – Adil

0

Nếu quy tắc của bạn rất đơn giản hoặc vài bạn có thể thử và sử dụng SQL gây nên để cập nhật quan điểm lưu trữ, mà có thể được nhanh chóng truy vấn. Ví dụ.giả sử, mà bạn muốn phát hiện, rằng một bộ cảm biến nào đó đã hoạt động trong một khoảng thời gian nhất định, bạn có thể có một bảng chứa thời gian kích hoạt các cảm biến đang hoạt động hiện tại. Bất cứ khi nào bạn lưu trữ một sự kiện thô, trình kích hoạt sẽ cập nhật một bảng như vậy.

Sẽ khó khăn hơn đối với các quy tắc loại 3. Trừ khi có một vài quy tắc trong số đó và bạn có thể thiết lập bộ kích hoạt và chế độ xem cho từng chế độ hoặc khoảng thời gian được cho trước.

0

Tùy chọn # 4. Cơ sở dữ liệu quan hệ là nút cổ chai rõ ràng. Sắp xếp để phân phối dữ liệu dưới dạng đơn giản hơn (các tệp trong thư mục, được đặt tên theo tên cảm biến hoặc bất kỳ khóa duy nhất nào). Bạn có thể xử lý nhanh hơn nhiều, kiểm tra dấu thời gian và đọc - sau đó đẩy dữ liệu đến rdb ở cuối, sau khi bạn phân tích.

+0

Tôi không thể mong đợi các tệp có chứa dữ liệu từ cả ngày. Dữ liệu được liên tục gửi đến máy chủ. Vì vậy, tôi phải nhận nó và tiết kiệm. Ngoài ra tôi không thể nói rằng tôi sẽ không phải phân tích lại dữ liệu này - ví dụ như khi truy vấn theo dõi mới được tạo, như: bây giờ tôi muốn được thông báo khi cảm biến mở hơn một tuần. Vì vậy, hệ thống của tôi phải phân tích dữ liệu cũ như 1 tuần) – eXt

0

Bạn có nghĩ về việc bị vướng phải bởi sự cố và luồng xử lý dữ liệu đầu vào không?

Một cách tiếp cận mẫu thuộc loại này sẽ là:

for event in new_events: # new events to be written from the RESTful service 
    for test in tests: # known tests you need to perform 
     increment/decrement <test.bucket>.<sensor>.<valueX> # update the bucket as necessary 
     # e.g. seconds_since_changed.sensor1.value3 += 1 
    # additionally, save each record to a standard database for long-term purposes 
    # and to be able to rebuild/redo tests as necessary. 

Cơ chế lưu trữ lý tưởng cho một dòng giao dịch như vậy là một trong đó cho vay cũng chính nó để độ trễ thấp viết/cập nhật. Các giải pháp NoSQL hoạt động rất tốt cho loại công việc này (cá nhân tôi đã sử dụng Redis cho một loại phân tích tương tự, nhưng bạn không bị ràng buộc vào giải pháp cụ thể đó.)

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