Comment augementer votre compression sans toucher au format de compression?

Bonjour,

Aujourd’hui nous allons parler de compression de données lossless (sans changement de l’information).
Cela vas s’appliquer surtout au MMORPG CatchChallenger sur les points suivant: données de taille petite et moyenne, fortement compressible (xml, base64 continue).

Choix de la compression

Même si dans ce post se n’est pas le but, il faut bien choisir votre compression en fonction de votre système. Si vous voulez plus de bande passante en échange de cpu, si vous faites la compression dynamiquement ou non, …

Ratio de compression

Temps de compression

Réduire l’entropie

Nous allons avant tout commencer à reduire l’entropie. Vous devez donc supprimer toutes les données aléatoire inutile. Et faire que celle utile forme des suites.

Isoler les bloques aléatoires

Quand un bloque de donnés viens couper des données similaire:

items/1073.png 1 XXXX
items/1149.png 1 XXXX
items/1178.png 1 XXXX

Cela casse la compression (le système de compression switch tout le de temps compressé a non compressé). Cela n’as pas d’importance sur les grands bloque car le changement de mode est mineur vis a vis de la taille du bloque à compresser. L’idée est donc de les mettre la la fin pour que la compression soit maximal d’un coté et que le système de compression marque simplement un gros bloque comme non compressible.

items/1073.png 1
items/1149.png 1
items/1178.png 1
XXXX
XXXX
XXXX

Cela fait gagné 20% sur le format au dessus.

Binaire et pas hexa

Les formats de compression sont très sensible aux données non compressibles, les mettre en binaire et pas en hexa permet de réduire leur taille (10%).

Contenu

En fonction du contenu ET de la taille certaine compression seront plus avantageuse. Par exemple la zlib/gzip est plus efficace que xz/lzma sur les packet <300o.

Il n’y as pas une compression meilleur que les autres, chaque une ont leurs caractéristiques et leurs caractéristiques vis à vis de certaines données.

Zopfli

Zopfli permet de garder le format de compression actuel, mais à énormément besoin de cpu, ne jamais l’utiliser en dynamique. Il réduit de 10% à 50% la taille de vos compressions zlib/gzip (donc png aussi)

Mon outils tmxTileLayerCompressor pour compresser les bloques zlib dans les tmx avec zopfli permet de réduire la taille des tmx même sous leur forme compressé d’environ 10%.

Chose étonnante je ne constate pas de réduction de taille du datapack.tar.xz comme prévu. Idem coté tar sans xz, je pense que la modification est noyé dans un volume tellement gros d’informations qu’elle n’as pas d’influence. Par contre sur les pngs zopfli a une une influence notable.

Brotli

Je doit tester cette compression qui semble sympa surtout pour le streaming réseau avec des bloques de plus de 800o. Une compression proche de xz pour le statique, mais plus performant que gzip en -6 pour le streaming réseau tout en conservant un trés bon ratio. Mais hélas je trouve qu’il est trop orienté décompression, car la compression est bien trop lente mon gout, où en -6 c’est trés proche ou inférieur au ratio de zlib en fonction du contenu. Comme zlib: C’est parallélisable? Possible accélération hardware?

Voir le super lien: https://quixdb.github.io/squash-benchmark/

Lossy

Pour certain fichier comme les png/audio, les compressions sont lossless (sans perte de qualité/informations) mais j’ai appliquer un filtre de compression lossy (perte de qualité/informations) pour réduire la taille.

CatchChallenger

Voila les résultats spécifiques à CatchChallenger pour la liste des fichiers à télécharger:

