Maison > Article > base de données > Comment MySQL peut-il améliorer la vitesse de réponse
MySQL a ses propres limites. De nombreux sites ont adopté l'architecture classique de MySQL+Memcached, et certains ont même abandonné MySQL et adopté les produits NoSQL. Il est indéniable que lors de l'exécution de requêtes simples (en particulier les requêtes PK), de nombreux produits NoSQL sont beaucoup plus rapides que MySQL.
MySQL a ses propres limites. De nombreux sites ont adopté l'architecture classique de MySQL+Memcached, et certains ont même abandonné MySQL et adopté des produits NoSQL, comme Redis. /MongoDB etc. Il est indéniable que lors de l'exécution de certaines requêtes simples (en particulier les requêtes PK), de nombreux produits NoSQL sont beaucoup plus rapides que MySQL, et plus de 80 % des requêtes sur le site Web frontal sont des services de requêtes simples.
MySQL fournit une interface d'accès API via le plug-in HandlerSocket. Dans notre test de référence, l'instance unique du serveur R510 ordinaire Percona/XtraDB a atteint 72 W+QPS (lecture pure) si un processeur plus puissant est utilisé pour ajouter plus de cartes réseau. En théorie, des performances plus élevées peuvent être obtenues. Dans les mêmes conditions, Memcached n'a que 40 W+QPS (lecture pure), et une seule instance de Memcached sur R510 ne peut pas améliorer les performances car Memcached dispose d'un verrou important sur la mémoire qui limite ses capacités de concurrence.
Moteur Innodb, recherche par clé primaire, clé unique ou index (c'est-à-dire, sa condition SQL où doit être celle-ci) ; prend en charge l'instruction de limite, IN, INSERT/UPDATE/DELETE.
La recherche sans clé primaire, clé unique ou index ne fonctionnera pas !
La table doit être le moteur Innodb
Les principaux scénarios d'utilisation de HandlerSocket et NoSQL sont différents. HandlerSocket est principalement utilisé pour améliorer MySQL, optimiser les opérations telles que les ajouts, suppressions, modifications et modifications de la structure des tables, et prend en charge les opérations intensives du processeur tandis que NoSQL, en tant que fonction de cache, prend en charge les opérations d'E/S intensives.
Par conséquent, lorsque cela est nécessaire, les deux peuvent être combinés pour travailler ensemble.
HandlerSocket est un plug-in pour MySQL, intégré au processus mysqld ; les requêtes complexes et autres opérations que NoSQL ne peut pas implémenter sont toujours implémentées à l'aide de la propre base de données relationnelle de MySQL. Au niveau de l'exploitation et de la maintenance, l'expérience largement utilisée de la réplication maître-esclave MySQL continue de jouer un rôle. Par rapport à d'autres produits NoSQL, la sécurité des données est plus garantie. Le principe est le suivant :
Il. On peut voir que HandlerSocket contourne le SQL de MySQL. La couche d'analyse (SQL Layer) accède directement à la couche de stockage MySQL. De plus, HandlerSocket utilise epoll et l'architecture réseau de pool de threads de travail/thread pour obtenir des performances supérieures.
L'architecture de MySQL est la séparation de la « gestion de base de données » et de la « gestion des données », c'est-à-dire le modèle MySQL Server+Storage Engine. MySQL Server est une couche qui interagit directement avec le client. Il est responsable de la gestion des threads de connexion, de l'analyse de SQL pour générer des plans d'exécution, de la gestion et de l'implémentation des vues, des déclencheurs, des procédures stockées et d'autres choses qui n'ont rien à voir avec la gestion spécifique des opérations de données. Il permet le stockage en appelant l'API Handler. Le moteur fonctionne sur des données spécifiques. Storage Engine implémente les fonctions de l'API Handler en héritant et est responsable de l'interaction directe avec les données, de la mise en œuvre de l'accès aux données (doit être implémentée), de la mise en œuvre des transactions (facultatif), de la mise en œuvre de l'index (facultatif) et de la mise en œuvre du cache de données (facultatif).
HandlerSocket est un composant interne de MySQL. Il fournit des services réseau de type NoSQL sous la forme d'un plugin MySQL Daemon. Il ne traite pas directement les données, mais écoute uniquement un port configuré et reçoit des données à l'aide de NoSQL/API. protocole de communication, puis appelle le moteur de stockage (tel qu'InnoDB) pour traiter les données via l'API Handler dans MySQL. Théoriquement, HanderSocket peut gérer différents moteurs de stockage MySQL. Cependant, lors de l'utilisation de MyISAM, les données insérées ne peuvent pas être trouvées car le premier octet n'est pas initialisé à 0xff lors de la construction de la ligne. Après l'initialisation, il n'y a pas non plus de problème. Il peut toujours être pris en charge, mais afin de mieux utiliser la mémoire, HandlerSocket sera utilisé avec le moteur de stockage InnoDB.
Comme le montre la figure ci-dessus, HandlerSocket sert de couche intermédiaire entre le client MySQL et MySQL, remplaçant une partie du travail natif de traitement des données et des tables de MySQL, en utilisant une approche multithread pour distinguer les opérations DDL et DML. . L’objectif est de garantir que les traitements complexes peuvent être traités efficacement.
Étant donné que HandlerSocket existe sous la forme de MySQL Daemon Plugin, MySQL peut être utilisé comme NoSQL dans les applications. Sa fonction principale est de permettre l'interaction avec les moteurs de stockage, tels qu'InnoDB, sans aucune surcharge d'initialisation SQL. Lorsque vous accédez à la TABLE de MySQL, bien sûr, vous devez également ouvrir/fermer la table, mais cela n'ouvre/ferme pas la table à chaque fois car cela enregistrera le cache de table précédemment accédé pour la réutilisation, tandis que l'ouverture/fermeture des tables est la plus simple. consomme beaucoup de ressources et peut facilement provoquer des conflits pour le mutex. Ceci est très efficace pour améliorer les performances. Lorsque le trafic diminue, HandlerSocket ferme les tables, il ne bloque donc généralement pas DDL.
Quelle est la différence entre HandlerSocket et MySQL+Memcached ? En comparant la figure 1-2 et la figure 1-3, nous pouvons voir les différences. La figure 1-3 montre une architecture d'application MySQL+Memecached typique. Étant donné que l'opération d'obtention de Memcached est beaucoup plus rapide que la requête de clé primaire de MySQL en mémoire ou sur disque, Memcached est utilisé pour mettre en cache les enregistrements de la base de données. Si la vitesse de requête et le temps de réponse de HandlerSocket sont comparables à ceux de Memcached, nous pouvons envisager de remplacer la couche architecturale des enregistrements de cache de Memcached.
1) Prend en charge plusieurs modes de requête
HandlerSocket prend actuellement en charge la requête d'index (à la fois l'index de clé primaire et l'index ordinaire de clé non primaire), l'analyse de plage d'index, Clause LIMIT, c'est-à-dire qu'elle prend en charge les fonctions complètes d'ajout, de suppression, de modification et d'interrogation, mais elle ne prend pas encore en charge les opérations qui ne peuvent utiliser aucun index. De plus, execute_multi() est pris en charge pour transmettre plusieurs requêtes de requête sur le réseau en même temps, économisant ainsi le temps de transmission du réseau.
2) Gérer un grand nombre de connexions simultanées
Les connexions HandlerSocket sont légères car HandlerSocket utilise epoll() et l'architecture worker-thread/thread-pooling, et le nombre de threads internes MySQL est limité (peut être configuré par my.cnf (contrôlé par le paramètre handlersocket_threads/handlersocket_threads_wr), donc même si des dizaines de millions de connexions réseau sont établies vers HandlerSocket, il ne consommera pas beaucoup de mémoire et sa stabilité ne sera en aucun cas affectée (une consommation trop importante de mémoire entraînera énorme concurrence d'exclusion mutuelle et d'autres problèmes, tels que le bug n° 26590, le bug n° 33948, le bug n° 49169).
3) Excellentes performances
Les performances de HandlerSocket sont décrites dans l'article Rapport de test de performances de HandlerSocket. Par rapport à d'autres produits NoSQL, les performances ne sont pas du tout inférieures, non seulement il n'appelle pas de fonctions liées à SQL, mais il optimise également. réseau/concurrence Problèmes associés :
Paquets réseau plus petits : comparé au protocole MySQL traditionnel, le protocole HandlerSocket est plus court, donc le trafic réseau global est plus petit.
Exécutez un nombre limité de threads internes MySQL : reportez-vous à ce qui précède.
Requêtes client de groupe : lorsqu'un grand nombre de requêtes simultanées arrivent à HandlerSocket, chaque thread de travail regroupe autant de requêtes que possible, puis exécute les requêtes agrégées et renvoie les résultats en même temps. De cette façon, les performances sont grandement améliorées en sacrifiant un peu de temps de réponse. Par exemple, vous pouvez réduire le nombre d'appels fsync() et réduire la latence de copie.
4) Pas de mise en cache en double
Lorsque vous utilisez Memcached pour mettre en cache les enregistrements MySQL/InnoDB, ces enregistrements sont mis en cache à la fois dans Memcached et dans le pool de tampons InnoDB, donc l'efficacité est très faible (en fait, il y a deux copies des données, et Memcached lui-même peut également nécessiter la prise en charge de HA) et le plug-in HandlerSocket est utilisé, qui accède directement au moteur de stockage InnoDB et les enregistrements sont mis en cache dans le pool de tampons InnoDB, afin que d'autres instructions SQL puissent réutiliser les données mises en cache.
5) Aucune incohérence des données
Étant donné que les données ne sont stockées qu'à un seul endroit (dans le cache du moteur de stockage InnoDB), contrairement à l'utilisation de Memcached, la cohérence des données doit être maintenue entre Memcached et MySQL.
6) Sécurité en cas de crash
Le stockage back-end est le moteur InnoDB, qui prend en charge les caractéristiques ACID des transactions et assure la sécurité des transactions Même si innodb_flush_log_at_trx_commit=2 est défini, si le serveur de base de données plante, seulement
7) Coexistence SQL/NOSQL
Dans de nombreux cas, nous souhaitons toujours utiliser SQL (comme les requêtes de rapports complexes), et la plupart des produits NoSQL ne prennent pas en charge les interfaces SQL. HandlerSocket n'est qu'un plug-in MySQL, nous pouvons toujours. utilisez-le Le client MySQL envoie des instructions SQL, mais lorsqu'un débit élevé et une réponse rapide sont requis, HandlerSocket est utilisé.
8) Hériter des fonctions MySQL
Étant donné que HandlerSocket fonctionne sur MySQL, toutes les fonctions MySQL sont toujours prises en charge, telles que : SQL, sauvegarde en ligne, réplication, haute disponibilité, surveillance, etc.
9) Pas besoin de modifier/reconstruire MySQL
Étant donné que HandlerSocket est un plug-in et open source, il prend en charge la construction à partir de n'importe quel code source MySQL, même des versions tierces (telles que Percona), sans aucune modification de MySQL.
10) Indépendant du moteur de stockage
Bien que nous ayons testé uniquement les plug-ins MySQL-EnterpriseInnoDB et Percona XtraDB, HandlerSocket peut théoriquement interagir avec n'importe quel moteur de stockage. MyISAM peut également être pris en charge par de simples modifications, mais cela n'a que peu d'importance du point de vue de la mise en cache des données et de l'utilisation de la mémoire.
1) Incompatibilité de protocole
L'API HandlerSocket n'est pas compatible avec l'API Memcached, bien qu'elle soit simple à utiliser, elle nécessite tout de même un peu d'apprentissage pour apprendre à interagir avec HandlerSocket. Cependant, nous pouvons le traduire vers l'API HandlerSocket en surchargeant la fonction Memecached.
2) Aucune fonctionnalité de sécurité
Semblable à d'autres bases de données NoSQL, HandlerSocket ne prend pas en charge les fonctionnalités de sécurité. Le thread de travail de HandlerSocket s'exécute avec les autorisations de l'utilisateur système, de sorte que l'application peut accéder à tous les objets de la table via le protocole HandlerSocket, mais cela peut l'être. modifié simplement le protocole, ajoutez un élément de configuration comme mot de passe dans my.cnf et passez la vérification du mot de passe de cette configuration lors de la connexion. Bien entendu, les paquets de données peuvent également être filtrés à travers le pare-feu réseau.
3) Il n'y a aucun avantage pour les scénarios gourmands en E/S disque
Pour les scénarios d'applications gourmandes en E/S, la base de données ne peut pas exécuter des milliers de requêtes par seconde, généralement seulement 1 à 10 % d'utilisation du processeur, dans ce cas, l'analyse SQL ne deviendra pas un goulot d'étranglement en termes de performances, il n'y a donc aucun avantage à utiliser HandlerSocket ne doit être utilisé que sur des serveurs sur lesquels les données sont entièrement chargées en mémoire. Cependant, pour les périphériques SSD PCI-E (tels que Fusion-IO), qui peuvent fournir plus de 4 W IOPS par seconde, et que le périphérique IO lui-même consomme une grande quantité de CPU, l'utilisation de HandlerSocket présente toujours des avantages.
Remarque : La méthode d'installation décrite dans le livre est obsolète et la version est relativement basse. Il n'est pas recommandé de l'utiliser. Il est recommandé d'utiliser la documentation officielle pour l'installation : https://. github.com/DeNA/HandlerSocket-Plugin-for-MySQL
Documentation d'installation : https://github.com/DeNA/HandlerSocket-Plugin-for-MySQL/blob/master/docs-en/installation.en.txt
Télécharger le code source : vous pouvez utiliser directement github. Vous pouvez également git cloner ou télécharger
Étapes d'installation :
1 build Handlersocket
./autogen.sh ./configure --with-mysql-source=/work/mysql-5.1.50 --with-mysql-bindir=/work/mysql-5.1.50-linux-x86_64-glibc23/bin --with-mysql-plugindir=/work/mysql-5.1.50-linux-x86_64-glibc23/lib/plugin
Remarque :
2 Compile
make && make install
Configuration
HandleSocket ne peut pas être utilisé après la compilation. , et vous devez l'ajouter au fichier de configuration MySQL (my.cnf) La configuration suivante :
[mysqld] # 绑定读请求端口 loose_handlersocket_port = 9998 # 绑定写请求端口 loose_handlersocket_port_wr = 9999 # 读请求线程数 loose_handlersocket_threads = 16 # 写请求线程数 loose_handlersocket_threads_wr = 16 # 设置最大接收连接数 open_files_limit = 65535
Celles ajoutées ici sont principalement pour la configuration de HandleSocket Il dispose de deux ports, 9998 pour la lecture des données et 9999 pour l'écriture des données. . Cependant, la lecture jusqu'à 9998 est plus efficace. Ici, le nombre de threads pour traiter la lecture et l'écriture est défini sur 16. De plus, afin de gérer davantage de connexions simultanées, définissez le nombre de descripteurs de fichiers ouverts sur 65535
De plus. , l'option de configuration innodb_buffer_pool_size d'InnoDB ou key_buffy_size de MyISAM est liée à l'index du cache, alors définissez-le aussi grand que possible afin qu'il puisse utiliser le potentiel de HandleSocket.
4. Activez HandleSocket
Connectez-vous à MySQL pour exécuter
mysql> install plugin handlersocket soname 'handlersocket.so';
Vous pouvez voir HandleSocket via show processlist ou show plugins
Enfin, vous devez installer le package d'extension PHP PHP HandlerSocket
Documentation d'installation : https:// github.com/tz -lom/HSPHP
Utilisation PHP :
Sélectionnez
<?php $c = new \HSPHP\ReadSocket(); $c->connect(); $id = $c->getIndexId('data_base_name', 'table_name', '', 'id,name,some,thing,more'); $c->select($id, '=', array(42)); // SELECT WITH PRIMARY KEY $response = $c->readResponse(); //SELECT with IN statement $c = new \HSPHP\ReadSocket(); $c->connect(); $id = $c->getIndexId('data_base_name', 'table_name', '', 'id,name,some,thing,more'); $c->select($id, '=', array(0), 0, 0, array(1,42,3)); $response = $c->readResponse();
Mise à jour
<?php $c = new \HSPHP\WriteSocket(); $c->connect('localhost',9999); $id = $c->getIndexId('data_base_name','table_name','','k,v'); $c->update($id,'=',array(100500),array(100500,42)); // Update row(k,v) with id 100500 to k = 100500, v = 42 $response = $c->readResponse(); // Has 1 if OK $c = new \HSPHP\WriteSocket(); $c->connect('localhost',9999); $id = $c->getIndexId('data_base_name','table_name','','k,v'); $c->update($id,'=',array(100500),array(100500,42), 2, 0, array(100501, 100502)); // Update rows where k IN (100501, 100502) $response = $c->readResponse(); // Has 1 if OK
Supprimer
<?php $c = new \HSPHP\WriteSocket(); $c->connect('localhost',9999); $id = $c->getIndexId('data_base_name','table_name','','k,v'); $c->delete($id,'=',array(100500)); $response = $c->readResponse(); //return 1 if OK
Insérer
<?php $c = new \HSPHP\WriteSocket(); $c->connect('localhost',9999); $id = $c->getIndexId('data_base_name','table_name','','k,v'); $c->insert($id,array(100500,'test\nvalue')); $response = $c->readResponse(); //return array() if OK
Recommandations associées : "Tutoriel mysql"
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!