2009-06-16 10 views
2

J'écris actuellement le projet java contre mysql dans un cluster avec dix nœuds. Le programme tire simplement quelques informations de la base de données et fait un calcul, puis repasse certaines données dans la base de données. Cependant, il y a des millions de lignes dans la table. Est-il possible de diviser le travail et d'utiliser l'architecture de cluster? Comment faire du multi-threading sur un noeud différent?accélérer l'opération sur mysql

Répondre

0

Je penserais à faire ce calcul dans une procédure stockée sur le serveur de base de données et transmettre des millions de lignes au niveau intermédiaire. Vous économiserez beaucoup d'octets sur le fil. En fonction de la nature du calcul, de votre schéma, de l'indexation, etc., vous pouvez trouver que le serveur de base de données est bien équipé pour faire ce calcul sans avoir à recourir au multi-threading. Je peux me tromper, mais ça vaut le coup de voir un prototype.

+0

Il semble qu'il ne dispose que d'un seul serveur mysql, ce qui gèlerait simplement la ressource unique au lieu d'utiliser son cluster pour distribuer le problème. – NeuroScr

1

J'ai regardé une présentation intéressante sur l'utilisation de Gearman pour faire des choses de style Map/Reduce sur une base de données mysql. C'est peut-être ce que vous recherchez: voir here. Il y a un enregistrement sur la page Web here de mysql (pour enregistrer cependant mysql.com).

+0

Utiliser gearman et UDF est un excellent moyen de distribuer le problème de MySQL aux autres machines. – NeuroScr

0

Supposons que la table (A) que vous souhaitez traiter comporte 10 millions de lignes. Créez une table B dans la base de données pour stocker l'ensemble des lignes traitées par un noeud. Vous pouvez donc écrire le programme Java de manière à ce qu'il récupère d'abord la dernière ligne traitée par les autres nœuds, puis ajoute une entrée dans la même table pour informer les autres nœuds de la plage de lignes qu'il va traiter (vous pouvez décider nombre). Dans notre cas, supposons que chaque nœud peut traiter 1000 lignes à la fois. Le nœud 1 récupère la table B et la trouve vide. Ensuite, le nœud 1 insère une ligne ('Node1', 1000) informant qu'il traite jusqu'à ce que la clé primaire de A soit < = 1000 (en supposant que la clé primaire de la table A est numérique et qu'elle est dans l'ordre croissant). Le nœud 2 arrive et constate que 1000 clés primaires sont traitées par un autre nœud. Il insère donc une ligne ('Node2', 2000) informant les autres qu'il traite les lignes entre 1001 et 2000. Veuillez noter que l'accès à la table B doit être synchronisé, c'est-à-dire qu'un seul peut travailler dessus à la fois.

+0

J'éviterais deux tables si possible, je recommanderais quelques champs supplémentaires de suivi à la table courante. Si ce n'est pas possible, il existe des tables temporaires. – NeuroScr

0

Puisque vous n'avez qu'un seul serveur mysql, assurez-vous que vous utilisez le moteur innodb pour réduire le verrouillage des tables lors des mises à jour.

Aussi, j'essaierais de garder vos requêtes aussi simples que possible, même si vous devez en exécuter plusieurs. Cela peut augmenter les risques d'accès au cache des requêtes, ainsi que réduire la charge de travail globale sur le backend, décharger une partie de l'interrogation et travailler vers les interfaces (où vous avez plus de ressources). Cela réduira également le temps pendant lequel un verrou de ligne est maintenu, réduisant ainsi la contention.

La solution Gearman proposée est probablement l'outil idéal pour ce travail. Comme il vous permettra de décharger le traitement par lots de mysql vers le cluster de manière transparente.

Vous pouvez configurer le sharding avec un mysql sur chaque machine, mais le temps d'installation, la maintenance et les modifications de la couche d'accès à la base de données peuvent représenter beaucoup de travail par rapport à une solution gearman. Vous pouvez également regarder le moteur spider expérimental qui pourrait vous permettre d'utiliser plusieurs mysqls à l'unisson.

0

À moins que votre calcul ne soit très complexe, vous passerez la plupart du temps à extraire des données de MySQL et à renvoyer les résultats à MySQL. Comme vous avez une seule base de données, aucune quantité de parallélisme ou de clustering du côté de l'application ne fera une grande différence. Donc, vos meilleures options seraient de faire la mise à jour en pur SQL si cela est possible, ou, utilisez une procédure stockée pour que tout le traitement puisse avoir lieu au sein du serveur MySql et aucun mouvement de données n'est requis.

Si ce n'est pas assez rapide, vous devrez diviser votre base de données entre plusieurs instances de MySQL et trouver un schéma pour partitionner les données en fonction de certaines clés d'application.