MySQL データベースを使用して Java で記述された MMORPG サーバーを実行しています。数か月間は非常にうまく機能していましたが、人気が高まり、データベースが大きくなるにつれて、問題が発生し始めました。クエリはすべて、パケットも処理する同じスレッドで実行されました (はい、設計が非常に貧弱でした)。これにより、大きな遅延が発生しました。10 分間保存されていない文字を定期的に保存する save-worker を実装することで、これを偽造しました。 5スレッドで。さらに、他の 5 つのスレッドは、ゲームプレイ中に即時処理を必要とするデータベース クエリを処理します。
私たちの問題は、キャラクターに関する一般的な情報を含むテーブルにアクセスする更新が、何らかの理由で時間がかかり、タイムアウトになることです。
プロセスリスト: http://i.imgur.com/Fr0kD.png
更新にはさらに約 30のcharacters
フィールドが含まれ、WHERE id = ?で終わります。.
プロセスリストに表示されるテーブルのレイアウト:
TABLE `characters` ( -- Contains about 300.000 rows
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`accountid` int(10) unsigned NOT NULL DEFAULT '0',
`world` int(11) NOT NULL DEFAULT '0',
`name` varchar(13) NOT NULL DEFAULT '',
`level` int(11) NOT NULL DEFAULT '0',
`exp` int(11) NOT NULL DEFAULT '0',
`str` int(11) NOT NULL DEFAULT '0',
`dex` int(11) NOT NULL DEFAULT '0',
`luk` int(11) NOT NULL DEFAULT '0',
`int` int(11) NOT NULL DEFAULT '0',
...
`job` int(11) NOT NULL DEFAULT '0',
...
PRIMARY KEY (`id`),
KEY `accountid` (`accountid`),
KEY `ranking1` (`level`,`exp`),
KEY `ranking2` (`job`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
TABLE `items` ( -- contains 34 million rows
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
`type` tinyint(3) unsigned NOT NULL,
`inventoryType` tinyint(4) NOT NULL,
`characterId` int(10) unsigned DEFAULT NULL,
`accountId` int(10) unsigned DEFAULT NULL,
`itemId` int(10) unsigned NOT NULL,
...
PRIMARY KEY (`id`),
KEY `FK_items_1` (`characterId`),
KEY `FK_items_2` (`accountId`),
CONSTRAINT `FK_items_1` FOREIGN KEY (`characterId`) REFERENCES `characters` (`id`) ON DELETE CASCADE,
CONSTRAINT `FK_items_2` FOREIGN KEY (`accountId`) REFERENCES `accounts` (`id`) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
TABLE `wishlists` ( -- contains ~75.000 rows
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`characterId` int(10) unsigned NOT NULL,
`serialNumber` int(10) unsigned NOT NULL,
PRIMARY KEY (`id`),
KEY `FK_wishlists_1` (`characterId`),
CONSTRAINT `FK_wishlists_1` FOREIGN KEY (`characterId`) REFERENCES `characters` (`id`) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
これは、WS2008 R2、MySQL 5.5.22、および Java 7 を実行する専用サーバーです。Java は JDBC (MySQL コネクタ 5.1.18) を介してデータベースに接続し、これらのクエリに対して autoCommit は false に設定され、アイソレーションは TRANSACTION_READ_UNCOMMITTED です。サーバーには 32 GB の RAM があり、そのうち 24 は Java に使用され、残りは MySQL に使用できます。いくつかの設定:
innodb_buffer_pool_size=8G
innodb_log_file_size=1024M
innodb_thread_concurrency=10
その行動の原因は何ですか?