2

私は Heroku で Web サービスを実行しており、そのパフォーマンスを監視するために New Relic を使用しています。MySQL を Hibernate 上で使用しています。デフォルト以外の c3p0 設定は次のとおりです。

hibernate.c3p0.maxStatementsPerConnection, 5
hibernate.c3p0.maxPoolSize, 35
hibernate.c3p0.minPoolSize, 5
hibernate.c3p0.initialPoolSize, 10
hibernate.c3p0.acquireIncrement, 10

私の Web サービスへのすべてのリクエストは、データベースに少なくとも数回ヒットします。約 200 リクエスト/分の負荷テストを 10 分間実行した後、ほとんどの時間が費やされていることがわかりました。

com.mchange.v2.c3p0.impl.AbstractPoolBackedDataSource.getConnection

接続プールで接続を待っていると思いますか? 面白い部分は私が増加したようです

hibernate.c3p0.maxPoolSize, 40

パフォーマンスは悪化しました (同じ呼び出しでの待ち時間が長くなりましたgetConnection。テスト中に、MySQL サーバーで最大接続数が実際に開いていることがわかりc3p0ます (MySQL 側で設定された最大接続数は であり300、使い果たされていません)。

データベース関数はすべて同じ形式を使用しています

public void executeTransaction( Session session, IGenericQuery<T> query, T entity )
{
    Transaction tx = null;

    try
    {
        tx = session.beginTransaction();

        query.execute( session, entity );

        tx.commit();
    }
    catch ( RuntimeException e )
    {
        try
        {
            tx.rollback();
        }
        catch ( RuntimeException e2 )
        {
        }

        throw e;
    }
    finally
    {
        if ( session != null )
        {
            session.close();
        }
    }
}

したがって、すべてのセッションが閉じられていると確信しています。これは、接続の閉じにつながるはずです。接続の最大数を増やすと、待機時間が長くなるのはなぜですか? hibernate.c3p0.maxPoolSize, 25からまではパフォーマンスが向上しているように見えますが、をhibernate.c3p0.maxPoolSize, 30超えると低下しhibernate.c3p0.maxPoolSize, 35ます。私の価値観はかけ離れていますか?

ありがとう!

4

1 に答える 1

1

推測として、numHelperThreadsを増やしてみます。あなたは重荷を負っています。c3p0 の管理スレッドがバックアップされている可能性があります。(スタック トレースをダンプするか、JMX を使用して c3p0 を監視すると、これを確認できるはずです。ヘルパー スレッドが十分にある場合は、通常、idle()、wait() を実行する必要があります。それらがバックアップされている場合は、それらがほとんどアクティブで実行可能であることを確認し、JMX によってタスクがキューに入れられていることを確認できます。)

ヘルパー スレッドが不十分であることは、maxPoolSize で観察されたパフォーマンスの向上と低下と一致しています。最初は必要なものを取得し、準備ができている接続を増やしますが、ヘルパースレッドが追いつかず、接続を追加すると事態が悪化します。

あなたの設定を考えると、maxStatementsPerConnection が小さすぎる場合を除き、ヘルパー スレッドはあまり多くの作業を行うべきではありません。アプリに頻繁に実行される PreparedStatement が 5 つ以上ある場合は、Statement を大量に処理し、Statement close() タスクでヘルパー スレッドを結び付けることになります。この値を大きくしてみてください。これは、アプリケーションによって継続的に使用される個別の PreparedStatements の数とほぼ同じ (切り上げ) である必要があります。(セットアップやクリーンアップなどに関連する、単一の、またはほとんど使用されない PreparedStatement は無視できます。) ここでも、どのヘルパー スレッドが実行されているかを監視すると、これが問題であるかどうかについての情報が得られます。(バックアップされた Statement close() タスクが表示されます。)

したがって、試してみること: numHelperThreads を増やし、maxStatementsPerConnectionを増やします (またはゼロに設定して、Statement キャッシュを完全にオフにします)。

幸運を!

于 2013-08-26T05:55:43.280 に答える