Binaire 7% de taille en moins pour gzip
Suppression des retours de ligne pour les hash partiel (données non compressibles: réduction de 10% pour xz, 7% pour gzip
La spéparation en deux fichier (l’un compressé l’autre non) fait gagné 100o mais qui sont perdu par le protocole http (2x les entêtes pour les deux fichiers)
Répartition de la taille pour la base:
* 7Ko pour la liste de fichiers
* 500o pour la taille des fichiers
* 12Ko pour les hash partiel (non compressible)
Répartition de la taille pour le main:
* 2200o pour la liste de fichiers
* 500opour la taille des fichiers
* 2200opour les hash partiel (non compressible)

Programmation Broadcast vs singlecast et chat

Bonjour,

J’avais vu une bétise sur internet disant qu’il valais mieux utiliser une serveur irc pour le chat de votre jeu pour les performances. Si vous êtes sur le même hardware et que irc fait beaucoup mieux alors c’est que vous avez mal codé votre programme.
Buffer
Le principe basique est d’envoyer le message à tout les clients connectés.  Si le buffer n’est pas assez grand, ou le message/liste de client trop grand, alors votre programme vas être bloqué à chaque écriture dans votre socket et donc ne vas pas pouvoir tourner. Vous pouvez pour contourner cela en l’isolant dans un thread (cela vaut pour tout les autres syscall bloquant) ou passer votre socket en mode non bloquant (plus de travail mais plus de performance).
Packaging
Vous avez plusieurs couche, hélas la plus par du temps vous ne pouvez pas directement accéder au buffer tcp, mais ce que je vais vous dire vaux pour les couches suppérieures. J’ajoute en header un code de packet et une taille, donc pour du broadcast je compose le packet complet (avec header), et je l’envoie, ce qui est bien plus efficace que de le recomposer à chaque fois inutilement (cela demande des fast path dans le code, et une décomposition total pour le controle de la sortie). Le CRC32 du tcp est aussi calculable qu’une seule fois, mais l’OS ne propose en générale pas d’interface pour cela.
Application tiers

Le faite de rajouter un application n’as de sens que si le client se connecte directement a elle et qu’elle est sur un autre serveur, mais personnelement je ne vois pas comment ont peu saturer un serveur irc ou un chat avec un usage normale. Le faite de communiquer entre le serveur et un autre serveur rajoute une couche tcp et de message qui fait plus de consomation cpu/réseau/mémoire.

Ces principes valent aussi pour les déplacements des joueurs qui sont aussi envoyé d’un block à tout les joueurs dans la même zone.
PS: avec un « \0 » bien placé ont peu cacher des données dans le chat de maniére discréte

CatchChallenger 2 et passage sur C++11

Salut,

J’ai fini la partie cluster de CatchChallenger 2, la localité des données est vraiment bonne, juste des petites réquetes pour un veroux global non bloquant sur les données communes et des serveurs indépendants. La passerelle avec cache (permet d’exposer un server sur TOR/I2P vers l’internet normal ou l’inverse), et les CDN sont aussi codés. L’infrastructure réseau est donc principalement prête pour fonctionner même dans les pires conditions: réseau trés lent <60Ko/s, ping/latence énorme: >800ms. Ce que semble confirmer les testes que j’ai pu faire via i2p et sur l’internet normal au travers du monde entier.
 
J’ai voulu faire des optimisations particuliérement de refesant le protocole, mais pour avoir un bon bon de vu sur ce qui est lent, j’ai besoin de refaire en C++11 le programme car les conteneur Qt sont lent (32x plus lent pour les chaines). Le version 11 me permet d’avoir accés a plein chose sur les containers, permet au compilateur de mieux optimiser le code, ajoute les regex, timer, temps, être plus portable sans recourrir a Qt. Cela vas me permettre aussi de faire des programmes avec trés peu de dépendance, et donc pouvoir les embarquer et cacher un peu partout. Ce remake vas être très long, surtout car je ne suis pas prêt pour le C++11 et que je doit donc tout apprendre. Ce qui est du standard, il permet de définir un certain nombre de propiété, par exemple les espace mémoire continu pour certain conteneur ContiguousContainer (for T other than bool) (since C++17) ou ContainerAllocatorAwareContainerSequenceContainer and ReversibleContainer tout cela permet d’être pris en compte par le compilateur et donc d’ouvrir des oportunités d’optimisation. Si elle pourront être profité par le compilateur et si elle le seront, seul l’avenir nous le dira. Donc oui, C++17 > C++14 > C++11 > C++99 > C++ pour les performance.
On pourra potentielement imaginer de puissant assitant de preuve avec les nouveaux standard pour détecter les failles potentielles, les cas de buffer overflow, … il ne feront pas tout, ce n’est qu’un outils, mais cela limitera les failles basiques, enseignera les bonnes habitudes.
 
J’ai mon portable datacenter qui est en ARM, ce qui me permet de tester mon jeu sur différente architecture (avec x86 sur Intel Atom z530 et AMD Geode LX800, et x86_64 Intel haswell) et tracker les possibles régréssions. J’ai ouvert les options de compression et rajouter lz4 pour comblé un vide, sur ARM les performances été desastreuses, j’ai donc ouvert quelques noeux pour l’auteur de xxhash et lz4, Yann Collet, que je salut en passant, qui as optimisé ces derniers pour ARMv6 et ARMv7.
Les changements pour le support des clusters sont donc fait, il reste ceux pour la portabilité, un énorme remake sur le protocole pour optimiser le parsage des packets. Il faut toujours différencier le format/algo/protocole de l’implémentation (comment c’est codé). C’est comme une maison, les plans peuvent être super mais la réalisassion pas génial.

 

 

 

Cluster ARM

arm-cluster
Cluster arm, cubox im cubieboard, rpi, odroid

Salut,

Je souhaite revenir sur quelque mois d’utilisation intensive de mon cluster ARM. L’image n’est pas celle actuel mais donne une idee de mon portable datacenter.

Je trouve dommage que pour avoir java 8, il faille utiliser le java de oracle et que ce dernier n’est pas actualisé et donc potentiellement avec des failles. Java est une technologie qui permet de faire fonctionner une application que vous soyez sur ARMv6, v7, x86. Mais cela ajoute une abstraction assez casse pieds qui bloque l’accès a certain truc spécifique de l’OS et ne permet de de descendre aussi bas dans le optimisation que en c/c++.

Nagios est performant, munin est pourri cote performance et plombe ces propres mesures (Surtout a cause du spawn de processus). Le backup sur une node en btrfs, le but étant d’avoir des backups différentiel.

Il faut faire très attention à la bande passante inter processus/thread qui est très réduite, sans même parler des communication externe. Donc il vaut mieux privilégier plusieurs processus mono thread qui travaille en local sur leur données locales que du multi-thread qui passe plus de temps à faire tourner les données entre plusieurs threads et se coordonner le travail que à travailler. L’ordonnanceur cpu vas naturellement repartir chaque processus par cpu (base de donnée, noyau, serveur authentification serveur de jeu). Le multi-thread peu être simpa si vous avec qu’un service sur un matos multi coeur (votre base donnée sur un quadcore, bien que dans ce cas l’ordonnanceur disk, le FS et le disque en lui même auront plus d’influence). Mon programme est plus simple est bien plus rapide sur ARM vu que je n’utilise pas de verrou, et je fait juste tourner plusieurs serveur en parallèle. Le joueur n’as plus qu’as jouer sur le même serveur que ces amis, ce qui déporte le problème du multi-thread sur l’humain. Cela permet que le serveur consomme 10-50x moins de cpu que le noyau linux pour gérer les packet tcp.

Grsec combiné à certain manque d’optimisation sur ARM (hardware comme software) fonds que certaines fonction sont bien plus lente (memcpy() vs accès non aligné, presque aucune différence de performance sur x86, ARM + grsec 7x plus performant sur les accès non aligné). Une taille fix en mémoire de l’application aide à ne pas faire de pression sur le code de gestion de la mémoire.

La consommation et prix de la puce est défini par le nombre de transistor dans la puce. Si vous avec une puce trop généraliste vous perdez sur cela, par exemple j’ai pas besoin du GPU ni du FPU pour mes serveur. Par contre j’ai besoin de l’ALU et des unités SIMD. J’aurai aussi besoin d’ASIC AES et SHA224, un générateur de nombre aléatoire pour optimiser la partie cryptographique des applications (connexion des utilisateurs, des serveurs aux bases de données, des serveurs entre eux). La communication chiffré est de nos jours obligatoire, donc le volume transmit via une connexion chiffré même établis en permanence a un impacte sur les performances, les accélérateur hardware se rapporte à un système de chiffré qui hélas se font brisé de plus en plus rapidement). Je n’est presque jamais vu d’accélération sur la compression, si cela est possible. Pas mal de puce ont démontré un meilleur ratio GFLOPS/W car leur circuit sont fix et optimisé. (GPU passage de statique, partiellement programmable, totalement programmable)

