Проблема производительности торнадо с MySQL и Redis - PullRequest
0 голосов
/ 22 мая 2018

У меня есть сервер торнадо, работающий с MySQL для БД и Redis для кеша.Я использую веб-сокет для отправки / получения данных.Мой код выглядит так:

Сервер

import logging
import os.path
import uuid
import sys
import json

import tornadis
import tormysql
import tornado.escape
import tornado.ioloop
import tornado.options
import tornado.web
import tornado.websocket
from tornado import gen
from tornado.concurrent import Future
from tornado.options import define, options

@gen.coroutine
def getFromDB(query):
    with (yield dbPool.Connection()) as conn:
        with conn.cursor() as cursor:
            yield cursor.execute(query)
            datas = cursor.fetchall()
            return datas
    return None

@gen.coroutine
def getFromCache(cmd):
    pipeline = tornadis.Pipeline()
    pipeline.stack_call(cmd)
    with (yield cachePool.connected_client()) as singleClient:
        redisResult = yield singleClient.call(pipeline)
        if isinstance(redisResult, tornadis.TornadisException):
            print("Redis exception: %s"%(redisResult))
        else:
            return redisResult

async def getData(dbQuery, cacheQuery):
    waitDict = {}
    if dbQuery:
        waitDict['db'] = getFromDB(dbQuery)
    if cacheQuery:
        waitDict['cache'] = getFromCache(cacheQuery)
    resultList = []
    if len(waitDict) > 0:
        await gen.multi(waitDict)
        if 'db' in waitDict:
            dbRes = waitDict['db'].result()
            if dbRes:
                for eachResult in dbRes:
                    changeRes = someFunct(eachResult) 
                    resultList.append(changeRes)
        if 'cache' in waitDict:
            cacheRes = waitDict['cache'].result()
            if cacheRes:
                for eachResult in cacheRes:
                    changeRes = someFunct(eachResult) 
                    resultList.append(changeRes)
    return resultList

class SocketHandler(tornado.websocket.WebSocketHandler):
    SUPPORTED_METHODS = ("GET")

    def open(self):
        print("Socket open:%s"%(self))

    def on_close(self):
        print("Socket closed:%s"%(self))

    async def on_message(self, inp):
        if requestForData:
            ret = await getData(dbQuery, cacheQuery)
            self.write_message(ret)

class Application(tornado.web.Application):
    def __init__(self):
        handlers = [
            (r"/sock", SocketHandler),
        ]

define("port", default=8000, help="run on the given port", type=int)
tornado.options.parse_command_line()
app = Application()
app.listen(options.port)
print("PORT:%s"%(options.port))
tornado.ioloop.IOLoop.current().start()

Я использую tornadis для Redis и tormysql для MySQL.
Я запускаю эту настройку на экземпляре amazon linux m5.large с памятью 2vCPU: 8Gib.

Клиент

Я пытаюсь смоделироватьтрафик с использованием веб-сокета.Код выглядит так:

import sys
import json
import asyncio
import websockets

def getData():
    for i in range(100):
        async with websockets.connect(SOCKET_URL, extra_headers=extraHeaders) as websocket:
            for i an range(100):
                await websocket.send("get data")
                reply = await websocket.recv()
                print(reply)

asyncio.get_event_loop().run_until_complete(getData())

Я использую несколько экземпляров клиента.
Сервер работает нормально, но способен обрабатывать только 25 соединений.После 25 соединений задержка ответа от сервера увеличивается.Я хочу, чтобы сервер отвечал очень быстро.Как уменьшить задержку ответа?Так есть ли проблема в коде?

...