1

私のソケット サーバーは 1 秒間に 5,000 を超えるパケットを受信し、データはデータベースに保存されます。

問題は、データベースへのデータの処理 (ストアド プロシージャの呼び出し、行の選択など) が、ソケットからデータを受信するよりも遅いことです。その結果、ソケットの受信バッファがオーバーしているため、ソケットはすべてのデータを受信できません。

簡単な例はここにあります。

do_something( char *buf, char *res ) {

/*
call some database stored procedures and get the result
this part makes bottle neck.
*/

}

recv_data( .. ) {

ながら(1) {

    n = epoll_wait( efd, events, EPOLL_SIZE, -1 );

    if( -1 == n ) {
        perror( "epoll wait error" );
    }

    for( i=0; i<n; i++ ) {
        if( events[i].data.fd == sfd ) {
           /* accept code */
        } else {
            memset( buf_in, 0x00, 256 );
            readn = read( events[i].data.fd, buf_in, 255  );
            if( readn <= 0 ) {
                /* close connection */
            } else {
                do_something( buf_in, result ); /* the function treats data into dbms */
                write( events[i].data.fd, res, 255 ); /* ack the result */
            }
        }
    }
}

}

私のクエストは

  1. 受信データとは別のスレッドでデータ処理部分を分離する必要がありますか?

  2. do_somthing 関数のパフォーマンスを向上させるだけですか?

4

1 に答える 1

2

対処すべき根本的な設計上の問題があるかもしれません。入ってくるデータは、処理できる速度よりも高速です。これがおそらく短期間の状況である場合は、do_something を 1 つ以上のスレッドに移動し、処理キューを作成するだけで十分な場合があります。ただし、「証明可能な」バックログを処理するのに十分なバッファ スペースがあることを確認してください。ただし、これが持続的な状況である場合は、別のスレッドに移動したり、巨大な処理キューを作成したりするだけでは十分ではありません (それでも必要ですが)。その場合、次のいずれかを行う必要があります

  1. フロー制御を使用して着信 torrent の速度を落とす/一時停止する
  2. 蓄積された do_something を、物事が入る可能性よりも速く発生させます

後者が可能である可能性は低いため、フロー制御が必要になる可能性があります。いくつかの特定の状況では、パケットをドロップする 3 番目のソリューションが利用可能であることに注意してください。これは、監視システムの設計などでよく発生します (たとえば)。

于 2013-11-14T04:18:32.940 に答える