lundi 18 mars 2013

Remplacer Google Reader en 5 minutes et gratuitement


L'annonce de la part de Google de la fermeture du service Reader au 1er juillet 2013 en a perturbé plus d'un car en 7 ans d'existence Goggle Reader s'était imposé comme la solution n°1 pour consulter ses flux RSS et Atom.


Comme tout le monde je me suis mis à chercher des alternatives à Google Reader, il en existe beaucoup (Feedly, Netvibes, NewsBlur,...) mais aucune ne me convenait. Pourtant je ne demande pas grand chose:

  1. Une interface web pas trop chargée
  2. Une appli Android
  3. Une appli Android qui fonctionne en mode offline (les joies du transport en commun)
Et c'est sur le point 3. que ça bloque, je n'ai rien de trouvé de très convaincant mis à part un produit open-source Tiny tiny RSS qui se charge de tout le travail et dispose même d'un client Android gratuit et fonctionnant en mode offline, génial !

Le seul défaut et pas des moindre pour moi est qu'il faut l'installer sur son propre serveur... Pas envie de faire de l'administration de serveur le soir chez moi j'en fais déjà assez au travail, et encore moins envie de payer pour la lecture de flux RSS (je n'ai qu'une cinquantaine de flux).


Et on va faire tout ça en 3 étapes:

  1. S'inscrire à OpenShift
  2. Installer Tiny Tiny RSS
  3. Utiliser l'application Android

Inscription à OpenShift

OpenShift est la solution de PaaS de Redhat (un peu comme Google App Engine). Le gros avantage est qu'elle dispose d'une offre gratuite pour une utilisation raisonnée et c'est de ça que l'on va profiter maintenant.
On commence d'abord par s'inscrire sur OpenShift :



On remplit les champs, on valide l'email et on arrive alors à une page demandant de créer une application. Inutile d'aller plus loin on fera tout ça automatiquement par la suite.


On passe à l'étape 2.

Installation de Tiny Tiny RSS

Installation de rhc

Pour installer notre application Tiny Tiny RSS il faut installer l'outil rhc. Voici comment faire sur Linux Ubuntu (pour les autres systèmes d'exploitation voir la page RedHat dédiée):


$ sudo apt-get install ruby-full rubygems git-core
$ sudo gem install rubygems-update
$ sudo update_rubygems
$ sudo gem install rhc
$ rhc setup


Pour la dernière commande il faudra entrer le nom d'utilisateur (l'adresse mail) et le mot de passe choisit lors de la première étape.

Création de notre application Tiny Tiny RSS

On va ensuite utiliser la commande rhc pour créer automatiquement notre application grâce au travail de who-me :


$ rhc app create <app name> php-5 postgresql-8 \
--from-code=git://github.com/who-me/ttrss-fast-deployment.git
$ rhc cartridge add cron-1.4 -a <app name>


Et voilà l'installation de Tiny Tiny RSS est terminée et on peut se connecter à notre application à l'url http://<app name>-<your namespace>.rhcloud.com :





Le couple nom d'utilisateur / mot de passe par défaut est admin / password (à changer immédiatement bien sûr...).

Configuration

Nous avons notre application de gestion des flux RSS tout propre, toute neuve mais elle fait un peu vide quand même ! Pour la remplir nous allons exporter nos données de Google Reader. Pour cela utiliser le service Google Takeout qui vous permettra de récupérer vos données sous la forme d'une archive zip.

Le fichier qui nous intéresse dans cette archive se nomme subscriptions.xml et va nous servir à intégrer dans Tiny Tiny RSS tous nos flux RSS.

Pour cela dans Tiny Tiny RSS aller dans "Actions..." > "Preferences" > "Feeds" > "OPML" et sélectionner le fichier subscriptions.xml :





Tant que l'on est dans les préférences on va également activer les API externes pour le client Android Dans l'onglet "Preferences" au paragraphe "General" changer la ligne "Enable external API" à "Yes".


Et voilà terminé pour l'installation de l'application ! On passe à la partie Android !

Utilisation de l'application Android

Sur Google Play installer l'application nommée TTRSS-Reader de Nils Braden (ne pas prendre l'autre, elle ne fonctionne que 7 jours) et l'installer.

