Django に Memcached の Cache 設定を行おうとして、
pylibmc インストールしてみたのですが、相当うまくいかず、
色々やってみた結果を記載します。
誰かの役に立てばよいなと思います。。


前提

以下の環境で実行しています。

  • OS
    CentOS release 6.9 (Final)

  • Python Version
    Python 2.7.8

  • Package (必要そうなものだけ抜粋)
    Django (1.10.6)


参考


pylibmc のインストールと設定

pylibmc のインストール

pip install pylibmc
--------------------------------------------------------------
Command "/usr/local/bin/python2.7 -u -c "import setuptools, tokenize;__file__='/tmp/pip-build-ff0iS1/pylibmc/setup.py';f=getattr(tokenize, 'open', open)(__file__);code=f.read().replace('\r\n', '\n');f.close();exec(compile(code, __file__, 'exec'))" install --record /tmp/pip-zNeMIE-record/install-record.txt --single-version-externally-managed --compile" failed with error code 1 in /tmp/pip-build-ff0iS1/pylibmc/
--------------------------------------------------------------
まず、コンパイルエラーになりました。。 [python] memchachedを使うためにpip install pylibmcでエラーがでる – あれは、魔法だろうか?
見る限り、libmemcached必要なようなので、そちらをインストールしました。
yum install libmemcached
---------------------------------------------------------------
インストール:
  libmemcached.x86_64 0:0.31-1.1.el6                                                                                                                                                

完了しました!
---------------------------------------------------------------
再度インストール
pip install pylibmc
---------------------------------------------------------------
Command "/usr/local/bin/python2.7 -u -c "import setuptools, tokenize;__file__='/tmp/pip-build-RbaKMi/pylibmc/setup.py';f=getattr(tokenize, 'open', open)(__file__);code=f.read().replace('\r\n', '\n');f.close();exec(compile(code, __file__, 'exec'))" install --record /tmp/pip-F4oT75-record/install-record.txt --single-version-externally-managed --compile" failed with error code 1 in /tmp/pip-build-RbaKMi/pylibmc/
---------------------------------------------------------------
まだだめでした。
django - pylibmc installation error using pip in python - Stack Overflow
参考に、libmemcached-develインストール。
yum install libmemcached-devel
---------------------------------------------------------------
インストール:
  libmemcached-devel.x86_64 0:0.31-1.1.el6                                                                                                                                          

完了しました!
---------------------------------------------------------------
再々度インストール。
pip install pylibmc
---------------------------------------------------------------
Successfully built pylibmc
Installing collected packages: pylibmc
Successfully installed pylibmc-1.5.2
---------------------------------------------------------------
インストール完了となりました。

settings.py の設定

django document の コピー&ペーストです。
Django 1.11 よりも古いversion だと、OPTIONS に直接、pylibmc の設定を追加できたようですが、
この設定は、廃止予定で、behaviors書くになるようです。

CACHES = {
    'default': {
        'BACKEND': 'django.core.cache.backends.memcached.PyLibMCCache',
        'LOCATION': '127.0.0.1:11211',
        'OPTIONS': {
            'binary': True,
            'behaviors': {
                'ketama': True,
            }
        }
    }
}

コンソールから、お試しで実行

import _pylibmc
RuntimeError: pylibmc requires >= libmemcached 0.32, was compiled with 0.31
どうも、CentOS 6.9 の デフォルトでインストールされる libmemcachedVersion が古いようです。

対応の方向性として、

  • pylibmc のversion を下げていき、libmemcached 0.31 で動くversionをインストールする。
    しくは、

  • libmemcached の version を上げる

があります。まず、pylibmc の<wbr> version を<wbr>下げる<wbr> 方向で、なんとかしていきます。

