2

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

その行動の原因は何ですか?

4

1 に答える 1

0

テーブルにアクセスするときにロックを正しく使用していますか? アクセス設定はわかりませんが、読み取り/書き込みが不足しているようです。

于 2012-04-04T13:10:45.860 に答える