Finalement les performances son bien meilleur que un gros serveur x86 (15x la vitesse de la DDR3), plus de sécurité car il y as beaucoup moins de vm par hardware car il y as plus de hardware pour le même prix/consommation énergétique. Je suis très content de mon cluster MMORPG sur ce cluster qui peu tenir d’apres mes testes en gardant beaucoup de marge 30 hardware*4 cpu*100k utilisateur=12 millions de joueur pour moins de 100W.

Longueur idéal de token (jeton)

Bonjour,

Je vais couvrir une partie peu couverte sur le web: quel est la longueur idéal d’un token (jeton)?

Pour qu’il soit réutilisé (piraté) il faut qu’il y ai une collision, c’est à dire que le nombre aléatoire corresponde à celui que l’ont est de notre coté. Cela ne sert à rien d’avoir une grosse longueur si les nombres aléatoires générés sont de mauvaise qualités, car il pourrons être prédit.

Calcule

Avec 32 octets, soit 256Bits, il y as 1.15792089237e+77 possibilité, considérons que l’ont vas tomber par chance sur le bon token dés les 1er 0.01%, il faut donc tester: 1.15792089237e+77/10000=1.15792089237e+73, sachant que un token fait 32 octets et qu’il y as 1.15792089237e+73, cela fait: 1.15792089237e+73*32 donc 3.70534685559e+74 octets à tester. Soit 3.36999333339e+62To à tester. Ce qui corresponds à 1.17495778018e+59 années (oui 59 zeros) avec un réseau 1000Mbps. Les tokens plus grands que 32Bytes me semble inutile.

