Mailing : question de perf. serveur

15 réponses
AuteurMessage

tonguide |
Modérateur

 

Inscrit le : 09/05/2005

# Le 01/09/2015 à 12:37

Bonjour tout le monde,

Je me pose une question au niveau perf, et je n'arrive pas à trouver de solution intéressante, ou disons que j'aimerai en trouver une plus intéressante.

Supposons que j'ai à envoyer 500K mails (ou 10Millions, allé, comme ça on imagine bien).

Je laisse le service d'envoi de mailing s'occupait de l'envoi, donc je n'ai pas à gérer l'attente de gmail ou hotmail etc.
Bref, je dois juste refourguer les emails en masse.

Mon problème étant là, comment faites-vous pour envoyer proprement les emails, avoir un suivi des emails envoyés sans être un gros bourrin ?

La solution que j'ai imaginé étant la suivante :

- mettre la liste complète des emails dans un fichier texte (avec les infos séparés par un séparateur : pseudo / nom etc. et 1 email par ligne)
- ensuite, je prend de X à Y lignes, donc X à Y emails (en faisant attention à ne pas lire tout le fichier pour ça), en gros, j'ai pris une fourchette de 500 emails
- A chaque fois que je fais ça, j'enregistre le numéro X et l'heure précise d'envoi théorique de la tranche de 500 emails suivants.
- J'envoi au service les emails
- Et je recommence.

De cette manière je peux suivre l'avancement de l'envoi, et en cas de plantage, je peux reprendre (à 500 près) l'envoi là où il s'était arrêté. Sachant que le service s'occupe de ne pas envoyer l'email 2 fois à la même personne théoriquement.

Ceci m'évite de faire trop de requete. Une requete pour recup tous les emails, celle là me fait un peu peur, puis des petites requetes d'update entre chaque tranche de 500 emails.

C'est encore que j'ai trouvé de mieux niveau perf ... (par contre, ça ne me permet pas de définir l'heure précise d'envoi de la newsletter à un membre, mais en même temps, comme l'envoi est parfois pas dans l'ordre, voir différé par le service d'envoi, ça n'aurait pas énormément d'utilité, puisque pas forcement exacte).

Comment feriez-vous ça de votre côté ?

Merci !

Bool | Olivier
Modérateur

Photo de Bool

Inscrit le : 09/05/2005

# Le 01/09/2015 à 13:46

Hello,

pour ToutGagner on a un peu ré-inventer la roue : on utilise une file d'attente en BDD, où chaque "worker" réserve une partie de la liste par petit paquet.
Si c'était à refaire, je regarderai les softs de gestion de messages/file d'attente, genre Gearman ou RabbitMQ, mais comme on fait l'envoi nous même j'avais besoin de règles de priorisation avancées (mettre certains FAI temporairement en pause, prioriser tel envoi plutôt qu'un autre, mettre les plus réactifs en premier, etc).

Dans tous les cas, y a peu de chance que ça coince de ton côté, c'est surtout le service qui fait effectivement l'envoi qui n'arrivera pas à suivre.

daevel : infogérance et conseilOuvrir dans une nouvelle fenetre || moiOuvrir dans une nouvelle fenetre

Salemioche | Nicolas
Membre

Photo de Salemioche

Inscrit le : 26/12/2008

# Le 01/09/2015 à 14:15

10 millions ca peut commencer à piquer, mais 500k, c'est pas grand chose, tu peux mettre ca en DB sans probleme ( enfin pas en MyIsam )
Tu peux mettre plusieurs processes en paralelle également, plein de méthode, mais une super simple est d'avoir une colonne ou tu stockes le process ID de l'envoyant, comme ca s'il plante, tu peux retrouver son lot de réservations. De cette manière tu peux y aller franco si le service d'expédition le supporte.

Après avoir pas mal étudier la question, pour le queueing je me suis arreté sur beanstalkd, et cela peut aussi être complémentaire avec gearman vers ton Saas d'expédition pour vider plus vite. ( Pas testé avec 10M non plus )

Tu peux aussi te faire un sharding artisanal avec une 10aine de tables si tu penses que ca va coincer à ce niveau là

francois10 | Francois
Membre

 

Inscrit le : 14/05/2006

# Le 01/09/2015 à 14:56

Et pourquoi pas utiliser les services de sociétés spécialisées ?

tonguide | Jeremy
Modérateur

 

Inscrit le : 09/05/2005

# Le 01/09/2015 à 15:14

Euh, c'est précisément ce que je fais, mais il faut bien leur envoyer les emails quand même, à ces services pour qu'ils puisent les traiter.

Bool | Olivier
Modérateur

Photo de Bool

Inscrit le : 09/05/2005

# Le 01/09/2015 à 16:00

Disons que du coup ça n'est plus forcément lié aux emails : ton problème est surtout de pouvoir taper sur une API externe à haut régime.

Je vois deux facteurs limitant :
1) la capacité du service en face à accepter ta demande
2) la latence induite par le réseau/service

