3

ソケット サーバー エンジンとして Twisted 8.1.0 を使用しています。リアクター - epoll。データベース サーバーは MySQL 5.0.67 です。OS - Ubuntu Linux 8.10 32 ビット

/etc/mysql/my.cnf:

max_connections        = 1000

ソースコード:

adbapi.ConnectionPool("MySQLdb", ..., use_unicode=True, charset='utf8', 
                      cp_min=3, cp_max=700, cp_noisy=False)

SHOW PROCESSLISTしかし実際には、アプリケーションが高負荷で実行されている場合、200 (またはそれ以下) の開いている接続 ( ) しか確認できません。私のアプリには十分ではありません:(

ご覧のとおり、これはスレッドプールの制限です。何か案は?

4

1 に答える 1

8

ご想像のとおり、これはおそらくスレッドの問題です。cp_maxスレッドプール内のスレッド数の上限を設定しますが、プロセスはこの制限をはるかに下回ってメモリ不足になる可能性が非常に高く、この場合は約 200 スレッドです。各スレッドには独自のスタックがあるため、プロセスが使用するメモリの合計がシステムの制限に達し、それ以上スレッドを作成できなくなります。

bashこれは、プログラムを実行する前にスタック サイズの ulimit 設定 (私は を使用しています) を調整することで確認できます。

$ ulimit -a
core file size          (blocks, -c) 0
data seg size           (kbytes, -d) unlimited
max nice                        (-e) 0
file size               (blocks, -f) unlimited
pending signals                 (-i) 32750
max locked memory       (kbytes, -l) 32
max memory size         (kbytes, -m) unlimited
open files                      (-n) 1024
pipe size            (512 bytes, -p) 8
POSIX message queues     (bytes, -q) 819200
max rt priority                 (-r) 0
stack size              (kbytes, -s) 10240
cpu time               (seconds, -t) unlimited
max user processes              (-u) 32750
virtual memory          (kbytes, -v) unlimited
file locks                      (-x) unlimited

私のマシンのデフォルトのスタック サイズは 10240K で、この設定で約 300 のスレッドを作成できることがわかりました。スタック サイズを 1024K に調整すると ( を使用ulimit -s 1024)、約 3000 のスレッドを作成できます。

次のスクリプトを使用して、システムでのスレッド作成の制限についていくつかのアイデアを得ることができます。

from thread import start_new_thread
from time import sleep

def sleeper():
    try:
        while 1:
            sleep(10000)
    except:
        if running: raise

def test():
    global running
    n = 0
    running = True
    try:
        while 1:
            start_new_thread(sleeper, ())
            n += 1
    except Exception, e:
        running = False
        print 'Exception raised:', e
    print 'Biggest number of threads:', n

if __name__ == '__main__':
    test()

これで問題が解決するかどうかは、ConnectionPoolスレッドのメモリ要件によって異なります。

于 2009-07-24T01:38:48.833 に答える