pylibmc の version を下げる

  • libmemcached 0.31 で動作する version を探す
    [python - Pip unable to install pylibmc - Stack Overflow][http://stackoverflow.com/questions/24437325/pip-unable-to-install-pylibmc] 上記StackOverFLowでの回答を参考に、1.2.3インストールします。
    pip uninstall pylibmc 
    pip install pylibmc==1.2.3
    -------------------------------------------------------------------
    Successfully built pylibmc
    Installing collected packages: pylibmc
    Successfully installed pylibmc-1.2.3
    -------------------------------------------------------------------
    
    再度コンソールから実行
    import _pylibmc
    RuntimeError: pylibmc requires >= libmemcached 0.32, was compiled with 0.31
    
    同様のエラーが出力されます。
    更にバージョンを下げてみます。install できるversionの確認します。
    pip install pylibmc==x.x.x.x
    -----------------------------------------
    Collecting pylibmc==x.x.x.x
      Could not find a version that satisfies the requirement pylibmc==x.x.x.x (from versions: 0.2, 0.3, 0.4, 0.5, 0.5.1, 0.5.2, 0.5.3, 0.5.4, 0.5.5, 0.6, 0.6.1, 0.7, 0.7.1, 0.7.2, 0.7.3, 0.7.4, 0.8, 0.8.1, 0.8.2, 0.9, 0.9.1, 0.9.2, 1.0a0, 1.0b0, 1.0, 1.1, 1.1.1, 1.2.0, 1.2.1, 1.2.2, 1.2.3, 1.3.0, 1.4.0, 1.4.1, 1.4.2, 1.4.3, 1.5.0, 1.5.1, 1.5.2)
    No matching distribution found for pylibmc==x.x.x.x
    -----------------------------------------
    
    0.9.2 まで下げたところ、
    import _pylibmc
    RuntimeError: pylibmc requires >= libmemcached 0.32, was compiled with 0.31
    
    いうエラーは発生しなくなり、
    動作するようになりました。

libmemcached の version を上げる

pylibmc の version を下げての動作は確認できたので、 libmemcached の version を上げて動作確認をしていきます。
libmemcached の 新しいversion は remi というrepository にあるようなので、
repository の 設定をしてから、yumを行います。
remi の 設定は以下が参考になりました。
CentOS6.7 64bitのyumリポジトリにRemiを追加 | kakiro-web カキローウェブ

  • memcached 自体の install

centos の 標準リポジトリのmemcached memcached-devel も、
古そうなので、そちらも、remiから取得します。

remi

yum --enablerepo=remi,epel install memcached memcached-devel
----------------------------------------------
memcached 1.4.36
----------------------------------------------
1.4.36なりました。 ちなみに、標準リポジトリのほうは、1.4.4 です。

  • libmemcached-last libmemcached-last-devel のインストール

remi の libmemcached と、 libmemcached-devel は名前にlast 含まれています。
そのまま、install しようとすると、既にlibmemcached libmemcached-devel をインストールしている場合は、
install できないので、まずインストールされている libmemcached libmemcached-devel を削除します。

yum -erase libmemcached libmemcached-devel

yum --enablerepo=remi,epel install libmemcached-last libmemcached-last-devel
libmemcached-last-1.0.18-6.el6.remi.x86_64 と、 libmemcached-last-devel-1.0.18-6.el6.remi.x86_64
インストールされます。

  • pylibmc の再インストール と 動作確認
    pylibmc の 最新をインストールしなおします。

    pip uninstall pylibmc
    pip install pylibmc
    -------------------------------
    Installing collected packages: pylibmc
    Successfully installed pylibmc-1.5.2
    -------------------------------
    

  • コンソールで動作確認

    import pylibmc
    -------------------------------------
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
      File "/usr/local/lib/python2.7/site-packages/pylibmc/__init__.py", line 71, in <module>
        import _pylibmc
    ImportError: libmemcached.so.2: cannot open shared object file: No such file or directory
    -------------------------------------
    
    今度は別のエラーになりました。 pylibmc が互換性なさそうなので、
    github のリポジトリから、インストールしてみます。

  • Githubからpipでインストール

    pip uninstall pylibmc
    pip install git+https://github.com/lericson/pylibmc
    

  • 再度、コンソールで動作確認

    import pylibmc
    
    開発版だと、互換性があるようで、 動作するようになりました。


バイナリプロトコルで、Memcached と通信させる

Memcached には、バイナリプロトコルがあり、テキストプロトコルより、
若干早そうです。 Django の django.core.cache.backends.memcached.PyLibMCCache で、
バイナリプロトコル で通信できるか試してみたのですが、
Django (1.10.6) ではオプションを認識してくれなかったので、 django-pylibmc/django-pylibmc: A cache backend for Django using pylibmc
使ってみます。 1
1. Django’s cache framework | Django documentation | Django見る限り、Django 1.11 から、PyLibMCCache で、バイナリプロトコルでつなげるようになりそうです。

django-pylibmc のインストール

pip install django-pylibmc

---------------------------------------------------
Installing collected packages: django-pylibmc
Successfully installed django-pylibmc-0.6.1
---------------------------------------------------
django-pylibmc-0.6.1インストールされました。

settings.py に設定を追加

django-pylibmc/django-pylibmc: A cache backend for Django using pylibmc
README.rst を参考に以下を記載します。
OPTIONS の記載の意味はあまりわかっておりません。

CACHES = {
    'default': {
        'BACKEND': 'django_pylibmc.memcached.PyLibMCCache',
        'LOCATION': 'localhost:11211',
        'TIMEOUT': 60 * 60 * 24,
        'BINARY': True,
        'OPTIONS': {  # Maps to pylibmc "behaviors"
            'tcp_nodelay': True,
            'ketama': True
        }
    }
}

サーバーを再起動して、 ぺージを表示させます。
memcached を-vv オプションを起動していれば、
ログファイルに以下のように、binary protocol で通信している旨が出力されます。

27: Client using the binary protocol
<27 Read binary protocol data:
<27    0x80 0x0c 0x00 0x23
<27    0x00 0x00 0x00 0x00
<27    0x00 0x00 0x00 0x23


まとめ

以下まとめます。

  • 一言で言うと
    CentOS 6.9 の Django 1.10.6 の組み合わせで、pylibmcを使うのは面倒くさい。

  • entOS の デフォルトでインストールできる Memcached使う場合
    pylibmc は 0.9.2使うようにする。

  • remi のリポジトリにある、Memcached使う場合
    pylibmc-1.5.2 だと動かないので、githubからpipで落としたものを使う。

  • バイナリープロトコルを使う場合
    Django (1.10.6) django.core.cache.backends.memcached.PyLibMCCache だと、
    バイナリープロトコルを使えないので、django-pylibmcインストールして、
    django_pylibmc.memcached.PyLibMCCache使うようにする。

インストールのトラブルはなかなかしんどかったので、
個人的には、python-memcachedほうを使おうかと思っています。
以上です。

コメント