Plus petit?

Ne connaissant pas les futures innovations technologique (memristor, remplacement du silicium par quelque chose sans vrai limite de fréquence, loi de moore, …), sachant que la courbe est exponentiel (division par 2 réduit fortement la sécurité), sachant que un protocole est difficile à changer, que les futures matériel auront tous les générateurs de nombres aléatoires (voir wikipedia)… Je pense qu’il ne faut pas tomber en dessous de 16 octets, soit 128Bits. Si vous l’envoyé par le réseau en binaire, comptez 60 d’entête (header) tcp donc même avec 32 octets c’est votre entête tcp qui prendra tout la place (inutile donc de diminuer plus pour économiser du réseau).

Plus grands?

Après un certain moments cela n’est plus utile, les temps explose, les risques de collision sont presque null. Ne pas oublier que après 64 octets la taille ce fait sentir sur des packets réseau ne transportant que le token. Si vous n’avez pas de générateurs de nombres aléatoires (voir wikipedia) hardware comme sur les vieux matériel ou bas de gammes et que vous être sur un serveur, il y aura peu d’entropie (voir wikipedia). Donc dépasser 64 octet me semble inutile.

Conclusion

32 octets me semble un bonne taille en générale pour un bonne sécurité. Si la duré de vie du token est limité, si la sécurité n’est pas trés importante, si c’est juste utilisé pour switcher d’un serveur à l’autre dans un temps imparti vous pouvez utilisé 16 octets. Si la sécurité est critique et que le token est stoker et pas généré dynamiquement jusqu’as 64 octets peuvent être utilisé. Je met à part les clef privé (128-512 octets ou +) car les implications sont pas les mêmes et que je suis pas sur de maîtriser le sujet. J’utilise /dev/random pour les clefs/tokens stockés, et /dev/urandom pour les tokens dynamiques.

Je m’en sert pour ajouter un salt dynamique avec le mot de passe et comparer les hash coté server (envoie du token serveur -> client, hash, résultat client -> serveur). Le token n’étant jamais le mêmes la personne ne peu répété les packets réseau, cela permet d’authentifier la personne sans que le mot de passe puisse être intercepté ou répété.

Lien sympa:

CatchChallenger 2 et cluster

CatchChallenger 2 introduit l’infrastructure de cluster. Ce qui implique des changements coté datapack (base commune pour faire tourner les avatars entre les serveurs, et partie spécifique), les changements sont principalement fait. Des changements coté base de données, qui en plus d’avoir les obligations du datapack se doit d’être performante et de marcher sans les auto increment pour les index (pour les bases ne le supportant pas), il y aura encore des changements.

