it-swarm-eu.dev

Jak používat zpoždění vložení s InnoDB motorem a použít méně spojení pro vložení příkazů?

Pracuji na aplikaci, která zahrnuje mnoho zápisů do databáze, přibližně ~ 70% příloh a 30% čtení. Tento poměr by také zahrnoval aktualizace, které považuji za jedno čtení a jedno psaní. Pomocí příkazů insert vkládá více klientů data do databáze pomocí příkazu insert níže:

$mysqli->prepare("INSERT INTO `track` (user, uniq_name, ad_name, ad_delay_time ) values (?, ?, ?, ?)");

Otázkou je, zda mám použít buď insert_delay nebo použít mysqli_multi_query mechanismus, protože insert příkaz využívá ~ 100% CPU na serveru. Používám motor InnoDB ve své databázi, takže vložení zpožděné není možné. Vložení na server je ~ 36k/h a 99,89% přečteno, také jsem pomocí příkazu SELECT tam načíst data sedmkrát v jediném dotaz , tento dotaz trvá 150 sekund na serveru k provedení. Jakou techniku ​​nebo mechanismus mohu použít pro tento úkol? Paměť mého serveru je 2 GB, měla bych rozšířit paměť ?. Podívejte se na tento problém, jakýkoli návrh mi bude vděčný.

Struktura tabulky:

+-----------------+--------------+------+-----+-------------------+----------------+
| Field           | Type         | Null | Key | Default           | Extra          |
+-----------------+--------------+------+-----+-------------------+----------------+
| id              | int(11)      | NO   | PRI | NULL              | auto_increment |
| user            | varchar(100) | NO   |     | NULL              |                |
| uniq_name       | varchar(200) | NO   |     | NULL              |                |
| ad_name         | varchar(200) | NO   |     | NULL              |                |
| ad_delay_time   | int(11)      | NO   |     | NULL              |                |
| track_time      | timestamp    | NO   | MUL | CURRENT_TIMESTAMP |                |
+-----------------+--------------+------+-----+-------------------+----------------+

Moje databáze je v aktuálním stavu, zobrazuje 41 kB vložení (zápisů), což je pro moji databázi velmi pomalé.

database status

10
Shashank

Protože máte více zápisů a pak přečte, rád bych doporučil následující

Klíčem by bylo slušné ladění InnoDB

Fond vyrovnávacích pamětí (Velikosti podle innodb_buffer_pool_size )

Protože InnoDB nepodporuje INSERT DELAYED , použití velkého fondu vyrovnávacích pamětí InnoDB je nejbližší věcí, kterou můžete získat INSERT DELAYED. Všechny DML (INSERTs, UPDATE a DELETE) budou ukládány do mezipaměti ve fondu vyrovnávacích pamětí InnoDB. Transakční informace pro Zápisy jsou okamžitě zapsány do Redo Logů (ib_logfile0, ib_logfile1). Zápisy, které jsou zaúčtovány ve fondu vyrovnávacích pamětí, jsou periodicky vyprazdňovány z paměti na disk prostřednictvím ibdata1 (InsertBuffer pro sekundární indexy, vyrovnávací paměť Double Write). Čím větší je fond vyrovnávacích pamětí, tím větší množství INSERTů lze uložit do mezipaměti. V systému s 8 GB nebo více paměti RAM použijte 75-80% z hodnoty RAM jako innodb_buffer_pool_size. V systému s velmi malou pamětí RAM 25% (pro přizpůsobení operačního systému)).

CAVEAT: Můžete nastavit innodb_doublewrite na 0 pro zrychlení zápisu více, ale s rizikem integrita dat. Můžete také urychlit věci nastavením innodb_flush_method na O_DIRECT, abyste zabránili ukládání InnoDB do OS do mezipaměti.

Opakovat záznamy (Velikosti podle innodb_log_file_size )

Ve výchozím nastavení jsou protokoly opakování pojmenovány ib_logfile0 a ib_logfile1 a každý by měl být 5 MB. Velikost by měla být 25% velikosti innodb_buffer_pool_size. Pokud již existují nové protokoly, přidejte nové nastavení do my.cnf, vypněte mysql, odstraňte je a restartujte mysql .

