一回tornado QPS最適化を記す
4234 ワード
この記事は個人ブログに最初に発表されました:Pylixm'Wiki
プロジェクトのニーズに応じてtornadoを用いてapiシステムを開発し,システム開発が完了した後,8コア16 Gのダミーマシン上で圧力測定qpsを経て200+しかなかった.我々が初期に定めたQPSが2 kより大きいと1桁差があり,長い最適化の道が始まった.最適化の過程で、多くのことを学び、記録を整理して調べる必要がある.
デルのテクノロジー選択: python2.7 tornado4.4.3 sqlalchemy1.1.5 mysql5.6 rabbitmq
当初技術が型を選ぶ時tornadoを選んで、その優秀な性能のためで、こんなに低いQPSは自然に悔しいです.果たしてtornadoはどのくらいのQPSに達することができるのだろうか.そこで簡単なhello worldを作成し、上の仮想マシンの中で16のプロセスの下で、ab圧測QPSを使って驚くべき6 Kに達し、平均応答時間はミリ秒級だった.これでapiのQPSを最適化し続ける自信があります.
初歩的な分析
QPSを向上させるには、2つの側面から着手することができ、1つは同時数を増加させることであり、2つは平均応答時間を減少させることである.現在の状況から見ると,プロセスの同時数を増やすことが最も直接的な手段であるが,機械資源のボトルネックに達すると,確実に機械を積み重ねて解決する.比較すると,平均応答を低減することがより重要である.我々が開発したapiを初歩的に解析し,平均応答時間は数百ミリ秒レベルであった.ほとんどの時間はシステムとデータベースのインタラクションに費やされ、これにより、平均応答時間を最大限に低減する最適化されたテーマ構想が得られます.
私たちのAPIが完成した機能は、要求パラメータを受け入れていくつかの列の認証判断(データベースとインタラクティブ)を行い、メッセージをrabbitmqにブロードキャスト形式で消費者に送信し、最後にクライアントに結果を送信することです.この論理によると、応答時間に影響する箇所は、以下のように分析される. mysqlデータベースとのインタラクション rabbitmqを使用してメッセージをブロードキャストする場合の時間消費量 消費時間のトラフィック論理コードフラグメント 構想の最適化
上記の問題に基づいて、以下のいくつかの面から着手します. tornadoの非同期特性 を増加するデータベースとのインタラクションを分析し、データベースとのインタラクション時間を減らす rabbitmqを解析する時間の消費量を低減し、情報送信時間 を低減する.最適化ビジネスコードロジック 具体的な実施
tornadoの非同期特性
apiを開発する際,tornadoの非同期特性にあまり詳しくないため,使用しなかった.その後、テストが進むにつれて、使用する必要があることに気づき、理解し始めました.理解が深まるにつれて、tornadoはデータベースの非同期特性をよくサポートしていないことがわかり、より多くはネットワークに対する非同期であり、公式サイトにも「ネットワーク非ブロックフレームワーク」と書かれている.公式ドキュメントを調べ、tornadoの非同期実現は、公式ドキュメントの総じて言えば、プログラムを非同期にする方法は3種類あり、ここを参考にする.第1種は、tornadoのgen.coruntineを使用する. の2つ目は、tornadoのスレッドモジュールを使用します. の3つ目は、外部キューを使用して、workerプロセスまたはスレッドを個別に処理します.例えば、celeryなどです.
非同期特性の増加に加えて著しく向上した.
mysqlデータベースの最適化
データベースは便利で、SQLAlchemyに適しています.ORMを使用すると、裸のsqlによるクエリーの複雑さを減らすと同時に、クエリー・データベースの消費時間が必然的に増加します.私たちもテストをしたことがあります.pymsqlリンクmysqlを使用して、裸のsqlクエリーを直接使用することと、sqlalcemyを使用するオブジェクトクエリーの時間の違いは7、8ミリ秒で、sqlalchemyの裸のsql方式の実行時間とほぼ一致しています.sqlalchemyのorm方式は一定の時間損失があることがわかる.stackoverflowの1つの問題、私の考えも検証して、Why is loading SQLAlchemy objects via the ORM 5-8 x slower than rows via a raw MySQLdb cursorを見ますか?
データベースについて、次の最適化を行いました. SQLAlchemyクエリをコアヌードsql方式に変更するには、ここを参照してください. データベースを最適化し、必要なインデックスを追加します. 論理のフィルタ条件をできるだけsqlに移動し、sql結果セットのサイズを減らし、クエリーの速度を速める. 単語検索可能なデータセットを1回のクエリーに配置し、データベースへのリンク回数を減らす.
rabbitmqを分析する時間の消費量を減らし、情報送信時間を減らす
rabbitmqでは,pikaをドライバライブラリとして接続し,データを送信するたびにリンクとチャネルを作成し,送信が完了するとすぐにリンクを閉じる.長いリンクを使用できるかどうかを考慮して、リンクを作成して閉じずにchannelだけを閉じます.修正後、エラーが発生しました.具体的なコードは以下の通りです.
補足エラー材料分析-todo
pikaのドキュメントをめくると、非同期の使用方法があり、tornandoフレームワークと結合した例があります.ドキュメントを参照してください.pikaの非同期方式は,tornadoと同じepullベースのイベントループモデルを用いて,tornadoのIOloopとどのように結合するかが問題であり,tornadoのリンクアダプタがあり,そのコードをめくってもどのように使用するかは不明であり,時間があるときに検討を続ける.
rabbitmqの最適化についてはあきらめたが、最適化の過程で分析に値する文章がいくつかあり、以下のように整理された. rabbitmq-amqp-channel-best-practices rabbitmq-best-practices-for-designing-exchanges-queues-and-bindings tornadoとpikaの結合例 ビジネスコードロジックの最適化
コードロジックの最適化は、次のように便利です.減少サイクル reviewロジック、冗長ロジック を除去共通変数を抽出し、1回付与し、クエリー・データベースを削減します.
まとめ
以上の最適化を経て,我々のapiのQPSは1200+に向上し,時間の問題のため,継続的な最適化を一時停止した.今回のQPSの最適化過程を通じて、いくつかの悟りがある.新しい技術を使用する場合は、必ず公式文書をよく読んで、よく知ってから使用してください. 公認の「技術の真理」を簡単に否定しないで、データを持って話してください.
個人の仕事の総括、伝言の交流を歓迎します!
プロジェクトのニーズに応じてtornadoを用いてapiシステムを開発し,システム開発が完了した後,8コア16 Gのダミーマシン上で圧力測定qpsを経て200+しかなかった.我々が初期に定めたQPSが2 kより大きいと1桁差があり,長い最適化の道が始まった.最適化の過程で、多くのことを学び、記録を整理して調べる必要がある.
デルのテクノロジー選択:
当初技術が型を選ぶ時tornadoを選んで、その優秀な性能のためで、こんなに低いQPSは自然に悔しいです.果たしてtornadoはどのくらいのQPSに達することができるのだろうか.そこで簡単なhello worldを作成し、上の仮想マシンの中で16のプロセスの下で、ab圧測QPSを使って驚くべき6 Kに達し、平均応答時間はミリ秒級だった.これでapiのQPSを最適化し続ける自信があります.
初歩的な分析
QPSを向上させるには、2つの側面から着手することができ、1つは同時数を増加させることであり、2つは平均応答時間を減少させることである.現在の状況から見ると,プロセスの同時数を増やすことが最も直接的な手段であるが,機械資源のボトルネックに達すると,確実に機械を積み重ねて解決する.比較すると,平均応答を低減することがより重要である.我々が開発したapiを初歩的に解析し,平均応答時間は数百ミリ秒レベルであった.ほとんどの時間はシステムとデータベースのインタラクションに費やされ、これにより、平均応答時間を最大限に低減する最適化されたテーマ構想が得られます.
私たちのAPIが完成した機能は、要求パラメータを受け入れていくつかの列の認証判断(データベースとインタラクティブ)を行い、メッセージをrabbitmqにブロードキャスト形式で消費者に送信し、最後にクライアントに結果を送信することです.この論理によると、応答時間に影響する箇所は、以下のように分析される.
上記の問題に基づいて、以下のいくつかの面から着手します.
tornadoの非同期特性
apiを開発する際,tornadoの非同期特性にあまり詳しくないため,使用しなかった.その後、テストが進むにつれて、使用する必要があることに気づき、理解し始めました.理解が深まるにつれて、tornadoはデータベースの非同期特性をよくサポートしていないことがわかり、より多くはネットワークに対する非同期であり、公式サイトにも「ネットワーク非ブロックフレームワーク」と書かれている.公式ドキュメントを調べ、tornadoの非同期実現は、公式ドキュメントの総じて言えば、プログラムを非同期にする方法は3種類あり、ここを参考にする.
, , mysql python , 。
, , , , 。
, 。
, , 。
非同期特性の増加に加えて著しく向上した.
mysqlデータベースの最適化
データベースは便利で、SQLAlchemyに適しています.ORMを使用すると、裸のsqlによるクエリーの複雑さを減らすと同時に、クエリー・データベースの消費時間が必然的に増加します.私たちもテストをしたことがあります.pymsqlリンクmysqlを使用して、裸のsqlクエリーを直接使用することと、sqlalcemyを使用するオブジェクトクエリーの時間の違いは7、8ミリ秒で、sqlalchemyの裸のsql方式の実行時間とほぼ一致しています.sqlalchemyのorm方式は一定の時間損失があることがわかる.stackoverflowの1つの問題、私の考えも検証して、Why is loading SQLAlchemy objects via the ORM 5-8 x slower than rows via a raw MySQLdb cursorを見ますか?
データベースについて、次の最適化を行いました.
rabbitmqを分析する時間の消費量を減らし、情報送信時間を減らす
rabbitmqでは,pikaをドライバライブラリとして接続し,データを送信するたびにリンクとチャネルを作成し,送信が完了するとすぐにリンクを閉じる.長いリンクを使用できるかどうかを考慮して、リンクを作成して閉じずにchannelだけを閉じます.修正後、エラーが発生しました.具体的なコードは以下の通りです.
# -*- coding:utf-8 -*-
import pika
from settings import settings
class Client(object):
def __init__(self, host, port, username, pwd):
self.host = host
self.port = port
self.username = username
self.pwd = pwd
self.init_connection()
def init_connection(self):
user_pwd = pika.PlainCredentials(self.username, self.pwd)
self.connection = pika.BlockingConnection(pika.ConnectionParameters(
host=self.host, port=self.port, credentials=user_pwd))
# ...
補足エラー材料分析-todo
pikaのドキュメントをめくると、非同期の使用方法があり、tornandoフレームワークと結合した例があります.ドキュメントを参照してください.pikaの非同期方式は,tornadoと同じepullベースのイベントループモデルを用いて,tornadoのIOloopとどのように結合するかが問題であり,tornadoのリンクアダプタがあり,そのコードをめくってもどのように使用するかは不明であり,時間があるときに検討を続ける.
rabbitmqの最適化についてはあきらめたが、最適化の過程で分析に値する文章がいくつかあり、以下のように整理された.
コードロジックの最適化は、次のように便利です.
まとめ
以上の最適化を経て,我々のapiのQPSは1200+に向上し,時間の問題のため,継続的な最適化を一時停止した.今回のQPSの最適化過程を通じて、いくつかの悟りがある.
個人の仕事の総括、伝言の交流を歓迎します!