Au niveau des préférences de l'application entrer l'url de votre serveur (http://<app name>-<your namespace>.rhcloud.com normalement), le nom d'utilisateur et le mot de passe. N'activer pas le mode "Lazy Server" j'ai eu des problèmes avec. De même ne mettez pas de quote (') dans le mot de passe cela semble poser problème.


Et voilà vous avez un client Android qui fonctionne en mode déconnecté:





Bon, je l'admet les cinq minutes c'était uniquement pour appâter le chaland mais malgré tout vous voilà avec une solution viable, gratuite et qui ne s'arrêtera pas le 1 juillet !


Amusez-vous bien !


Post 8/52

samedi 9 mars 2013

Ajout d'un syntaxe highlighter à Blogger



Blogger est plutôt sympa mais il manque un truc essentiel pour un geek, un syntaxe highlighter pour que vos extraits de code ne ressemble pas à rien !

Pour ajouter ça à Blogger c'est plutôt simple, on va utiliser pour cela un script externe fait par un Googler (on reste dans la même crêmerie...): Prettify.
Prettify est composé d'un module Javascript et d'une classe CSS permettant de colorer un grand nombre de langages et cela de manière très légère. Il est égalemment modifiable via quelques styles CSS fournis (et si ça ne vous plait toujours pas le code source est disponible).
Actuellement Prettify est utilisé sur code.google.com et stackoverflow, pas mal comme références !

Installation

L'installation se déroule en une étape et on est tranquille ensuite. Il faut aller dans la partie "Modèle" de votre blog et appuyer sur le bouton "Modifier le code HTML":







Puis repérer la balise "</body>" et insérer la ligne suivante juste avant:


<script src="https://google-code-prettify.googlecode.com/svn/loader/run_prettify.js"/>


On sauvegarde et c'est terminé !

Utilisation

Utilisation Basique

Vous pouvez ensuite poster un nouveau message bien geek et lorsque vous voudrez ajouter de la coloration syntaxique il suffira d'ajouter les balises suivantes autour du contenu à modifier (en mode "HTML" bien sûr):

<pre class="prettyprint">
<?php
    echo "Hello World!"; 
?>
</pre>

Résultat:

<?php
echo "Hello World!"; 
?>

Numero de lignes

Il est possible également d'ajouter les numéros de lignes en marge du message. Pour cela il faut ajouter "linenum" à la balise pre précédente:

<pre class="prettyprint linenums">
<?php
echo "Hello World!\n";
echo "Les numéros de ligne sont affichés toutes les 5 lignes.\n";
echo "Cela peut être modifié dans la feuille de style.\n";
?>
</pre>

Résultat:

<?php
echo "Hello World!";
echo "Les numéros de ligne sont affichés toutes les 5 lignes.\n";
echo "Cela peut être modifié dans la feuille de style.\n";
?>

Spécifier un langage particulier

Prettify fait son maximum pour détecter le langage utilisé mais on peut lui faciliter la vie en précisant le langage présent entre les balises <pre>:

<pre class="prettyprint lang-dart">
library hi;

import 'dart:html';

main() {
  query('#status').text = 'Hi, Dart';
}
</pre>

Résultat:

library hi;

import 'dart:html';

main() {
  query('#status').text = 'Hi, Dart';
}


Post 7/52

Memcached: optimisation


Cet article fait partie d'une série de trois posts sur Memcached. Il fait suite au premier article: "Memcached: principe de fonctionnement" et au deuxième article: "Memcached: Gestion de la mémoire".
Troisième et dernier article sur Memcached et on finit en beauté: comment optimiser son Memcached afin de faire toujours plus avec la même quantité de mémoire !

Optimiser l'utilisation de son Memcached

Superviser son Memcached

Avant de modifier les paramètres de son Memcached il faut d'abord pouvoir les observer afin de vérifier que ce que l'on fait améliore effectivement les choses.

Pour cela deux options faciles:

  • utiliser l'interface telnet fournie afin d'obtenir des informations sur le serveur. Les informations intéressantes sont fournies par la commande "stats" et "stats slabs"
  • utiliser un script PHP affichant de manière un peu plus sympathique l'état du Memcached. Ce script est disponible sur le blog de l'auteur.






Les informations qui nous intéressent sont le compteur d'éviction (accessible uniquement via l'interface telnet) et le nombre d'éléments par slabs (via la commande "stats slabs" ou le bouton "variables" de memcached.php):





Quelques conseils

