Sam & Max: Python, Django, Git et du cul » cache http://sametmax.com Deux développeurs en vadrouille qui se sortent les doigts du code Wed, 05 Feb 2014 14:20:37 +0000 en hourly 1 http://wordpress.org/?v=3.3.1 Marre des mots de passe pour push sur git ? http://sametmax.com/marre-des-mots-de-passe-pour-push-sur-git/ http://sametmax.com/marre-des-mots-de-passe-pour-push-sur-git/#comments Tue, 19 Nov 2013 08:36:34 +0000 Sam http://sametmax.com/?p=8013 Vous êtes dans une situation où vous ne pouvez pas utiliser uniquement une clé pour vous authentifier, et il faut taper votre putain de mot de passe à chaque push.

Ça sent le vécu n’est-ce pas ?

Mais bien entendu git vient avec une option bien cachée au fond de son fion pour adresser ce problème :

git config credential.helper 'cache --timeout=3600'

Et votre authentification sera gardée en mémoire pour une heure. Vous pouvez faire :

git config --global credential.helper 'cache --timeout=3600'

Pour l’étendre à tous les repos de votre machine.

flattr this!

]]>
http://sametmax.com/marre-des-mots-de-passe-pour-push-sur-git/feed/ 12
Question d’un lecteur sur le cache et Django http://sametmax.com/question-dun-lecteur-sur-le-cache-et-django/ http://sametmax.com/question-dun-lecteur-sur-le-cache-et-django/#comments Sun, 04 Aug 2013 06:12:36 +0000 Sam http://sametmax.com/?p=7003 Encore un message du formulaire de contact auquel je n’arrive pas à répondre (delivery failure).

> Subject: Idée d’article/Question
>
> Message Body:
> Salut !
>
> Merci pour vos articles décalés et ceux qui sont plus au centre.
>
> J’ai une petite question sur Django :
> Est-ce possible de mettre toutes les résultats de requetes de l’ORM de
Django dans memcached, et de les récupérer / mettre à jour / supprimer ?
> Pour moi ça bloque au niveau de la mise à jour / suppression.
>
> Du coup je me suis dit que vous pourriez faire un article sur les
différentes méthodes de mise en cache dans Django et ce que on peut
faire avec.

Hello,

Oui, c’est possible.

La mise à jour et la suppression du cache a toujours été une des choses
les plus difficiles en programmation, donc c’est naturel de bloquer dessus.

Pour commencer, utilise django-cache-machine ou johnny-cache, qui sont des
surcouche à l’ORM Django avec cache automatique. Ensuite, tu apprendras
à faire le reste à la main petit à petit.

Pour les pages complètes, des solutions qui n’ont rien à avoir avec
Django, telles que Varnish, sont aussi des approches qui permettent de
gagner pas mal en perfs.

Bref, je note ce truc dans la liste des articles à faire.

Sam

flattr this!

]]>
http://sametmax.com/question-dun-lecteur-sur-le-cache-et-django/feed/ 1
Savoir si une page est en cache avec Varnish http://sametmax.com/savoir-si-une-page-est-en-cache-avec-varnish/ http://sametmax.com/savoir-si-une-page-est-en-cache-avec-varnish/#comments Wed, 01 May 2013 07:44:34 +0000 Max http://sametmax.com/?p=5945 Pour savoir si cette feignasse de Varnish a bien fait son boulot voici une petite astuce pour afficher dans les HEADERS de son navigateur la provenance de la page, le cache ou le backend.
Varnish propose dans son wiki cette méthode.


dans le fichier de conf de Varnish:

vi /etc/varnish/default.vcl

et rajoutez ces quelques lignes:

sub vcl_deliver {
        if (obj.hits > 0) {
                set resp.http.X-Cache = "HIT";
        } else {
                set resp.http.X-Cache = "MISS";
        }
}

On redemarre le service pour prendre en compte les changements:

service varnishd restart

Dans le navigateur:

Comme on le voit ici, la page a été servie par le backend, si ce n’était pas prévu il va falloir revoir vos règles.

ATTENTION: Pensez à bien rafraichir votre navigateur pour être sur que ce ne soit pas la page mise en cache par ce dernier qui soit affichée, personnellement j’utilise la version navigation privé de chrome.

flattr this!

]]>
http://sametmax.com/savoir-si-une-page-est-en-cache-avec-varnish/feed/ 2
Changement du cache du blog http://sametmax.com/changement-du-cache-du-blog/ http://sametmax.com/changement-du-cache-du-blog/#comments Mon, 08 Apr 2013 13:06:22 +0000 Sam http://sametmax.com/?p=5641 ce plugin Wordpress (ou alors quelqu'un me l'a recommandé, je sais plus) et j'ai trouvé la motivation pour l'installé ce matin.]]> Vu qu’on est des feignasses et qu’on a pas envie de tweaker le blog jusqu’à ce que performances s’en suivent, on a fait les bourrins en mettant un gros varnish en front.

On a reçu de nombreuses remarques comme quoi on ne voyait pas si les commentaires étaient postés et autres détails qui rendaient la consultation du blog fort confuse.