Vyrovnávací paměť protokolu (velikost podle innodb_log_buffer_size )

Vyrovnávací paměť protokolu obsahuje změny v RAM před jejich propláchnutím do opakovacích protokolů. Výchozí hodnota je 8 M. Čím větší je vyrovnávací paměť protokolu, tím méně diskového vstupu/výstupu. Buďte opatrní při velmi velkých transakcích, protože to může zpomalit COMMITs o milisekundy.

Přístup k více procesorům

MySQL 5.5 a MySQL 5.1 InnoDB Plugin mají nastavení umožňující přístup InnoDB Storage Engine k více procesorům. Zde jsou možnosti, které musíte nastavit:

  • innodb_thread_concurrency nastavuje horní hranici počtu souběžných vláken, které může InnoDB udržovat otevřený. Obvykle se doporučuje nastavit pro toto nastavení (2 x počet procesorů) + počet disků. Minulý rok jsem se na konferenci v Percona NYC dozvěděl, že byste to měli nastavit na 0, abyste varovali InnoDB Storage Engine, aby našel nejlepší počet vláken pro prostředí, ve kterém běží.
  • innodb_concurrency_tickets nastavuje počet vláken, která mohou beztrestně obejít kontrolu souběžnosti. Po dosažení tohoto limitu se opět stane normou kontrola souběžnosti vláken.
  • innodb_commit_concurrency nastavuje počet souběžných transakcí, které mohou být potvrzeny. Vzhledem k tomu, že výchozí hodnota je 0, nenastavení umožňuje libovolnému počtu transakcí provádět transakce současně.
  • innodb_thread_sleep_delay nastavuje počet milisekund, ve kterých může být vlákno InnoDB nečinné, než znovu vstoupí do fronty InnoDB. Výchozí hodnota je 10 000 (10 sekund).
  • innodb_read_io_threads (nastaveno na 3000) a innodb_write_io_threads (nastaveno na 7000) (oba od MySQL 5.1.38) přidělte určený počet vláken pro čtení a zápisy. Výchozí hodnota je 4 a maximální je 64. Nastavte je na 64. Také nastavte innodb_io_capacity na 10000.

Upgradujte na MySQL 5.5

Pokud máte MySQL 5.0, upgradujte na MySQL 5.5. Pokud máte MySQL 5.1.37 nebo starší, upgradujte na MySQL 5.5. Pokud máte MySQL 5.1.38 nebo vyšší a chcete zůstat v MySQL 5.1, nainstalujte si zásuvný modul InnoDB. Tímto způsobem můžete využít všech procesorů pro InnoDB.

11
RolandoMySQLDBA

INT (2) stále používá 4 bajty - možná jste mysleli TINYINT UNSIGNED?

Kolik různých hodnot v setno? Pokud je malý, KEY (setno) nebude nikdy použit. INSERTing musí tento index aktualizovat; odebrání KEY některé zrychlí.

CHAR (10) - Je flag vždy 10 znaků? A v utf8? Možná byste mohli použít příznak VARCHAR (10) CHARACTER SET ascii

Dávejte své přílohy - 100 najednou poběží 10krát rychleji. (Více než 100 se dostává do „klesajících výnosů“.)

Jaká je hodnota autocommit? Zabalujete všechny VLOŽKY do ZAČÁTEK ... PŘIPOJIT? Jaká je hodnota innodb_flush_log_at_trx_commit?

2
Rick James

Nastavit frontu. Aplikace se zapisuje do řádku 1 ve frontě najednou a poté vyjme řádky a vloží do databáze v dávce na základě počtu řádků na množství času, který uplynul od posledního vložení.

Viděl jsem, kde je dávkování vložek 10 000 najrychlejší, takže byste museli vyzkoušet, abyste našli sladké místo.

Mohli byste si vytvořit svůj vlastní jednoduchý systém front nebo použít existující. Zde je několik příkladů: HornetQ a File :: Queue . Zde je příspěvek na SE se seznamem dalších dobrých možností: Fronty zpráv v Perlu, php, python .

1
dabest1