Pour les serveurs, je tiens à garder le serveur Qt (avec une interface et de beaux boutons) pour faciliter la mise en place de petit serveur perso, et le serveur epoll linux simple en CLI pour des serveurs moyens. Le faite de n’avoir qu’un exécutable, une base de donnée et un port à ouvrir rends simple l’utilisation du serveur mais cela permet aussi de ce passer d’une surcouche de communication inter-serveur qui peu être coûteuse en performance.
Le mode cluster ce compose de 2 types de base de données distante (login et common) qui vont être accédé par plusieurs serveurs. Et une base de données spécifique par serveur (qui peu être distante ou non). Il y a des serveurs de login pour gérer l’authentification, le changements de la liste des avatars, création d’avatars et de l’envoie de la base du datapack. Il peuvent servir de proxy pour que le joueur ne doivent pas se reconnecté sur le game serveur (meilleur anonymisation car les ip des games serveurs ne sont pas connu, mais à cause des connexions maintenu ouverte cela à un coût). Un serveur master qui est responsable d’unifier les configs qui ne doivent pas varier en fonction du serveur, d’avoir une base datapack unifié et d’avoir un point de centralisation pour poser les verrous sur les avatars. Il n’est connu que des serveurs login et game. Les games serveurs sont la où joue les joueurs. Si les joueurs sont directement connecté sur les games serveur, les logins serveurs peuvent être coulé par une attaque DDOS sans que les joueurs déjà connecté soit affecté.
Status map du portable datacenter avec nagios pour CatchChallenger 2
Status map du portable datacenter avec nagios pour CatchChallenger 2
La communication inter-serveur n’est pas facile sachant qu’il faille tenir compte des RTT car les serveurs au quatre coin du monde vont avoir des latences de communications. La bande passante peu être limité dans un pays en voie de développement ce qui rends la compression obligatoire. La cryptographie l’est pour certifier que les serveurs autorisé peuvent bien ce connecter entre eux et que les données ne puisse être intercepté (idem pour les bases de données). La modification dynamique de l’infrastructure doit être pris en charge pour ajouter ou retirer à la demande des logins ou games serveurs sans rien redémarrer. Les serveurs doivent se comporter comme un cluster. Il faut prendre en compte aussi les possibles déconnexion temporaire avec le master serveur. C’est la ou l’asynchronisme surtout coté base de données prends tout sont sens.
Pour idéalement une bonne portabilité sur tout les environnements mais aussi de bonne performance (le QDataStream + QByteArray de Qt à beau être sécurisé et très commode, il est extrêmement peu performant), le passage d’un maximum de code en C++11 et surtout les sérialiseurs (avec des buffers pré-allouer pour éviter des pressions sur la mémoire à cause de new/malloc trop fréquent) est en cour. Mais je ne pense pas pouvoir tout bouclé pour la version 2 donc la dépendance avec Qt sera toujours de mise. Le passage en C++11 me permet un certain nombre de chose via la norme même, et me force à faire du code souple Qt <-> C++. Cela permet aussi d’exploiter les parties spécifiques à l’OS qui est totalement abstraite en Qt et donc qui n’est pas accessible. Je pense aussi à libOS qui veux être dans la branche principale de linux, j’ai un peu peur de cela car certain dev newbies ont tendance à vouloir le contrôle sur tout, soit car il ont entendu que ça augmenterai les performances (ce qui est vrai seulement si ont sais s’en servir) ou simplement pour se sentir aux commandes (en oubliant la sécurité, et l’isolation des taches). Sans parler que refaire un ordonnanceur, un driver, … et le maintenir est une grosses charge supplémentaire qui fait exploser le développement à faire. Idéalement si le master serveur et les logins serveur font 10Mo et utilise 1Mo de mémoire ou max <10Mo ça me vas.
Un support de NoSQL ne me semble pas réaliste ainsi que les requêtes préparé pour cette version. Par contre vu que MySQL 5.5+ ce généralise je verrai si j’ai le temps de faire le support de MySQL en asynchrone.
Le portable datacenter continue à grandir, ayant changé ma connexion pour 2M en download et upload, cela me permet de faire un peu d’hébergement (site + 200 joueurs). Peu de services sont visibles mais pas mal de service en background sont la. Il continue à être un mix de machine légère (rpi 1, cubieboard2, ordoid u3, cubox-i, fit pc 1…, donc Geode LX800, Cortex A9, ARM1176JZF-S, Cortex A7, de 1 à 4 coeur par config). Le tout monitoré sous nagios + munin. Avec un peu de btrfs, beaucoup d’ext4. Lxc + grsec comme système de virtualisation, et gentoo en -march=native pour les hôtes et -march=native pour les hardwares où j’ai de multiple exemplaire et -march=generic pour les autres. Cela me fait un bon parque pour faire de l’auto benchmarking.

 

 

btrfs vs overlayfs

Bonjour,

Btrfs est un systéme de fichier avec des fonctions évolué telque la compression, le support du raid, la déduplication, la gestion de multiple volume (pour booster le FS avec un SSD), les snapshots pour faire les backups et ne garder sur le hdd que les différence entre 2 snapshots…. ZFS est une alternative, mais ce n’est pas dans la branche principale de linux.

