2010-12-14 8 views
20

おそらくこれは完全に正常な動作ですが、django_sessionテーブルははるかに大きい必要があります。巨大なDjangoセッションテーブル、通常の動作またはバグ?

DELETE FROM %s WHERE expire_date < NOW() 

番号:

  • 我々はおよそ持っているサイズ期限切れのセッションによって引き起こさではありませんので

    まず第一に、私は毎日、次のクリーンアップコマンドを実行します。毎日5000人のユニークビジター(ボットが除外されています)。

  • SESSION_COOKIE_AGEがテーブルだから少し1,000,000 を超える行

を持って、私は、Djangoはまた訪れるすべてのロボットのためのセッション鍵を生成することを推測している

  • 2週間、デフォルトに設定されていますボットはクッキーを保存しないので、新しいクッキーが継続的に生成されます。

    これは正常な動作ですか? Djangoが匿名ユーザーのためのセッションを生成しない、または少なくともセッションを使用していないユーザーのセッションを生成しない設定がありますか?

  • 答えて

    17

    少しのデバッグの後、私は問題の原因を追跡することができました。 私のミドルウェア(そして私の意見のほとんど)にはrequest.user.is_authenticated()があります。

    django.contrib.authミドルウェアはrequest.userソース

    LazyUser()に設定していますがreturn Noneが、OKがあり、なぜhttp://code.djangoproject.com/browser/django/trunk/django/contrib/auth/middleware.py?rev=14919#L13は(私は見ていません...)

    class AuthenticationMiddleware(object): 
        def process_request(self, request): 
         assert hasattr(request, 'session'), "The Django authentication middleware requires session middleware to be installed. Edit your MIDDLEWARE_CLASSES setting to insert 'django.contrib.sessions.middleware.SessionMiddleware'." 
         request.__class__.user = LazyUser() 
         return None 
    

    LazyUser通話get_user(request)ユーザーを取得するには:

    出典:http://code.djangoproject.com/browser/django/trunk/django/contrib/auth/init.py?rev=14919#L100

    http://code.djangoproject.com/browser/django/trunk/django/contrib/auth/middleware.py?rev=14919#L5

    class LazyUser(object): 
        def __get__(self, request, obj_type=None): 
         if not hasattr(request, '_cached_user'): 
          from django.contrib.auth import get_user 
          request._cached_user = get_user(request) 
         return request._cached_user 
    

    get_user(request)方法はuser_id = request.session[SESSION_KEY]

    ソースを行います

    出典:セッションにアクセスする際

    def get_user(request): 
        from django.contrib.auth.models import AnonymousUser 
        try: 
         user_id = request.session[SESSION_KEY] 
         backend_path = request.session[BACKEND_SESSION_KEY] 
         backend = load_backend(backend_path) 
         user = backend.get_user(user_id) or AnonymousUser() 
        except KeyError: 
         user = AnonymousUser() 
        return user 
    
    はtrueに accessedを設定 http://code.djangoproject.com/browser/django/trunk/django/contrib/sessions/backends/base.py?rev=14919#L183

    def _get_session(self, no_load=False): 
        """ 
        Lazily loads session from storage (unless "no_load" is True, when only 
        an empty dict is stored) and stores it in the current instance. 
        """ 
        self.accessed = True 
        try: 
         return self._session_cache 
        except AttributeError: 
         if self._session_key is None or no_load: 
          self._session_cache = {} 
         else: 
          self._session_cache = self.load() 
        return self._session_cache 
    

    そして、それは、セッションの初期化になります。バグは、accessedがtrueに設定されているときにもセッションを生成する不良セッションバックエンドによって引き起こされました。

    +0

    私はこの答えが長い前に書かれた知っているが、私は同じ問題を見ている。説明は意味があるようですが、修正がありますか?ありがとう! – alan

    +0

    私にとっては、実際に使用されていないときにセッションが生成されないようにすることでした。私のミドルウェアの1つはセッションがすべての場合に「アクセスされました」と設定し、すべてのボットのすべてのページビューでそれを生成させました。 – Wolph

    +0

    ええと...私とは別の問題でなければなりません。私は新しいdjango 1.4アプリケーションを作成しようとしました.Django.contrib.auth.views.loginは、ユーザーが匿名で以前に訪問していない場合に新しいセッションを保存するように見えます。私はこれについて新しい質問を作成しました:http://stackoverflow.com/questions/17098142/django-session-created-in-database-when-login-page-loaded。あなたが一見することができれば素晴らしいだろう。ありがとう! – alan

    -3

    Djangoはこれらの期限切れのセッションmanagement command to cleanupを提供しています!

    +1

    私の元の質問で言ったように、私は期限切れのセッションについて話しているわけではありません。私は毎日のクリーンアップコマンドを実行しています(この量のセッションに達する前に、Djangoのバージョンはずっと前から死んでいます)。 – Wolph

    3

    ユーザーセッション(匿名ユーザーの場合でも)やsession.set_test_cookie()(たとえば、このメソッドを呼び出しているDjangoのデフォルトのログインビュー)を使用するページでロボットが何かを設定することは可能ですか?どちらの場合も、新しいセッションオブジェクトが作成されます。 robots.txt内のそのようなURLを除外すると役立ちます。

    +0

    問題は、ミドルウェアの1つで、セッションを使用してクッキーを設定する必要があるかどうかを検出していたことです。私は正しい方向に私を指してくれてありがとう:) +1 – Wolph

    0

    私の場合は、正確に意味を理解することなくに間違って設定しました。

    私のdjangoサービスに対するすべてのリクエストは、セッションエントリ、特にアップストリームロードバランサからのハートビートテスト要求を生成します。数日間稼働した後、django_sessionテーブルが巨大になった。

    関連する問題