Afin de tirer le meilleur partie de Memcached il faut vérifier que:

  1. Les dates d'expiration ont été correctement paramétrées ; rien ne sert de remplir la mémoire avec des éléments inutiles. Vérifier pour cela le pourcentage de hit sur vos get memcached si celui-ci est trop bas soit vous n'avez pas assez de mémoire pour stocker tous vos éléments soit vos durées d'expiration sont trop courtes.
  2. Les données sont réparties harmonieusement au sein des slabs: si vous avez un slab qui contient 90% des éléments il peut être intéressant de partitionner plus finement ce slab en jouant sur les paramètres -n (plage de début) et -f (facteur d'augmentation). Voir à ce sujet l'exemple ci-dessous
  3. Vérifier régulièrement la taille des objets que vous stockez dans Memcached car au fur et à mesure que votre application s'étoffe il se peut que la taille des données stockées dans Memcached augmente et que les paramètres initiaux ne soient plus adaptés.
J'ai mis en pratique récemment le conseil numéro 2: il faut savoir que sur mon projet actuel nous utilisons énormément Memcached mais que les paramètres mis en place datent de plus de 4 ans et que le projet n'a plus grand chose à voir avec ce qu'il était à l'époque.
En étudiant l'un des Memcached voici ce que j'ai pu constater:

  • De nombreuses évictions (1 par seconde en moyenne)
  • 65 000 objets max stockés dans le Memcached
  • Une distribution sur les différents slabs complètement disproportionnée:



Avec -n = 8000 et -f = 2


On voit clairement sur le graphique que le premier slab contient l'immense majorité des données. Le paramètre de taille initiale du slab a été visiblement mal choisi et il faut l'affiner.
La principale conséquence de ce choix est que l'on utilise 8 kio de mémoire pour tous les objets stockés dans Memcached alors que ceux-ci font en moyenne entre 3 et 4 kio (soit 50% de mémoire perdue à chaque fois!!) ce qui implique que l'on ne peut stocker que peu d'informations.
On voit bien ici l'importance de connaître ses données afin d'optimiser au mieux les paramètres.


Nous avons donc modifié les paramètres comme suit:

  • Diminution de la taille du premier slab de 8000 octets à 1000 octets afin de mieux découper l'espace où se trouve nos données
  • Même facteur d'accroissement
  • Même mémoire allouée






Les conséquences de cette modification:

  • Peu d'évictions (Quelques centaines par jour)
  • 125 000 éléments stockés dans Memcached (pour la même quantité de mémoire allouée !!)
  • Une distribution mieux répartie
On peut se dire au vu du graphique qu'il est encore possible de faire mieux en diminuant le facteur multiplicatif afin de décomposer encore plus le slab3 en de multiples slabs. Cette solution n'a pas été retenue car nous souhaitions garder une relative flexibilité dans la taille de nos données qui sont amenées à bouger régulièrement et donc nous focaliser sur la tranche 3 à 4 kio nous semblait trop réducteur pour les développements futurs de l'application.


C'est ainsi que se termine cette série de trois articles sur Memcached un outil fantastique pour améliorer les performances et la scalabilité de votre application.




Quelques liens intéressants:

Post 6/52

vendredi 8 mars 2013

Memcached: Gestion de la mémoire


Cet article fait partie d'une série de trois posts sur Memcached. Il fait suite au premier article: "Memcached: principe de fonctionnement"

Deuxième article sur Memcached et on passe aux choses sérieuses, la gestion de la mémoire par Memcached !


Gestion de la mémoire par Memcached

Expiration

En fonctionnement nominal la mémoire utilisée par les éléments expirés dans Memcached n'est pas réclamée activement. Ainsi même si l'élément est expiré alors sa mémoire ne sera pas libérée immédiatement.
Un cas particulier arrive quand on essaye de récupérer un élément expiré. Dans ce cas Memcached va se rendre compte que l'élément est expiré et libérer immédiatement la mémoire utilisée.

Insertion d'un élément dans le cache

Lorsque l'on ajoute un nouvel élément dans Memcached celui-ci vérifie un certain nombre de choses:

  • Étape 1: Reste-t-il de la place dans la page courante ?
  • Étape 2: Reste-t-il des pages mémoires non allouée à un slab ?
  • Étape 3: Déclenchement de l'algorithme LRU

Étape 1 : affectation simple

 

Cette étape est la plus simple et la plus classique: s'il reste de l'espace dans la page courante alors on utilise un chunk de cette page pour stocker notre élément.
Rien de bien compliqué ici !


Étape 2 : assignation d'une page

 

Nous arrivons dans cette étape s'il n'y a plus de chunk libre dans la page courante. A ce moment Memcached vérifie s'il lui reste des pages mémoire de 1 Mio non affectée au slab courant et si c'est le cas alors il assigne une plage libre au slab courant.
En faisant cela il découpe également cette page en chunk de même taille et utilise un de ces chunk pour stocker l'élément à insérer.


Attention : une fois qu'une page est assignée à un slab cette page ne peut plus être affectée à un autre slab.


Étape 3 : LRU et éviction

 

S'il n'y a plus de chunk ni de page disponibles alors Memcached va commencer à libérer de l'espace en utilisant un algorithme de type LRU (Least Recently Used). Le principe de cet algorithme est de maintenir une liste d'éléments par date d'utilisation. Ainsi un élément peu utilisé apparaîtra dès le début de cette liste. Memcached va alors parcourir les premiers éléments de la liste et libérer l'espace utilisé par un élément expiré.


La particularité de Memcached est qu'il ne maintient pas une liste globale listant l'ensemble des éléments mais une liste par slab. Ainsi l'algorithme LRU n'est pas global mais local par slab. Memcached conserve une liste d'éléments par slab:




Ainsi dans le scénario 1 l'algorithme LRU va parcourir le début de liste et supprimer l'élément 2 car il est expiré. Dans le scénario 2 au contraire il n'y a pas d'élément expiré dans les premiers éléments de la liste, Memcached va alors "évincer" le premier élément même si celui-ci n'est pas encore expiré. Cette action se nomme une eviction.


Habituellement on n'aime pas trop les évictions car elles correspondent à la suppression d'un élément encore valide dans Memcached. Néanmoins sur certains environnements où la mémoire est limitée ou la quantité d'éléments à stocker est très important il est intéressant de s'appuyer sur ce mécanisme pour conserver dans le Memcached les éléments les plus couramment utilisés et supprimer les autres.


Ce mécanisme fonctionne bien en général mais il peut arriver que malgré tout Memcached manque de mémoire et soit incapable d'en retrouver:
Supposons que l'on dispose de 3 slabs : slab1, slab2 et slab3.
Au démarrage du processus memcached tous les éléments sont insérés dans le slab1 et le slab3 et toute la mémoire allouée à Memcached est utilisée. A ce moment si l'on insère un nouvel élément dans le slab1 ou le slab3 le mécanisme de LRU va se déclencher pour libérer de la mémoire et donc stocker notre élément.






Mais imaginons que l'on souhaite insérer un élément dont la taille le destine à être stocké dans le slab2. Comme il n'est pas possible de réaffecter une page à un autre slab, nous ne pourrons jamais insérer notre nouvel élément dans Memcached et une erreur est renvoyée:




Cette exemple montre bien qu'il est primordial de bien configurer son serveur Memcached afin d'en tirer le maximum. C'est ce que nous allons voir dans la troisième et dernière partie: "Memcached: optimisation".

Posts  5/52 

mercredi 6 mars 2013

Memcached: principe de fonctionnement


Cette article est le premier d'une série de trois qui a pour but de présenter Memcached, la gestion de la mémoire et les optimisations possibles.


Présentation

Comme le dit si bien Wikipedia:
"Memcached est un système d'usage général servant à gérer la mémoire cache distribuée. Il est souvent utilisé pour augmenter la vitesse de réponse des sites web créés à partir de bases de données."


Le principe ici est que plutôt que d'aller chercher régulièrement certaines données en base il vaut mieux conserver cette donnée dans la mémoire afin de pouvoir y accéder plus rapidement. De la même façon on peut stocker ainsi le résultat de calculs couteux , des données à écrire en base (pour de l'écriture asynchrone) ou encore des pages web.