Overlayfs est une virtualisation du FS qui permet d’avoir un dossier de base, et une multitude variation de ce dernier. Cela est surtout utilisé dans les livecd, cela permet d’avoir une image fix (le cd), et une zone d’écriture (ramdisque, tmpfs), ce qui permet à l’utilisateur d’avoir l’impression d’avoir une version installé car il peu tout modifié (et donc les changements sont gardé en mémoire RAM grace à overlayfs). Il existe comme alternative aufs, unionfs, … mais seul overlayfs est dans la branche principale de linux.

Les machines virtuelles sont souvent trés similaire. J’ai donc testé ces 2 solutions pour monté des machines virtuelles:

  • Btrfs ne permet pas la déduplication de dossier (il vous avec 10000 fichiers identique dans un dossier, la liste de 10000 sera stocker 2x). La déduplication ne s’applique pas aux fichiers inline (petit fichier surtout). Il m’as fait perdre des vm pour ces divers bugs (vm de teste donc pas de backup). La réparation peu bloquer pourtant le FS est montable, … il faut donc le backuper, reformater et restaurer: un comble que la réparation ne marche pas. Par contre la compression est utile sur les petits espaces ou pour augmenter virtuellement la vitesse du média sur le fichiers compressible (carte SD 😉 mais en échange de latence un peu plus grande surtout sur les petits fichiers). Les backups temps réél avec juste sauvegarde des différences et la déduplication (même si elle est partiel) sont un plus.
  • Overlayfs ne déduplique pas, cela veux dire que 2 fichiers changés au dessus du dossier de base vont être stocké 2x sur le hdd. Donc si vous mettez à jour vos vm, la différence des mise à jour est stocker X fois. Mais c’est trés stable sur du ext4. La variation stocker est vraiment minime et permet de gagné vraiment beaucoup de place (c’est presque comme si vous stockiez les sites que vous y mettais).

Au final, quelle solution j’utilise? Aucune, les défauts de chaque solution sont trop grandes pour être utilisé en production. Donc ext4 pour les serveurs de prod, et btrfs + snapshot pour les serveurs de backups.

Ssl et serveur de MMORPG

Bonjour,

Je suis en train de mettre en place l’infrastructure pour commencer dans la prochaine version le supports des clusters.

L’overhead (qui est assez couteux sur http1) de la couche Ssl est peu important sur un serveur de type MMORPG car il garde la connexion ouverte. Par contre, à cause des petits packets envoyé à intervalle éloigné (ont de peu donc pas les grouper), la couche Ssl deviens extrêmement lourde. Le ralentissement vis à vis d’une connexion en claire est de 24x sur un Intel haswell (avec prise en charge matériel).

Les syscall pour les events des trames réseaux sont trés correcte et ont un coût minimum car il sont multipléxé sur epoll avec linux. Ca semble un peu du bricolage pour les timers, … je veux même pas voir d’autre syscall… Par contre une lecture/écriture sur un socket = un syscall, ce qui peu devenir très lourd rapidement. Une suggestion sur le problème C10M est de by-passer le noyau, cela oblige de ré-implémenté TCP, c’est trop dangereux et dur pour être fait (hors mit cas spéciaux). Par contre un syscall pour multipléxé les entrées/sorties sur socket peu être utile.

Comment bien découper votre serveur pour avoir un cluster de serveur? Déjà il faut l’avoir bien optimisé pour maximiser le ratio utilisateur par serveur/nombre de serveur. Car le mode cluster à un cout. Ensuite balancer via un round-robin dns sur plusieurs frontaux (cela permet de s’affranchir de HAPROXY, ou tout autre système qui serai à notre charge et moins fiable). Hors mit les clients, les frontaux doivent avoir le minimum de connexion, alors n’utilisez pas de maillage, mais une structure de serveur en arbre. Dans le cas de CatchChallenger cela vas être une connexion pour la base de données, et une connexion pour un serveur racine (chargé de broadcast, ou de passé le client sur un autre serveur via reconnexion pour séparer les serveurs: une groupe de serveurs = un groupe de maps dans la même zone). La découpe vas influer fortement sur votre cluster, spamer des threads dans tout les sens et n’importe comment vas ralentir votre serveur (apache worker vs nginx/lighttpd). Je vous conseiller d’attaquer votre db en asynchrone, et qu’elle ai plusieurs frontaux. Vous pouvez coder la communication inter-serveurs en claire, et faire des tunnels de communications crypté via openssl pour sécurisé l’échange. Cela permet un maximum de performance sur un réseau de confiance, et de la sécurité sur internet.

