3つのデータノードと1つのSQLノードを持つMySQLクラスターがあります。現在、100万個の1kbレコードがあります。挿入は非常に高速で、数ミリ秒しかかかりません。しかし、選択は非常に遅く、20秒を超えます。
すべてのマシンはm1.large EC2インスタンス(8GB RAM)です。
Config.iniは次のとおりです。
[NDB_MGMD]
NodeId=49
HostName=Host1
DataDir=/var/lib/mysql-mgmd-data
Portnumber=1186
[NDBD DEFAULT]
NoOfReplicas=1
DataMemory=1536M
IndexMemory=2560M
StringMemory=25
MaxNoOfTables=4096
MaxNoOfOrderedIndexes=2048
MaxNoOfUniqueHashIndexes=512
MaxNoOfAttributes=24576
MaxNoOfTriggers=14336
FragmentLogFileSize=256M
InitFragmentLogFiles=SPARSE
NoOfFragmentLogFiles=16
RedoBuffer=48M
MaxNoOfConcurrentOperations=100000
MaxNoOfConcurrentTransactions=16384
TimeBetweenGlobalCheckpoints=1000
TimeBetweenEpochs=100
TimeBetweenEpochsTimeout=32000
DiskCheckpointSpeedInRestart=100M
DiskCheckpointSpeed=10M
TimeBetweenLocalCheckpoints=20
HeartbeatIntervalDbDb=15000
HeartbeatIntervalDbApi=15000
MemReportFrequency=30
BackupReportFrequency=10
LogLevelStartup=15
LogLevelShutdown=15
LogLevelCheckpoint=8
LogLevelNodeRestart=15
SharedGlobalMemory=384M
DiskPageBufferMemory=1G
BatchSizePerLocalScan=512
[NDBD]
NodeId=1
HostName=Host2
DataDir=/mnt/mysql-cluster/1/
[NDBD]
NodeId=2
HostName=Host3
DataDir=/mnt/mysql-cluster/2/
[NDBD]
NodeId=3
HostName=Host4
DataDir=/mnt/mysql-cluster/3/
[MYSQLD DEFAULT]
[MYSQLD]
NodeId=53
HostName=Host1
my.cnf
[mysqld]
ndbcluster
ndb-nodeid=53
ndb-connectstring=Host1,
インサート:
INSERT INTO mytab(mykey, a, b, c, d, e, f, g, h, i,j)VALUES (1,1,2,3,4,5,6,7,8,9,0);
選択する:
SELECT * FROM mytab WHERE mykey = 12345;
テーブルステートメントを作成します。
mytab | CREATE TABLE `mytab` (
`mykey` varchar(32) NOT NULL,
`a` varchar(100) DEFAULT NULL,
`b` varchar(100) DEFAULT NULL,
`c` varchar(100) DEFAULT NULL,
`d` varchar(100) DEFAULT NULL,
`e` varchar(100) DEFAULT NULL,
`f` varchar(100) DEFAULT NULL,
`g` varchar(100) DEFAULT NULL,
`h` varchar(100) DEFAULT NULL,
`i` varchar(100) DEFAULT NULL,
`j` varchar(100) DEFAULT NULL,
PRIMARY KEY (`mykey`)
) /*!50100 TABLESPACE mytab_space STORAGE DISK */ ENGINE=ndbcluster DEFAULT CHARSET=latin1 MAX_ROWS=1000000000
/*!50100 PARTITION BY KEY (mykey) */ |
なぜそれがそんなに遅いのか誰かが考えていますか?
誰かがMySQL-clusterおよびEC2 m1.largeインスタンスを経験しましたか?
問題を解決するために間違ったツールを選択したようです。
MySQL Clusterは、メモリベースのテーブルから複数のスレッドから主にキーベースのルックアップを行う場合に適しています。ディスクベースのテーブルは、データをほとんど読み取らない場合に役立ちます。または、作業データセットは、サイズが DiskPageBufferMemory 構成変数で定義されているメモリキャッシュに収まるテーブルの小さな部分です。
クエリで多くの範囲またはフルスキャンが必要な場合-MySQL Clusterは物理マシン上でも低速です。そのようなクエリは、データノード間で大量のデータ交換を必要とするためです。データノード間でpingを実行してみてください。また、レンジスキャンの場合、データノードは数百および数千のそのようなメッセージを交換する必要がある場合があります。
また、MySQLは以前、データノードについては物理マシンを使用し、データノードトラフィックに対して適切な相互接続が必要であると述べました。この勧告が今日ではもはや有効ではないのではないかと思います。
そして、あなたはあなたの設定をクリーンアップしてみるべきだと思います。それらのほとんどをテストするために、ほとんど何も変更せず、いくつかの設定は物事を遅くしているかもしれません。そのような簡略化されたNDBD_DEFAULT
セクション:
[NDBD DEFAULT]
NoOfReplicas=1
DataMemory=1536M
IndexMemory=2560M
LockPagesInMainMemory=2
ODirect=1
ご協力ありがとうございました!それは私のせいだったと思います。私が使用したコードは間違っていました。 setString(..)の代わりにsetBytes(..)が使用されます。待ち時間は20秒から4秒に減少しました。 4sはまだmongodbのようなNoSQL dbとは比較できませんが、改善すべき点はそれほどないと思います。
preparedStatement = connection.prepareStatement("INSERT INTO "+ table+" VALUES (?,?,?,?,?,?,?,?,?,?,?)");
preparedStatement.setString(1, key);
for(int i=0; i<byteArray.length; i++){
preparedStatement.setString(i+2, byteArray[i].toString());
}
preparedStatement.executeUpdate();
preparedStatement.close();