Comme indiqué précédemment Memcached est un outil de stockage des données en mémoire de type clé - valeur. La principale conséquence de cela est que si la machine s'arrête on perd l'ensemble des données stockées dans Memcached. Il ne faut donc pas stocker les données importantes uniquement à cet endroit.


Ceci étant dit, Memcached est un outil fantastique pour améliorer la vitesse d'un site pour la bonne et simple raison qu'il est beaucoup beaucoup plus rapide d'accéder à de la mémoire qu'à un disque dur. Voici quelques ordres de grandeurs de temps d'accès:

  • 100 ns (10-7 s): temps d'accès à la mémoire
  • 10 000 000 ns (10-2 s): temps d'accès à un disque dur
Et tout de suite on voit que la mémoire est 100 000 fois plus lente qu'un accès disque disque... Bingo plein de perf' !


L'idée générale de Memcached est d'offrir un outil simple mais très performant afin de profiter au maximum de la vitesse de la mémoire. Il est possible d'accéder à Memcached via la majorité des langages utilisés à l'heure actuelle.

Principe de fonctionnement

Au moment du lancement du processus memcached on lui assigne une taille maximale (via le paramètre -m). Cet espace mémoire est ensuite découpé en page d'une taille fixe de 1 Mio (par défaut). La première conséquence de ce découpage est que l'on ne peut pas stocker dans Memcached des éléments de plus de 1Mio.