Pour le premier point, tu ne peux pas faire grand chose j'imagine... hormis essayer de rester dans les clous (ou contourner les quotas, mais c'est mal (tm)).
Pour le second point, la meilleure solution à ce que je sache c'est le parallélisme. Si tu es capable d'adapter le nombre d'appels parallèle en fonction de la latence, tu arriveras obligatoirement à la vitesse d'envoi souhaitée.

Par exemple, si ton presta met 100ms à intégrer un email dans sa file d'attente (c'est à dire 600 emails par minute), et que toi tu veux pouvoir lui en pousser 100k par minute, il te "suffit" d'avoir 167 sockets en parallèle pour pousser le bousin.

À partir de là tu as différentes méthodes de parallélisme, le système de message est probablement la méthode la plus simple.
Tu peux aussi tenter de tout gérer toi même via des sockets non bloquants (très économe en ressource, c'est la méthode utilisée par NginX).
Ou bien tu peux te contenter de forker un process (méthode basique mais efficace qu'on apprend en Bac+2 d'info, c'est la méthode utilisée par Apache 1).

Le système de message quant à lui est plus orienté cloud : ça te permet aussi de faire du multi serveur si besoin. Et si tu as besoin de 80 CPU pour procéder à ça, tu peux même louer 20 VMs pendant une heure chez AWS ou OVH et bourriner à mort.

daevel : infogérance et conseilOuvrir dans une nouvelle fenetre || moiOuvrir dans une nouvelle fenetre

francois10 | Francois
Membre

 

Inscrit le : 14/05/2006

# Le 01/09/2015 à 16:19

Re,

Ce que je ne comprend pas c'est dans quel cas tu as besoin de faire autant de call vers une API externe?
Chez nous par example nous envoyons plusieurs dizaines de millions de mails par mois, et en gros :
* transactionnel : on tape l'api du provider en real-time => pas de pb
* mailing : on le rentre direct dans el backoffice du provider => pas de pb non plus

Sinon Olivier t'a donné toutes les infos

François

Scull | Thomas
Membre

Photo de Scull

Inscrit le : 06/08/2006

# Le 01/09/2015 à 16:30

Yep j'avais la même question, pourquoi est ce à vous de gérer ce problème ? Tu tapes sur ton provider et il ce démerde pour étaler l'envoi, non ?

Mon GitHubOuvrir dans une nouvelle fenetre | Founder & CEO of [website I made over the weekend]

Bool | Olivier
Modérateur

Photo de Bool

Inscrit le : 09/05/2005

# Le 01/09/2015 à 16:32

Si tu as une newsletter qui part vers 1 million d'abonnés, et que le contenu est fortement personnalisé, même si le fournisseur a un système de template y a bien un moment où il faudra lui pousser les 1'000'000 de contenus différents, non ?

daevel : infogérance et conseilOuvrir dans une nouvelle fenetre || moiOuvrir dans une nouvelle fenetre

tonguide | Jeremy
Modérateur

 

Inscrit le : 09/05/2005

# Le 01/09/2015 à 16:49

Oui, sauf que c'est l'envoi en interne que j'aimerai qui se passe rapidement (l'objet de la question). Donc le "tu tapes sur le provider" ce n'est effectivement pas l'objet de la question.

J'avais sous traité le dev de l'envoi du mailing au service faute de temps, au final, ça mettait plusieurs heures à partir de chez moi (et non du service!).
Du coup je redev la solution par moi même, et dans cette optique, je cherche la solution la plus light en conso, chez moi, pour refourger le mail (qq bourdes faites par le dev explique une bonne partie de la latence énorme constaté, mais bref).

D'ailleurs, je regardais l'API de mailjet, un contact = un email, donc aucun moyen de personnaliser la newsletter selon le membre, obligé de passer par SMTP pour envoyer les emails donc, ce qui me parait plus gourmand, mais pas le choix ?

Et donc non, mon problème n'est pas de taper dans une API (ça serait effectivement plus simple), ou sinon il faudrait que je trouve un autre presta de service dont l'API est plus complète ...

@olivier : La méthode de la BDD, étant celle qu'on pourrait imaginer au départ, mais pour moi, des "petits paquets" signifie une à plusieurs requetes par "petit paquet", multiplié par le nombre petit paquet pour tout envoyer, ça peut vite faire une quantité énorme de "petit paquet" (et donc d'appel à la BDD et de traitement), si à côté de ça, 2 newsletters se croisent sur le même rythme, j'ai un peu peur des perfs et de l'impact sur le serveur en faisant ça.