On est pas devenu moins fainéant entre temps, mais il se trouve que je suis tombé par hasard sur ce plugin WordPress (ou alors quelqu’un me l’a recommandé, je sais plus) et j’ai trouvé la motivation pour l’installer ce matin.

Normalement il devrait invalider le cache à chaque fois qu’on met à jour un article ou que quelqu’un poste un commentaire.

À voir si ça plombe pas les perfs mais normalement ça devrait aller, on a eu à peine 4,758 comments depuis le lancement du blog, ça fait moins d’un comment à l’heure, on devrait survivre.

Si vous constatez que c’est mieux, faites le nous savoir, on aura au moins l’impression d’avoir fait notre BA.

flattr this!

]]>
http://sametmax.com/changement-du-cache-du-blog/feed/ 14
Firefox n’affiche plus les styles CSS ni les images http://sametmax.com/firefox-naffiche-plus-les-styles-css-ni-les-images/ http://sametmax.com/firefox-naffiche-plus-les-styles-css-ni-les-images/#comments Fri, 04 Jan 2013 12:15:30 +0000 Sam http://sametmax.com/?p=3956 Après avoir vidé le cache, il peut arriver que notre panda roux n’affiche plus les styles CSS ou les images: il n’y a plus aucune mise en page, juste du texte noir sur une page blanche. Damned !

La solution est de forcer le refresh de la page et du cache avec Ctrl + Shift + R.

flattr this!

]]>
http://sametmax.com/firefox-naffiche-plus-les-styles-css-ni-les-images/feed/ 6
Effacer le cache DNS sous Mac Os http://sametmax.com/effacer-le-cache-dns-sous-mac-os/ http://sametmax.com/effacer-le-cache-dns-sous-mac-os/#comments Thu, 22 Nov 2012 21:17:30 +0000 Max http://sametmax.com/?p=3257 Si vous avez encore l’ancienne IP lorsque vous faites un ping sur un site c’est que votre cache DNS l’a mémorisée. Il faut parfois le réinitialiser (si vous changez votre site de serveur ou que vous ne pouvez plus accéder à un site en particulier).

Ouvrez un Terminal:
Dans Applications > Utilitaires > Terminal

et tapez:

lookupd -flushcache

Si ça ne marche pas essayez (pour les Mac plus récents):

dscacheutil -flushcache

Rappel:
la commande ping est toujours utile, c’est un outil qui sert à tester la conneciton entre 2 IPs.

ping yahoo.com
PING yahoo.com (72.30.38.140): 56 data bytes
64 bytes from 72.30.38.140: icmp_seq=0 ttl=42 time=275.592 ms
64 bytes from 72.30.38.140: icmp_seq=1 ttl=42 time=212.991 ms
64 bytes from 72.30.38.140: icmp_seq=2 ttl=42 time=255.605 ms

flattr this!

]]>
http://sametmax.com/effacer-le-cache-dns-sous-mac-os/feed/ 0
Django cache illimité sur filesystem – Overrider FileBasedCache http://sametmax.com/django-cache-illimite-sur-filesystem-overrider-filebasedcache/ http://sametmax.com/django-cache-illimite-sur-filesystem-overrider-filebasedcache/#comments Sat, 13 Oct 2012 14:00:01 +0000 Max http://sametmax.com/?p=2569 Django propose plusieurs façons de mettre de son site en cache.
Un de nos site gourmant en pages commencait à saturer le cache en mémoire alors il a fallut le basculer sur le filesystem, oui mais Django et son backend filesystem par défaut autorise 300 entrées dans le cache, ensuite il va effacer les anciennes pour les remplacer par les nouvelles, etc…

On peut régler le nombre d’entrées avec l’option MAX_ENTRIES dans les settings mais que fait django derrière ?
Il va scanner votre répertoire de cache et compter tous les fichiers ! Niveau performance on a vu mieux !

Voici un petit patch qui consiste à bypasser le comptage des fichiers dans le cas où l’ont veut un cache “infini”, ce qui soulève un autre problème, ça va cacher jusqu’à qu’il n’y ait plus de pages à cacher ou que le disque sature :)

dans un fichier cache.py que vous mettez où vous voulez (moi dans libs par ex):

#!/usr/bin/env python
# -*- coding: utf-8 -*-
 
"""
    Override FileBasedCache to extend entries cache count.
    avoid scanning all cache dir to count entries.
 
"""
import os
from django.core.cache.backends.filebased import FileBasedCache
 
class CustomFileBasedCache(FileBasedCache):
 
    def _get_num_entries(self):
       count = 0
       if self._max_entries == 9999: return 0
       for _,_,files in os.walk(self._dir):
           count += len(files)
       return count
    _num_entries = property(_get_num_entries)

dans les settings rajoutez à votre backend filesystem le backend customisé “libs.cache.CustomFileBasedCache” et l’option MAX_ENTRIES à -1:

