web-dev-qa-db-ja.com

mysql NDBクラスターですべてのクエリが非常に遅い

これが私の状況です:

10Gを超えるWebログ(約3,000万行)を取得し、主にさまざまな条件で検索しました。

例えば。:

select * from tbl 
where ip = '123.123.12.3' 
  and agent = 'mozillar' 
  and body like '%script%'

データが大きくなるにつれて、単純なクエリは数分かかるので、MySQLクラスターで分散データベースを作成しようとしています。

GoogleクラウドVM上に1つの管理サーバー、1つのSQL(api)サーバー、および4つのデータノードを構築しました。各インスタンスに2つのCPUと8 GBがあります。

問題:

.sqlファイルからデータを復元しようとすると、各挿入ステートメントに約2〜3秒かかります。

3秒* 30m行= FOREVER!

選択クエリにも失望しました。通常のInnoDBのほぼ100倍の時間がかかります。

私は何か間違ったことをしていますか?

私の目的に適した解決策はありますか?

config.ini

[ndbd default]
NoOfReplicas=2    
DataMemory=5G    
IndexMemory=128M   
MaxNoOfConcurrentOperations=1000000
MaxNoOfLocalOperations=1100000
MaxNoOfConcurrentTransactions=327680
NoOfFragmentLogFiles=256
FragmentLogFileSize=32M
SharedGlobalMemory=512M
DiskPageBufferMemory=512M
DiskIoThreadPool=8

[ndb_mgmd]
NodeId=1
hostname=10.142.0.7
datadir=/var/lib/mysql-cluster/mgmt


[ndbd]
NodeId=11
hostname=10.142.0.8
datadir=/var/lib/mysql-cluster/data1
[ndbd]
NodeId=12
hostname=10.142.0.9
datadir=/var/lib/mysql-cluster/data2
[ndbd]
NodeId=13
hostname=10.142.0.10
datadir=/var/lib/mysql-cluster/data3
[ndbd]
NodeId=14
hostname=10.142.0.11
datadir=/var/lib/mysql-cluster/data4

[mysqld]
NodeId=100

すべてのノードが期待どおりに管理サーバーに接続されている

-- NDB Cluster -- Management Client --
ndb_mgm> show
Connected to Management Server at: localhost:1186
Cluster Configuration
---------------------
[ndbd(NDB)]     4 node(s)
id=11   @10.142.0.8  (mysql-5.6.29 ndb-7.4.11, Nodegroup: 0, *)
id=12   @10.142.0.9  (mysql-5.6.29 ndb-7.4.11, Nodegroup: 0)
id=13   @10.142.0.10  (mysql-5.6.29 ndb-7.4.11, Nodegroup: 1)
id=14   @10.142.0.11  (mysql-5.6.29 ndb-7.4.11, Nodegroup: 1)
[ndb_mgmd(MGM)] 1 node(s)
id=1    @10.142.0.7  (mysql-5.6.29 ndb-7.4.11)
[mysqld(API)]   1 node(s)
id=100  @10.142.0.2  (mysql-5.6.29 ndb-7.4.11)

追加情報:

    Create Table: CREATE TABLE `tbl` (
  `no` int(11) NOT NULL AUTO_INCREMENT,
  `rule_name` varchar(50) DEFAULT NULL,
  `ip` varchar(20) DEFAULT NULL,
  `detection_time` datetime NOT NULL,
  `uri` text,
  `site` varchar(500) DEFAULT NULL,
  `country` varchar(50) DEFAULT NULL,
  `body` text CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL,
  `detection_string` text,
  `detection_type` int(11) NOT NULL,
  `action` int(11) NOT NULL,
  `category` int(10) NOT NULL,
  PRIMARY KEY (`no`),
  KEY `no` (`no`),
  KEY `ip` (`ip`)
) ENGINE=InnoDB AUTO_INCREMENT=21682043 DEFAULT CHARSET=utf8
1 row in set (0.03 sec)
2
DavidK

冗長なインデックス。_PRIMARY KEY_はインデックスなので、冗長なKEY no(no)は必要ありません。 (DROPpingこれにより、処理が少し速くなります。)

Agent。スキーマのagentはどこにありますか? varcharですか?または列挙型?または正規化された_SMALLINT UNSIGNED_。最後のものはスペースを節約するため、速度は向上しますが、挿入が複雑になります。

より良いインデックス。INDEX(ip)INDEX(ip, agent)で置き換えます。これは与えられたSELECTをスピードアップします。 (しかし、エージェントは通常、指定されたIPで同じであると思います。)

国コード非常に標準的な2文字の国コードがあります。かさばるvarchar(50)の代わりに使用してください。

バッチ処理。とりあえず本当のスピードアップ...インサートをバッチ処理します。それらをテーブルに収集し、テーブルを交換し、_INSERT..SELECT_など 詳細はこちら 。その手法は自動調整です。物事が遅くなると、彼らの行動もより効率的になります。そのリンクは、効率的に正規化する方法も説明しています。

チューニング。_IndexMemory=128M_は、不当に小さいようです。

InnoDBに戻りますか?

選択クエリも私を失望させました、それは通常のInnoDBよりもほぼ100倍長くかかります。

私が述べたテクニックはInnoDBのために十分に調整されています。 MySQL Clusterの経験が少ない。たぶん、あなたはInnoDBに戻ったほうがいいでしょう。 _innodb_buffer_pool_size_はRAMの約70%にする必要があります。

IPv6。補足:IPv4にはVARCHAR(15)のみが必要です。 IPv6には_(39)_が必要です。また、IPアドレスは、utf8ではなく_CHARACTER SET ascii_でもかまいません。 (ここではパフォーマンス上の大きなメリットはありません。)

1
Rick James