Ensuite Memcached découpe ses pages de 1 Mio en éléments appelés des chunks. Un chunk est un espace mémoire de taille fixe qui va stocker la clé, la donnée associée et quelques infos destinées à Memcached. Si l'on spécifie par exemple une taille de chunk de 96 octets (paramètre -n) alors tous les éléments d'une taille (taille de la clé + taille de la donnée + métadonnée Memcached) inférieure à 96 octets occuperont un espace de 96 octets en mémoire.


Tous les éléments d'une même taille sont stockés dans une classe slab. Ainsi notre premier slab contient tous les éléments d'une taille comprise entre 1 et 96 octets.

Lors de l'insertion de la première donnée dans Memcached celui-ci vérifie d'abord à quelle classe appartient l'élément inséré puis décompose une page de 1Mio en chunks de la taille des éléments du slab.
Par exemple avec notre slab contenant des éléments de 96 octets, Memcached découpe sa page de 1 Mio en 10 922 chunks. Une fois les 10 922 chunks remplis Memcached assigne une nouvelle page de 1Mio au slab.


Dans le cas où l'élément fait plus de 96 octets Memcached détermine la taille du slab suivant en utilisant le facteur d'augmentation (paramètre -f). Par exemple avec un facteur de 2 le deuxième slab hébergera des éléments d'une taille maximale de 192 octets mais ne pourra plus héberger que 5461 chunks.


En lançant Memcached avec le paramètre -vv on obtient la taille des différents slabs ainsi que le nombre de chunks pouvant être stocké par page:


~ $ memcached -vv -f 2 -m 512
slab class   1: chunk size        96 perslab   10922
slab class   2: chunk size       192 perslab    5461
slab class   3: chunk size       384 perslab    2730
slab class   4: chunk size       768 perslab    1365
slab class   5: chunk size      1536 perslab     682
slab class   6: chunk size      3072 perslab     341
slab class   7: chunk size      6144 perslab     170
slab class   8: chunk size     12288 perslab      85
slab class   9: chunk size     24576 perslab      42
slab class  10: chunk size     49152 perslab      21
slab class  11: chunk size     98304 perslab      10
slab class  12: chunk size    196608 perslab       5
slab class  13: chunk size    393216 perslab       2
slab class  14: chunk size   1048576 perslab       1
 
On obtient donc 14 classes dont la taille varie entre 96 octets et 1 Mio et pouvant stocker entre 10 922 et 1 élément(s).


Nous avons donc notre espace de stockage mémoire qui écoute par défaut sur le port 11211. Pour insérer et lire des données il suffit d'utiliser l'un des nombreux bindings disponibles dans tous les langages, par exemple l'extension PHP Memcache:


<?php

$memcache = new Memcache;
$memcache->connect('localhost', 11211) or die ("Could not connect");

// Insert 'data' for 10 seconds in Memcached
$memcache->set('key', 'data', false, 10) or die ("Failed to save data");

$get_result = $memcache->get('key');

var_dump($get_result);

?>
 
Comme on peut le voir on insère des données pour une durée déterminée dans Memcached (maximum 30 jours). Mais que se passe-t-il si malgré tout Memcached vient à manquer de mémoire ?


Il existe alors un ensemble de mécanisme destiné à libérer de la mémoire. C'est ce que nous allons voir dans la deuxième partie: "Memcached: gestion de la mémoire".

Posts  4/52