Ssl fourni une compression activé par défaut. Je trouve cela assez mauvais, car la compression devrai être séparé de la cryptographie. Pour une question de sécurité, mais aussi de fléxibilité: toutes les formes de compression ne sont pas disponible (xz), et certain protocole comme CatchChallenger à sa propre compression adaptative interne qui est bien plus efficace. La compression devrai être donc si disponible, désactivé par défaut (bien que mon opinion n’est pas tranché sur ce point). La compression, même gzip/zlib doit avoir au moins 100 octets pour être efficace, hors la grosse majorité des packets de CatchChallenger fait moins de 6 octets. Et le reste est compressé…

J’espère vous avoir aidé.

Optimisation dans CatchChallenger

Salut,

J’ai fait de grosse optimisation dans CatchChallenger. J’ai composé le packet pour ensuite l’envoyer sur chaque client au lieu d’envoyer les variables et que chaque client compose le même packet. Cela donne un gros coup de boost sur les fonctions de type broadcast.

Ensuite j’ai fait une boucle ou j’appelle tout les clients, et j’ai connecté un QTimer dessus. Cela est bien plus efficace que de connecté ce timer sur chaque client (8x de performance).

Moins vous allez accéder à de grosse quantité de mémoire, plus il vont tenir dans un cache CPU performant, et donc vous allez gagner en performance (évitez d’allouer la mémoire aussi, si non RTT), sur mon haswell (pris grace à memtest86+):

  • 64Ko L1 202 427Mo/s
  • 256Ko L2 52 675Mo/s
  • 6144Ko L3 37 592Mo/s (répartie entre tout les cpus)
  • 8239Mo Mémoire 9 375Mo/s
Autant vous dire tout de suite, les performances pour un serveur MMORPG même bien fait, c’est:
  • à vide (<20 joueurs) utilisation du L1 trés performant
  • charge moyenne (<100 joueurs) utilisation du L2/L3
  • à forte charge (>2000 joueurs) utilisation de votre mémoire bien lente même si vous avec GDDR5/DDR4 avec un grosse fréquence en comparaison des caches interne (surement dans ce cas que votre config tirerai partie d’un mémoire rapide)
Et pourtant je fait passé sans problème le serveur de MMORPG sur un Intel Atom ou un Cortex-A9 à 1Ghz avec 6000 joueurs (charge simulé en les répartisant sur map map, avec les pires réglages, en débug, et avec génération de chat, déplacement, …). Hors mit les hash qui peuvent être consommateur de CPU, le reste de mon code utilise des variables/tableaux de variable avec presque aucun calcule dessus, donc le temps est passé à attendre la mémoire.
Pour finir, je constate même à l’heure actuelle, 99% du temps pris pas la gestion des events de Qt. Je ne sais pas encore si il y as un truc à faire pour mon cas (pas mal d’objet connecté entre eux pour un même client), ou si je vais devoir m’orienter vers un autre système d’event et donc réseau (boost?).
Limiter la fragementation mémoire aide à avoir des création d’objet et allocation mémoire plus rapide.
Bye,

Squashfs vs tar.xz

Bonjour,

Vous allez peu étre un jour vous demander la différence entre Squashfs et un tar.xz… Voila la réponse.

Squashfs est compressé par block, ce qui permet de seeker (sauter) d’un endroit à l’autre, comme sur un disque dur. Et donc d’aller lire et décompresser que certains fichiers que vous être en train de lire. Très utile pour stocker un OS, ou un site. Le taux de compression est donc moins bon.

Le tar.xz compresse toutes les données dans l’ensemble. Vous devez donc tout décompresser pour lire quelque fichiers. Pour un live CD, cela veux dire que vous devez décompresser tout le contenu en mémoire vive pour l’utiliser. Utile pour l’archivage, ou l’ont doit tout décompresser à chaque fois. Mais le taux de compression est optimal.

Pour juste les html pris du site bulbapedia:

  • Non compressé: 4500Mo et 43000 fichiers
  • squashfs: 194Mo
  • xz compression 6: 141Mo
  • xz compression 9: 93Mo

En espérant vous avoir éclairé.