2012-05-25 23 views
10

Tôi đang làm việc trên một nhà cung cấp phụ trợ/API web lấy dữ liệu thời gian thực từ API của bên thứ ba, đặt nó trong cơ sở dữ liệu MySQL và cung cấp nó trên API HTTP/JSON.Eventlet/chung async I/O nhiệm vụ chi tiết

Tôi đang cung cấp API với bình và làm việc với DB bằng SQLAlchemy Core.

Đối với phần lấy dữ liệu thời gian thực, tôi có các hàm bao bọc API của bên thứ ba bằng cách gửi một yêu cầu, phân tích cú pháp xml được trả về thành dict Python và trả về nó. Chúng tôi sẽ gọi các trình bao bọc API này.

Sau đó tôi gọi các hàm này trong các phương thức khác lấy dữ liệu tương ứng, thực hiện bất kỳ xử lý nào nếu cần (như chuyển đổi múi giờ, v.v.) và đặt trong DB. Chúng tôi sẽ gọi những bộ vi xử lý này.

Tôi đã đọc về I/O và eventlet không đồng bộ một cách cụ thể và tôi rất ấn tượng.

tôi sẽ kết hợp nó trong dữ liệu của tôi lấy mã, nhưng tôi có một số câu hỏi đầu tiên:

  1. là nó an toàn cho tôi để khỉ vá tất cả mọi thứ? xem xét tôi có bình, SQLAlchemy và một loạt các libs khác, có bất kỳ nhược điểm để khỉ vá (giả sử không có ràng buộc muộn)?

  2. Tính chi tiết tôi nên chia nhiệm vụ của mình là gì? Tôi đã nghĩ đến việc tạo ra một hồ bơi định kỳ sinh ra các bộ vi xử lý. Sau đó, khi bộ xử lý đạt đến phần mà nó gọi trình bao bọc API, trình bao bọc API sẽ bắt đầu một GreenPile để nhận dữ liệu HTTP thực tế bằng eventlet.green.urllib2. Đây có phải là một cách tiếp cận tốt?

  3. Hết thời gian chờ - Tôi muốn đảm bảo không có phần greenthread nào bị treo. Nó là một cách tiếp cận tốt để thiết lập eventlet.Timeout 10-15 giây cho mỗi greenthread?

FYI, tôi có khoảng 10 bộ dữ liệu thời gian thực khác nhau và bộ xử lý được sinh ra sau mỗi 5-10 giây.

Cảm ơn!

Trả lời

3

Tôi không nghĩ rằng nên kết hợp Flask/SQLAlchemy với mô hình lập trình kiểu không đồng bộ (hoặc sự kiện điều khiển). Tuy nhiên, vì bạn nói rằng bạn đang sử dụng RDBMS (MySQL) làm lưu trữ trung gian, tại sao bạn không chỉ tạo công nhân không đồng bộ lưu trữ kết quả từ các dịch vụ web của bên thứ ba trong RDMBS và giữ lối vào của bạn (Flask)./SQLAlchemy) đồng bộ?

Trong trường hợp đó bạn không cần phải monkeypatch Flask hoặc SQLAlchemy.

Về mức độ chi tiết, bạn có thể muốn sử dụng mô hình mapreduce để thực hiện các cuộc gọi và xử lý API web. Mẫu này có thể cung cấp cho bạn một số ý tưởng về cách phân tách một cách hợp lý các bước liên tiếp và cách kiểm soát các quy trình liên quan.

Cá nhân, tôi sẽ không sử dụng khung không đồng bộ để thực hiện việc này. Có thể tốt hơn nếu sử dụng đa xử lý, Celery hoặc một loại hệ thống bản đồ hóa thực sự như Hadoop.

Chỉ cần gợi ý: bắt đầu nhỏ, giữ cho nó đơn giản và mô-đun và tối ưu hóa sau nếu bạn yêu cầu hiệu suất tốt hơn. Điều này cũng có thể bị ảnh hưởng nhiều bởi thời gian thực bạn muốn thông tin.

+0

cảm ơn nhận xét của bạn. Tôi đồng ý liên quan đến việc không trộn Flask và Async I/O - nó không được rõ ràng từ câu hỏi của tôi, nhưng API (Flask) chạy trên một quá trình I/O không đồng bộ, không được vá riêng biệt. Trình thu thập dữ liệu chạy trên một quá trình được vá, ghi vào db bằng cách sử dụng SQLAlchemy Core (không phải ORM) chỉ nhằm mục đích đơn giản hóa. – user1094786

+0

OK, trong trường hợp đó bạn đã thực hiện nó theo cách này. Tôi tự hỏi, mặc dù nếu bạn thực sự cần async cho grabber dữ liệu. Bạn có thể được tốt hơn với các phương pháp khác của đồng thời (đa xử lý, Celery, vv), đặc biệt là nếu grabber dữ liệu của bạn là CPU chuyên sâu. –

+0

+1 cho cần tây. Nhiệm vụ trông giống như một ứng cử viên tốt cho nó. – Tisho

-1

Đó là an toàn để vá một mô-đun được viết bởi python tinh khiết và sử dụng lib tiêu chuẩn.

  • có rất ít tinh khiết mysql adapter:
  • PyMysql có một bộ kiểm tra SQLAlchemy, bạn có thể chạy thử nghiệm đối với trường hợp của bạn.
  • Có một mô-đun có tên pymysql_sa để cung cấp phương ngữ cho sqlalchemy
  • Bình được viết bằng python tinh khiết và 100% WSGI 1.0 tuân thủ. sử dụng eventlet.wsgi để cung cấp dịch vụ.

Chia các tác vụ bằng tìm nạp đơn bằng mô-đun màu xanh lá cây như bạn có thể. Đặt các công việc vào hàng đợi, cũng được cung cấp bởi eventlet, mỗi công nhân nhiệm vụ lấy một công việc từ hàng đợi, sau đó lưu kết quả vào db sau khi tìm nạp xong hoặc gửi đến một đối tượng event.Event để kích hoạt công việc chờ đợi nhiệm vụ kết thúc. Hoặc, cả hai quá trình.

CẬP NHẬT:

Các tài liệu chính thức eventlet khuyên sử dụng các bản vá tại dòng nắm tay của các mô-đun chính, và nó an toàn để gọi monkey_patch nhiều lần. Đọc thêm trên trang http://eventlet.net/doc/patching.html

Có một số mô-đun màu xanh lá cây có thể làm việc với eventlet, tất cả chúng đều có trong eventlet.green. Một danh sách trên bitbucket. Đảm bảo sử dụng mô-đun màu xanh lục trong mã của bạn hoặc vá chúng trước khi nhập mô-đun thứ 3 sử dụng lib chuẩn.

Nhưng khỉ_patch chỉ chấp nhận vài mô-đun, cần nhập thủ công mô-đun màu xanh lá cây.

def monkey_patch(**on): 
    """Globally patches certain system modules to be greenthread-friendly. 

    The keyword arguments afford some control over which modules are patched. 
    If no keyword arguments are supplied, all possible modules are patched. 
    If keywords are set to True, only the specified modules are patched. E.g., 
    ``monkey_patch(socket=True, select=True)`` patches only the select and 
    socket modules. Most arguments patch the single module of the same name 
    (os, time, select). The exceptions are socket, which also patches the ssl 
    module if present; and thread, which patches thread, threading, and Queue. 

    It's safe to call monkey_patch multiple times. 
    """  
    accepted_args = set(('os', 'select', 'socket', 
         'thread', 'time', 'psycopg', 'MySQLdb')) 
    default_on = on.pop("all",None)
Các vấn đề liên quan