La tabella InnoDB con inserti pesanti non utilizzerà tutta la mia CPU


8

Ho un database di log di pacchetti, che non viene quasi mai interrogato. Deve solo essere veloce sugli inserti. Sto usando InnoDB perché mi piacerebbe mantenere la conformità ACID, poiché anche perdere un singolo pacchetto potrebbe essere dannoso per i nostri clienti. In uno scenario di ottimizzazione delle prestazioni, invio 1.000.000 di pacchetti al server su più connessioni DB. Ma indipendentemente dalle impostazioni che utilizzo in my.cnf, non riesco a far sì che il processo mysqld usi più del 900% di CPU su un sistema con 12 core. (Nient'altro è in esecuzione sulla scatola.)

Ho impostato quanto segue

  • innodb_file_per_table = 1
  • innodb_write_io_threads = 64
  • innodb_read_io_threads = 64
  • innodb_thread_concurrency = 0

Se uso MyISAM, posso ottenere tutti i pacchetti scritti in circa 6 secondi. Ma InnoDB impiega circa 25. Posso fare in modo che MySQL usi il resto delle risorse di sistema e inserisca più velocemente?

Modifica: ecco lo schema per la tabella:

+-------+----------------------+------+-----+---------+-------+
| Field | Type                 | Null | Key | Default | Extra |
+-------+----------------------+------+-----+---------+-------+
| t     | bigint(20) unsigned  | YES  |     | NULL    |       |
| a     | char(1)              | YES  |     | NULL    |       |
| sa    | int(10) unsigned     | YES  |     | NULL    |       |
| sb    | int(10) unsigned     | YES  |     | NULL    |       |
| sc    | int(10) unsigned     | YES  |     | NULL    |       |
| sd    | int(10) unsigned     | YES  |     | NULL    |       |
| sp    | smallint(5) unsigned | YES  |     | NULL    |       |
| da    | int(10) unsigned     | YES  |     | NULL    |       |
| db    | int(10) unsigned     | YES  |     | NULL    |       |
| dc    | int(10) unsigned     | YES  |     | NULL    |       |
| dd    | int(10) unsigned     | YES  |     | NULL    |       |
| dp    | smallint(5) unsigned | YES  |     | NULL    |       |
+-------+----------------------+------+-----+---------+-------+

edit2: ho inserito in batch più inserti in modo che una singola query abbia quasi raggiunto la lunghezza massima (circa 16.000.000 di caratteri). Il database ora raggiunge il 1100% per due secondi, quindi scende al 100% per il resto del tempo. Il tempo totale è ora di 21 secondi, ovvero circa il 16% più veloce di quando ho iniziato.

Risposte:


7

Devi alzare anche innodb_io_capacity .

Il valore predefinito è 200. Alzalo a 5000 per cominciare. Vorrei andare a 20000.

Puoi anche assicurarti ib_logfile0che ib_logfile1siano sufficientemente grandi. Il valore predefinito per innodb_log_file_size è 5M. Vorrei alzarlo a 1G per cominciare.

Un pool di buffer InnoDB più grande potrebbe anche aiutare, forse 4G.

Per ricapitolare, utilizzare queste impostazioni aggiuntive:

[mysqld]
innodb_io_capacity=5000
innodb_buffer_pool_size=4G
innodb_log_file_size=1G

Dopo aver aggiunto queste impostazioni a my.cnf, per ridimensionare ib_logfile0 / ib_logfile1, procedi come segue

service mysql stop
rm -f /var/log/mysql/ib_logfile[01]
service mysql start

I file ib_logfile0 e ib_logfile1 vengono ricreati. Non ti preoccupare, l'ho fatto molte volte .

Potrebbe essere necessario fare qualcosa di straordinario per InnoDB

Prova quanto segue:

  • Blocco completo della tabella nella tabella InnoDB
  • Eseguire il caricamento di massa
  • Rilascia il blocco

Aiuterebbe avere più pool di buffer? O dal momento che è solo un tavolo, avrebbe importanza?
sep332,

Solo un pool di buffer. In questo modo non c'è limite virtuale. Ho un client con MySQL 5.5.9 che utilizza un singolo pool di buffer da 162 GB e funziona alla grande.
RolandoMySQLDBA

Usando questo sono arrivato a circa il 950% di CPU, ma non sembra essere più veloce.
sep332,

Prova un blocco completo della tabella sulla tabella InnoDB prima del caricamento di massa.
RolandoMySQLDBA,

3

Esistono numerosi fattori che influiscono sulla capacità di massimizzare l'uso di più core.

  • Alcuni mutex avranno un impatto su più CPU lasciando un po 'di attesa prima che possano procedere.
  • Hai bisogno di tanti thread attivi quante sono le CPU. Se il carico di lavoro risulta in 9 thread paralleli, non è possibile riempire 12 core.
  • La capacità di I / O deve essere sufficiente per fornire un lavoro sufficiente per tutte le CPU. Se stai accodando su I / O su disco o stai aspettando messaggi di rete, non sarai in grado di riempire le CPU.

Strumenti come SAR ti permetteranno di determinare se ci sono strozzature che stanno riducendo la tua capacità. Basta essere avvisati, eliminando un collo di bottiglia, si sposterà il collo di bottiglia.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.