2011-10-21 4 views
3

토네이도 및 파이썬 스레드에 익숙하지 않습니다. 내가 성취하고자하는 것은 다음과 같습니다. 사용자로부터 요청을받는 토네이도 웹 서버가 있습니다. 일부 데이터를 로컬에 저장하고 정기적으로 대량 삽입으로 데이터베이스에 쓰기를 원합니다.토네이도 웹 및 스레드

import tornado.ioloop 
import tornado.web 
import threading 

# Keep userData locally in memory 
UserData = {} 

def background(f): 
    """ 
    a threading decorator 
    use @background above the function you want to thread 
    (run in the background) 
    """ 
    def bg_f(*a, **kw): 
     threading.Thread(target=f, args=a, kwargs=kw).start() 
    return bg_f 

@background 
def PostRecentDataToDBThread(iter = -1): 
    i = 0 
    while iter == -1 or i < iter: 
     #send data to DB 
     UserData = {} 
     time.sleep(5*60) 
     i = i + 1 

class AddHandler(tornado.web.RequestHandler): 
    def post(self): 
     userID = self.get_argument('ui') 
     Data = self.get_argument('data') 

     UserData[userID] = Data 


if __name__ == "__main__": 
    tornado.options.parse_command_line() 

    print("start PostRecentDataToDBThread") 
    ### Here we start a thread that periodically sends data to the data base. 
    ### The thread is called every 5min. 
    PostRecentDataToDBThread(-1) 

    print("Started tornado on port: %d" % options.port) 

    application = tornado.web.Application([ 
     (r"/", MainHandler), 
     (r"/add", AddHandler) 
    ]) 
    application.listen(options.port) 
    tornado.ioloop.IOLoop.instance().start() 

내 목표를 달성하는 좋은 방법입니까? 서버 차단 시간을 최소화하고 싶습니다. 또는 나는 gevent 또는 다른 것을 사용해야합니까? Tornado와 스레드 모두에서 UserData에 액세스하여 문제가 발생할 수 있습니까? 서버 충돌이없는 한 여기서는 데이터 일관성이 중요하지 않습니다.

답변

6

토네이도는 멀티 스레딩과 함께 사용되지 않습니다. epoll을 기반으로 코드의 다른 부분 사이에서 컨텍스트를 전환합니다.

일반적으로 메시지 큐 (예 : pika + RabbitMQ)를 통해 작업자 프로세스에 데이터를 보내는 것이 좋습니다 (토네이도와 잘 통합됩니다). 작업자 프로세스는 메시지로 데이터를 누적하여 데이터베이스에 일괄 적으로 쓰거나이 설정으로 다른 모든 데이터 처리 논리를 구현할 수 있습니다.

또는 예를 들어 brukva의 Redis를 사용하여 들어오는 데이터를 메모리 내장 데이터베이스에 비동기 적으로 쓰기 만하면 Redis 구성에 따라 디스크에 비동기 적으로 덤프됩니다.

관련 문제