francois10 | Francois
Membre

 

Inscrit le : 14/05/2006

# Le 01/09/2015 à 16:49

Bool > ça dépend vraiment de ton niveau de personnalisation. Les champs "standard"' genre nom, prenom, etc... ne nécessitent sont directement rewrité par le provider, donc déjà ça les élimine. Il reste ensuite le contenu pur et dur.
Là, soit t'es un site avec un max de contenu et t'envoi des news super custom et effectivement t'as pas le choix, soit t'a au final que quelques dizaines de contenu différents et tu peux très bien créer des motifs chez ton provider puis les inclure.

Au passage, faire des templates chez le provider permet de faire des call API beaucoup plus petits (ie, je passe l'ID du template en paramètre au lieu d'envoyer 50ko de code comme un porc ), ça va accélérer grandement le débit, à moindre frais.

tonguide > regarde du côté de Mailchimp / Mandrill, tu trouveras ton bonheur

tonguide | Jeremy
Modérateur

 

Inscrit le : 09/05/2005

# Le 01/09/2015 à 16:57

Oui donc, c'est l'API de mailjet qui est trop limité à ce niveau là déjà ?
Parce qu'initialement, je pensais trouvé le moyen d'entrer suffisamment de donnée + un template, et go pour l'envoi de la newsletter, mais, sauf erreur ... je n'ai pas trouvé ça sur leur API.

francois10 | Francois
Membre

 

Inscrit le : 14/05/2006

# Le 01/09/2015 à 16:59

Là aucune idée, je connais pas du tout leur API.

tonguide | Jeremy
Modérateur

 

Inscrit le : 09/05/2005

# Le 01/09/2015 à 17:09

addContact (method pour ajouter un contact) contient uniquement les paramètres suivants :

contact (String, required)
› Description: Mailjet's contact ID or email
id (Integer, required)
› Description: Mailjet's List ID
force (Boolean, optional)
› Description: If the contact exists, reset unsub status.
› Default value: false

A priori, j'ai un peu fouillé partout, je n'ai trouvé mention nul part d'une autre façon de faire (sauf ajout de plusieurs à la fois, mais les critères restent les mêmes).

Maintenant, si un template + envoyer la liste complètes des emails (avec leur param) pour envoyer la newsletter par une API, il n'y a plus vraiment de problème de perf dans ces cas là. Je vais regarder de ce côté là. (l'idéal serait de pouvoir mettre uniquement à jour les changements dans la liste des mails, et là ça serait le paradis, plus de soucis de perf possible).

tonguide | Jeremy
Modérateur

 

Inscrit le : 09/05/2005

# Le 01/09/2015 à 17:56

Donc je confirme, l'API de MailChimp me semble nettement plus complète et permet de palier à mon soucis (bon, ça va nécessiter de redevelopper une partie mais bon).

Reste le soucis de l'email vraiment 100% personnalisé (= le contenu lui même), mais je pense que dans ces cas là, on peut considérer l'email comme non urgent (car pas spécifiquement daté) et donc diluer l'envoi sur toute la journée via un envoi "transactionnel" et ciblé à l'heure où le membre à l'habitude d'ouvrir ses emails.

Evidemment, j'aurai préféré utiliser mailjet, tout était déjà dev pour leur envoyer ...

radins | Tobias
Modérateur

Photo de radins

Inscrit le : 09/05/2005

# Le 29/12/2015 à 21:05

Bool a dit :
Hello,

pour ToutGagner on a un peu ré-inventer la roue : on utilise une file d'attente en BDD, où chaque "worker" réserve une partie de la liste par petit paquet.


Désolé pour le déterrage je ne passe plus souvent ici, mais ça me rappelle de vieux souvenirs ça..

Répondre

Vous ne pouvez pas participer au forum, car votre inscription n'a pas été validée. Pour vous faire valider en tant que Membre, cliquez ici.

© MHN - Tous droits réservés | CNIL N°844440 | 23/04/2024 8:16:41 | Généré en 53.29ms | Contacts | Mentions légales |