CACHE_DEFAULT_SECONDS = 3600
CACHES = {
   'default': {
       'BACKEND': 'redis_cache.RedisCache',
       'LOCATION': 'localhost:6379',
       'TIMEOUT': CACHE_DEFAULT_SECONDS,
   },
   'filesystem': {
       'BACKEND': 'libs.cache.CustomFileBasedCache',
       'LOCATION': '/var/tmp/django',
       'TIMEOUT': CACHE_DEFAULT_SECONDS,
       'OPTIONS': {
            'MAX_ENTRIES': 9999 # Set 9999 for unlimited cache
       }
   }
}

On évite du coup le os.walk de la méthode _get_num_entries qui dans le cas d’un grand nombre de fichiers en cache pourrait faire du mal à votre serveur.

A utiliser avec précaution car ça cache, ça cache, ça cache… :)

flattr this!

]]>
http://sametmax.com/django-cache-illimite-sur-filesystem-overrider-filebasedcache/feed/ 2
Optimiser Mysql en mettant en cache les requetes SELECT avec query_cache_size + benchmark http://sametmax.com/optimiser-mysql-en-utilisant-le-cache-query_cache_size/ http://sametmax.com/optimiser-mysql-en-utilisant-le-cache-query_cache_size/#comments Tue, 28 Aug 2012 23:25:24 +0000 Max http://sametmax.com/?p=1912 Voici une petite astuce pour mettre en cache les requetes mysql. Pour donner une idée du gain j’ai fait un petit script de benchmark, le gain à la lecture est plutôt convaincant. Je ne suis pas benchmarkeur de profession alors si il y en a dans la salle qui pensent que ce test n’est pas réaliste merci d’apporter votre contribution ;)

Editer le fichier my.cnf pour activer le cache des requetes:

query_cache_type = 1
query_cache_size = 256M

query_cache_type est le type de cache que l’on va adopter:
0 = pas de cache
1 = met en cache toutes les requetes sauf celles qui ont le flag “SELECT S_NO_CACHE”
2 = met en cache seulement les requetes qui comportent le flag “SELECT SQL_CACHE”

Ci dessous le script pour tester les perfs:

#!/usr/bin/python
# -*- coding: utf-8 -*-
 
import MySQLdb as mdb
import sys
 
from timeit import Timer 
 
def benchmark(cur):
    """
        execute query
    """
    cur.execute("SELECT * FROM Writers")
    rows = cur.fetchall()
    #     for row in rows:
    #         print row
 
def create_fixtures():
    """
        Create dummy datas for test
    """
 
    with con:
        cur = con.cursor()
        cur.execute("DROP TABLE IF EXISTS Writers")
        cur.execute("CREATE TABLE IF NOT EXISTS Writers(Id INT PRIMARY KEY AUTO_INCREMENT, Name VARCHAR(25))")
        cur.execute("INSERT INTO Writers(Name) VALUES('Jack London')")
        cur.execute("INSERT INTO Writers(Name) VALUES('Honore de Balzac')")
        cur.execute("INSERT INTO Writers(Name) VALUES('Lion Feuchtwanger')")
        cur.execute("INSERT INTO Writers(Name) VALUES('Emile Zola')")
        cur.execute("INSERT INTO Writers(Name) VALUES('Adolf Hitler')")
        cur.execute("INSERT INTO Writers(Name) VALUES('Ronald McDonalds')")
        cur.execute("INSERT INTO Writers(Name) VALUES('Mamie Nova')")
        cur.execute("INSERT INTO Writers(Name) VALUES('Sam & Max')")
 
def set_query_cache(query_cache_type=1):
    """
        Set query cache
        0 : Don't cache results in or retrieve results from the query cache.
        1 : Cache all query results except for those that begin with SELECT S_NO_CACHE.
        2 : Cache results only for queries that begin with SELECT SQL_CACHE
    """
 
    with con:
        cur = con.cursor()
        cur.execute("SET GLOBAL query_cache_size = 16777216")
        cur.execute("SET SESSION query_cache_type = %s" % str(query_cache_type)) 
 
def start_benchmark(nb_queries=1000, cached_queries=1):
    """
 
    """
    # use cached query benchmark
    print "Starting benchmark: %s reads - query cache type = %s" % (nb_queries, cached_queries)
 
    # set query cache
    set_query_cache(cached_queries)
 
    # run the test
    t = Timer("queries()", "from __main__ import queries")
    print t.timeit(number=nb_queries) 
 
if __name__ == '__main__':
 
    # connect to db
    con = mdb.connect('localhost', 'root', '12345', 'test');
 
    # create dummy datas
    create_fixtures()
 
    with con:
        cur = con.cursor()
        queries = lambda: benchmark(cur=cur)
 
    # launch benchmark
    start_benchmark(nb_queries=10000, cached_queries=1)
    start_benchmark(nb_queries=10000, cached_queries=0)
 
    con.close()

Ce qui me donne…

python mysql_tests.py
Starting benchmark: 10000 reads - query cache type = 1
1.47591710091
Starting benchmark: 10000 reads - query cache type = 0
1.96538686752

Conclusion:
Il semblerait qu’en effet le gain dû au cache est plutôt pas mal, en plus c’est juste 2 params à mettre dans son fichier de config.

Faites part de vos retours, ça peut toujours servir ;)

flattr this!

]]>
http://sametmax.com/optimiser-mysql-en-utilisant-le-cache-query_cache_size/feed/ 6