• Home
  • History
  • Annotate
Name Date Size #Lines LOC

..03-May-2022-

django_redis/H30-Nov-2021-1,9821,508

django_redis.egg-info/H03-May-2022-1,001751

tests/H30-Nov-2021-1,9201,460

AUTHORS.rstH A D30-Nov-2021796 1716

LICENSEH A D30-Nov-20211.4 KiB2723

MANIFEST.inH A D30-Nov-2021160 76

PKG-INFOH A D30-Nov-202130 KiB1,001751

README.rstH A D30-Nov-202128.8 KiB965718

pyproject.tomlH A D30-Nov-2021635 1413

setup.cfgH A D30-Nov-20214.4 KiB190169

setup.pyH A D30-Nov-202138 42

README.rst

1==============================
2Redis cache backend for Django
3==============================
4
5.. image:: https://jazzband.co/static/img/badge.svg
6    :target: https://jazzband.co/
7    :alt: Jazzband
8
9.. image:: https://github.com/jazzband/django-redis/actions/workflows/ci.yml/badge.svg
10   :target: https://github.com/jazzband/django-redis/actions/workflows/ci.yml
11   :alt: GitHub Actions
12
13.. image:: https://codecov.io/gh/jazzband/django-redis/branch/master/graph/badge.svg
14   :target: https://codecov.io/gh/jazzband/django-redis
15   :alt: Coverage
16
17.. image:: https://img.shields.io/pypi/v/django-redis.svg?style=flat
18    :target: https://pypi.org/project/django-redis/
19
20This is a `Jazzband <https://jazzband.co>`_ project. By contributing you agree
21to abide by the `Contributor Code of Conduct
22<https://jazzband.co/about/conduct>`_ and follow the `guidelines
23<https://jazzband.co/about/guidelines>`_.
24
25Introduction
26------------
27
28django-redis is a BSD licensed, full featured Redis cache and session backend
29for Django.
30
31Why use django-redis?
32~~~~~~~~~~~~~~~~~~~~~
33
34- Uses native redis-py url notation connection strings
35- Pluggable clients
36- Pluggable parsers
37- Pluggable serializers
38- Primary/secondary support in the default client
39- Comprehensive test suite
40- Used in production in several projects as cache and session storage
41- Supports infinite timeouts
42- Facilities for raw access to Redis client/connection pool
43- Highly configurable (can emulate memcached exception behavior, for example)
44- Unix sockets supported by default
45
46Requirements
47~~~~~~~~~~~~
48
49- `Python`_ 3.6+
50- `Django`_ 2.2+
51- `redis-py`_ 3.0+
52- `Redis server`_ 2.8+
53
54.. _Python: https://www.python.org/downloads/
55.. _Django: https://www.djangoproject.com/download/
56.. _redis-py: https://pypi.org/project/redis/
57.. _Redis server: https://redis.io/download
58
59User guide
60----------
61
62Installation
63~~~~~~~~~~~~
64
65Install with pip:
66
67.. code-block:: console
68
69    $ python -m pip install django-redis
70
71Configure as cache backend
72~~~~~~~~~~~~~~~~~~~~~~~~~~
73
74To start using django-redis, you should change your Django cache settings to
75something like:
76
77.. code-block:: python
78
79    CACHES = {
80        "default": {
81            "BACKEND": "django_redis.cache.RedisCache",
82            "LOCATION": "redis://127.0.0.1:6379/1",
83            "OPTIONS": {
84                "CLIENT_CLASS": "django_redis.client.DefaultClient",
85            }
86        }
87    }
88
89django-redis uses the redis-py native URL notation for connection strings, it
90allows better interoperability and has a connection string in more "standard"
91way. Some examples:
92
93- ``redis://[[username]:[password]]@localhost:6379/0``
94- ``rediss://[[username]:[password]]@localhost:6379/0``
95- ``unix://[[username]:[password]]@/path/to/socket.sock?db=0``
96
97Three URL schemes are supported:
98
99- ``redis://``: creates a normal TCP socket connection
100- ``rediss://``: creates a SSL wrapped TCP socket connection
101- ``unix://`` creates a Unix Domain Socket connection
102
103There are several ways to specify a database number:
104
105- A ``db`` querystring option, e.g. ``redis://localhost?db=0``
106- If using the ``redis://`` scheme, the path argument of the URL, e.g.
107  ``redis://localhost/0``
108
109When using `Redis' ACLs <https://redis.io/topics/acl>`_, you will need to add the
110username to the URL (and provide the password with the Cache ``OPTIONS``).
111The login for the user ``django`` would look like this:
112
113.. code-block:: python
114
115    CACHES = {
116        "default": {
117            "BACKEND": "django_redis.cache.RedisCache",
118            "LOCATION": "redis://django@localhost:6379/0",
119            "OPTIONS": {
120                "CLIENT_CLASS": "django_redis.client.DefaultClient",
121                "PASSWORD": "mysecret"
122            }
123        }
124    }
125
126An alternative would be write both username and password into the URL:
127
128.. code-block:: python
129
130    CACHES = {
131        "default": {
132            "BACKEND": "django_redis.cache.RedisCache",
133            "LOCATION": "redis://django:mysecret@localhost:6379/0",
134            "OPTIONS": {
135                "CLIENT_CLASS": "django_redis.client.DefaultClient",
136            }
137        }
138    }
139
140In some circumstances the password you should use to connect Redis
141is not URL-safe, in this case you can escape it or just use the
142convenience option in ``OPTIONS`` dict:
143
144.. code-block:: python
145
146    CACHES = {
147        "default": {
148            "BACKEND": "django_redis.cache.RedisCache",
149            "LOCATION": "redis://127.0.0.1:6379/1",
150            "OPTIONS": {
151                "CLIENT_CLASS": "django_redis.client.DefaultClient",
152                "PASSWORD": "mysecret"
153            }
154        }
155    }
156
157Take care, that this option does not overwrites the password in the uri, so if
158you have set the password in the uri, this settings will be ignored.
159
160Configure as session backend
161~~~~~~~~~~~~~~~~~~~~~~~~~~~~
162
163Django can by default use any cache backend as session backend and you benefit
164from that by using django-redis as backend for session storage without
165installing any additional backends:
166
167.. code-block:: python
168
169    SESSION_ENGINE = "django.contrib.sessions.backends.cache"
170    SESSION_CACHE_ALIAS = "default"
171
172Testing with django-redis
173~~~~~~~~~~~~~~~~~~~~~~~~~
174
175django-redis supports customizing the underlying Redis client (see "Pluggable
176clients"). This can be used for testing purposes.
177
178In case you want to flush all data from the cache after a test, add the
179following lines to your test class:
180
181.. code-block:: python
182
183    from django_redis import get_redis_connection
184
185    def tearDown(self):
186        get_redis_connection("default").flushall()
187
188Advanced usage
189--------------
190
191Pickle version
192~~~~~~~~~~~~~~
193
194For almost all values, django-redis uses pickle to serialize objects.
195
196The ``pickle.DEFAULT_PROTOCOL`` version of pickle is used by default to ensure safe upgrades and compatibility across Python versions.
197If you want set a concrete version, you can do it, using ``PICKLE_VERSION`` option:
198
199.. code-block:: python
200
201    CACHES = {
202        "default": {
203            # ...
204            "OPTIONS": {
205                "PICKLE_VERSION": -1  # Will use highest protocol version available
206            }
207        }
208    }
209
210Socket timeout
211~~~~~~~~~~~~~~
212
213Socket timeout can be set using ``SOCKET_TIMEOUT`` and
214``SOCKET_CONNECT_TIMEOUT`` options:
215
216.. code-block:: python
217
218    CACHES = {
219        "default": {
220            # ...
221            "OPTIONS": {
222                "SOCKET_CONNECT_TIMEOUT": 5,  # seconds
223                "SOCKET_TIMEOUT": 5,  # seconds
224            }
225        }
226    }
227
228``SOCKET_CONNECT_TIMEOUT`` is the timeout for the connection to be established
229and ``SOCKET_TIMEOUT`` is the timeout for read and write operations after the
230connection is established.
231
232Compression support
233~~~~~~~~~~~~~~~~~~~
234
235django-redis comes with compression support out of the box, but is deactivated
236by default. You can activate it setting up a concrete backend:
237
238.. code-block:: python
239
240    CACHES = {
241        "default": {
242            # ...
243            "OPTIONS": {
244                "COMPRESSOR": "django_redis.compressors.zlib.ZlibCompressor",
245            }
246        }
247    }
248
249Let see an example, of how make it work with *lzma* compression format:
250
251.. code-block:: python
252
253    import lzma
254
255    CACHES = {
256        "default": {
257            # ...
258            "OPTIONS": {
259                "COMPRESSOR": "django_redis.compressors.lzma.LzmaCompressor",
260            }
261        }
262    }
263
264*Lz4* compression support (requires the lz4 library):
265
266.. code-block:: python
267
268    import lz4
269
270    CACHES = {
271        "default": {
272            # ...
273            "OPTIONS": {
274                "COMPRESSOR": "django_redis.compressors.lz4.Lz4Compressor",
275            }
276        }
277    }
278
279*Zstandard (zstd)* compression support (requires the pyzstd library):
280
281.. code-block:: python
282
283    import pyzstd
284
285    CACHES = {
286        "default": {
287            # ...
288            "OPTIONS": {
289                "COMPRESSOR": "django_redis.compressors.zstd.ZStdCompressor",
290            }
291        }
292    }
293
294Memcached exceptions behavior
295~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
296
297In some situations, when Redis is only used for cache, you do not want
298exceptions when Redis is down. This is default behavior in the memcached
299backend and it can be emulated in django-redis.
300
301For setup memcached like behaviour (ignore connection exceptions), you should
302set ``IGNORE_EXCEPTIONS`` settings on your cache configuration:
303
304.. code-block:: python
305
306    CACHES = {
307        "default": {
308            # ...
309            "OPTIONS": {
310                "IGNORE_EXCEPTIONS": True,
311            }
312        }
313    }
314
315Also, you can apply the same settings to all configured caches, you can set the global flag in
316your settings:
317
318.. code-block:: python
319
320    DJANGO_REDIS_IGNORE_EXCEPTIONS = True
321
322Log Ignored Exceptions
323~~~~~~~~~~~~~~~~~~~~~~
324
325When ignoring exceptions with ``IGNORE_EXCEPTIONS`` or
326``DJANGO_REDIS_IGNORE_EXCEPTIONS``, you may optionally log exceptions using the
327global variable ``DJANGO_REDIS_LOG_IGNORED_EXCEPTIONS`` in your settings file::
328
329    DJANGO_REDIS_LOG_IGNORED_EXCEPTIONS = True
330
331If you wish to specify the logger in which the exceptions are output, simply
332set the global variable ``DJANGO_REDIS_LOGGER`` to the string name and/or path
333of the desired logger. This will default to ``__name__`` if no logger is
334specified and ``DJANGO_REDIS_LOG_IGNORED_EXCEPTIONS`` is ``True``::
335
336    DJANGO_REDIS_LOGGER = 'some.specified.logger'
337
338Infinite timeout
339~~~~~~~~~~~~~~~~
340
341django-redis comes with infinite timeouts support out of the box. And it
342behaves in same way as django backend contract specifies:
343
344- ``timeout=0`` expires the value immediately.
345- ``timeout=None`` infinite timeout
346
347.. code-block:: python
348
349    cache.set("key", "value", timeout=None)
350
351Get ttl (time-to-live) from key
352~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
353
354With Redis, you can access to ttl of any stored key, for it, django-redis
355exposes ``ttl`` function.
356
357It returns:
358
359- 0 if key does not exists (or already expired).
360- None for keys that exists but does not have any expiration.
361- ttl value for any volatile key (any key that has expiration).
362
363.. code-block:: pycon
364
365    >>> from django.core.cache import cache
366    >>> cache.set("foo", "value", timeout=25)
367    >>> cache.ttl("foo")
368    25
369    >>> cache.ttl("not-existent")
370    0
371
372With Redis, you can access to ttl of any stored key in milliseconds, for it, django-redis
373exposes ``pttl`` function.
374
375.. code-block:: pycon
376
377    >>> from django.core.cache import cache
378    >>> cache.set("foo", "value", timeout=25)
379    >>> cache.pttl("foo")
380    25000
381    >>> cache.pttl("not-existent")
382    0
383
384Expire & Persist
385~~~~~~~~~~~~~~~~
386
387Additionally to the simple ttl query, you can send persist a concrete key or
388specify a new expiration timeout using the ``persist`` and ``expire`` methods:
389
390.. code-block:: pycon
391
392    >>> cache.set("foo", "bar", timeout=22)
393    >>> cache.ttl("foo")
394    22
395    >>> cache.persist("foo")
396    True
397    >>> cache.ttl("foo")
398    None
399
400.. code-block:: pycon
401
402    >>> cache.set("foo", "bar", timeout=22)
403    >>> cache.expire("foo", timeout=5)
404    True
405    >>> cache.ttl("foo")
406    5
407
408The ``expire_at`` method can be used to make the key expire at a specific moment in time.
409
410.. code-block:: pycon
411
412    >>> cache.set("foo", "bar", timeout=22)
413    >>> cache.expire_at("foo", datetime.now() + timedelta(hours=1))
414    True
415    >>> cache.ttl("foo")
416    3600
417
418The ``pexpire_at`` method can be used to make the key expire at a specific moment in time with milliseconds precision:
419
420.. code-block:: pycon
421
422    >>> cache.set("foo", "bar", timeout=22)
423    >>> cache.pexpire_at("foo", datetime.now() + timedelta(milliseconds=900, hours=1))
424    True
425    >>> cache.ttl("foo")
426    3601
427    >>> cache.pttl("foo")
428    3600900
429
430The ``pexpire`` method can be used to provide millisecond precision:
431
432.. code-block:: pycon
433
434    >>> cache.set("foo", "bar", timeout=22)
435    >>> cache.pexpire("foo", timeout=5500)
436    True
437    >>> cache.pttl("foo")
438    5500
439
440Locks
441~~~~~
442
443It also supports the Redis ability to create Redis distributed named locks. The
444Lock interface is identical to the ``threading.Lock`` so you can use it as
445replacement.
446
447.. code-block:: python
448
449    with cache.lock("somekey"):
450        do_some_thing()
451
452Scan & Delete keys in bulk
453~~~~~~~~~~~~~~~~~~~~~~~~~~
454
455django-redis comes with some additional methods that help with searching or
456deleting keys using glob patterns.
457
458.. code-block:: pycon
459
460    >>> from django.core.cache import cache
461    >>> cache.keys("foo_*")
462    ["foo_1", "foo_2"]
463
464A simple search like this will return all matched values. In databases with a
465large number of keys this isn't suitable method. Instead, you can use the
466``iter_keys`` function that works like the ``keys`` function but uses Redis
467server side cursors. Calling ``iter_keys`` will return a generator that you can
468then iterate over efficiently.
469
470.. code-block:: pycon
471
472    >>> from django.core.cache import cache
473    >>> cache.iter_keys("foo_*")
474    <generator object algo at 0x7ffa9c2713a8>
475    >>> next(cache.iter_keys("foo_*"))
476    "foo_1"
477
478For deleting keys, you should use ``delete_pattern`` which has the same glob
479pattern syntax as the ``keys`` function and returns the number of deleted keys.
480
481.. code-block:: pycon
482
483    >>> from django.core.cache import cache
484    >>> cache.delete_pattern("foo_*")
485
486Redis native commands
487~~~~~~~~~~~~~~~~~~~~~
488
489django-redis has limited support for some Redis atomic operations, such as the
490commands ``SETNX`` and ``INCR``.
491
492You can use the ``SETNX`` command through the backend ``set()`` method with the
493``nx`` parameter:
494
495.. code-block:: pycon
496
497    >>> from django.core.cache import cache
498    >>> cache.set("key", "value1", nx=True)
499    True
500    >>> cache.set("key", "value2", nx=True)
501    False
502    >>> cache.get("key")
503    "value1"
504
505Also, the ``incr`` and ``decr`` methods use Redis atomic operations when the
506value that a key contains is suitable for it.
507
508Raw client access
509~~~~~~~~~~~~~~~~~
510
511In some situations your application requires access to a raw Redis client to
512use some advanced features that aren't exposed by the Django cache interface.
513To avoid storing another setting for creating a raw connection, django-redis
514exposes functions with which you can obtain a raw client reusing the cache
515connection string: ``get_redis_connection(alias)``.
516
517.. code-block:: pycon
518
519    >>> from django_redis import get_redis_connection
520    >>> con = get_redis_connection("default")
521    >>> con
522    <redis.client.Redis object at 0x2dc4510>
523
524WARNING: Not all pluggable clients support this feature.
525
526Connection pools
527~~~~~~~~~~~~~~~~
528
529Behind the scenes, django-redis uses the underlying redis-py connection pool
530implementation, and exposes a simple way to configure it. Alternatively, you
531can directly customize a connection/connection pool creation for a backend.
532
533The default redis-py behavior is to not close connections, recycling them when
534possible.
535
536Configure default connection pool
537^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
538
539The default connection pool is simple. For example, you can customize the
540maximum number of connections in the pool by setting ``CONNECTION_POOL_KWARGS``
541in the ``CACHES`` setting:
542
543.. code-block:: python
544
545    CACHES = {
546        "default": {
547            "BACKEND": "django_redis.cache.RedisCache",
548            # ...
549            "OPTIONS": {
550                "CONNECTION_POOL_KWARGS": {"max_connections": 100}
551            }
552        }
553    }
554
555You can verify how many connections the pool has opened with the following
556snippet:
557
558.. code-block:: python
559
560    from django_redis import get_redis_connection
561
562    r = get_redis_connection("default")  # Use the name you have defined for Redis in settings.CACHES
563    connection_pool = r.connection_pool
564    print("Created connections so far: %d" % connection_pool._created_connections)
565
566Since the default connection pool passes all keyword arguments it doesn't use
567to its connections, you can also customize the connections that the pool makes
568by adding those options to ``CONNECTION_POOL_KWARGS``:
569
570.. code-block:: python
571
572    CACHES = {
573        "default": {
574            # ...
575            "OPTIONS": {
576                "CONNECTION_POOL_KWARGS": {"max_connections": 100, "retry_on_timeout": True}
577            }
578        }
579    }
580
581Use your own connection pool subclass
582^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
583
584Sometimes you want to use your own subclass of the connection pool. This is
585possible with django-redis using the ``CONNECTION_POOL_CLASS`` parameter in the
586backend options.
587
588.. code-block:: python
589
590    from redis.connection import ConnectionPool
591
592    class MyOwnPool(ConnectionPool):
593        # Just doing nothing, only for example purpose
594        pass
595
596.. code-block:: python
597
598    # Omitting all backend declaration boilerplate code.
599
600    "OPTIONS": {
601        "CONNECTION_POOL_CLASS": "myproj.mypool.MyOwnPool",
602    }
603
604Customize connection factory
605^^^^^^^^^^^^^^^^^^^^^^^^^^^^
606
607If none of the previous methods satisfies you, you can get in the middle of the
608django-redis connection factory process and customize or completely rewrite it.
609
610By default, django-redis creates connections through the
611``django_redis.pool.ConnectionFactory`` class that is specified in the global
612Django setting ``DJANGO_REDIS_CONNECTION_FACTORY``.
613
614.. code-block:: python
615
616    class ConnectionFactory(object):
617        def get_connection_pool(self, params: dict):
618            # Given connection parameters in the `params` argument, return new
619            # connection pool. It should be overwritten if you want do
620            # something before/after creating the connection pool, or return
621            # your own connection pool.
622            pass
623
624        def get_connection(self, params: dict):
625            # Given connection parameters in the `params` argument, return a
626            # new connection. It should be overwritten if you want to do
627            # something before/after creating a new connection. The default
628            # implementation uses `get_connection_pool` to obtain a pool and
629            # create a new connection in the newly obtained pool.
630            pass
631
632        def get_or_create_connection_pool(self, params: dict):
633            # This is a high layer on top of `get_connection_pool` for
634            # implementing a cache of created connection pools. It should be
635            # overwritten if you want change the default behavior.
636            pass
637
638        def make_connection_params(self, url: str) -> dict:
639            # The responsibility of this method is to convert basic connection
640            # parameters and other settings to fully connection pool ready
641            # connection parameters.
642            pass
643
644        def connect(self, url: str):
645            # This is really a public API and entry point for this factory
646            # class. This encapsulates the main logic of creating the
647            # previously mentioned `params` using `make_connection_params` and
648            # creating a new connection using the `get_connection` method.
649            pass
650
651Use the sentinel connection factory
652^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
653
654In order to facilitate using `Redis Sentinels`_, django-redis comes with a
655built in sentinel connection factory, which creates sentinel connection pools.
656In order to enable this functionality you should add the following:
657
658
659.. code-block:: python
660
661    # Enable the alternate connection factory.
662    DJANGO_REDIS_CONNECTION_FACTORY = 'django_redis.pool.SentinelConnectionFactory'
663
664    # These sentinels are shared between all the examples, and are passed
665    # directly to redis Sentinel. These can also be defined inline.
666    SENTINELS = [
667        ('sentinel-1', 26379),
668        ('sentinel-2', 26379),
669        ('sentinel-3', 26379),
670    ]
671
672    CACHES = {
673        "default": {
674            "BACKEND": "django_redis.cache.RedisCache",
675            # The hostname in LOCATION is the primary (service / master) name
676            "LOCATION": "redis://service_name/db",
677            "OPTIONS": {
678                # While the default client will work, this will check you
679                # have configured things correctly, and also create a
680                # primary and replica pool for the service specified by
681                # LOCATION rather than requiring two URLs.
682                "CLIENT_CLASS": "django_redis.client.SentinelClient",
683
684                # Sentinels which are passed directly to redis Sentinel.
685                "SENTINELS": SENTINELS,
686
687                # kwargs for redis Sentinel (optional).
688                "SENTINEL_KWARGS": {},
689
690                # You can still override the connection pool (optional).
691                "CONNECTION_POOL_CLASS": "redis.sentinel.SentinelConnectionPool",
692            },
693        },
694
695        # A minimal example using the SentinelClient.
696        "minimal": {
697            "BACKEND": "django_redis.cache.RedisCache",
698
699            # The SentinelClient will use this location for both the primaries
700            # and replicas.
701            "LOCATION": "redis://minimal_service_name/db",
702
703            "OPTIONS": {
704                "CLIENT_CLASS": "django_redis.client.SentinelClient",
705                "SENTINELS": SENTINELS,
706            },
707        },
708
709        # A minimal example using the DefaultClient.
710        "other": {
711            "BACKEND": "django_redis.cache.RedisCache",
712            "LOCATION": [
713                # The DefaultClient is [primary, replicas...], but with the
714                # SentinelConnectionPool it only requires one "is_master=0".
715                "redis://other_service_name/db?is_master=1",
716                "redis://other_service_name/db?is_master=0",
717            ],
718            "OPTIONS": {"SENTINELS": SENTINELS},
719        },
720
721        # A minimal example only using only replicas in read only mode (and
722        # the DefaultClient).
723        "readonly": {
724            "BACKEND": "django_redis.cache.RedisCache",
725            "LOCATION": "redis://readonly_service_name/db?is_master=0",
726            "OPTIONS": {"SENTINELS": SENTINELS},
727        },
728    }
729
730.. _Redis Sentinels: https://redis.io/topics/sentinel
731
732Pluggable parsers
733~~~~~~~~~~~~~~~~~
734
735redis-py (the Python Redis client used by django-redis) comes with a pure
736Python Redis parser that works very well for most common task, but if you want
737some performance boost, you can use hiredis.
738
739hiredis is a Redis client written in C and it has its own parser that can be
740used with django-redis.
741
742.. code-block:: python
743
744    "OPTIONS": {
745        "PARSER_CLASS": "redis.connection.HiredisParser",
746    }
747
748Pluggable clients
749~~~~~~~~~~~~~~~~~
750
751django-redis is designed for to be very flexible and very configurable. For it,
752it exposes a pluggable backends that make easy extend the default behavior, and
753it comes with few ones out the box.
754
755Default client
756^^^^^^^^^^^^^^
757
758Almost all about the default client is explained, with one exception: the
759default client comes with replication support.
760
761To connect to a Redis replication setup, you should change the ``LOCATION`` to
762something like:
763
764.. code-block:: python
765
766    "LOCATION": [
767        "redis://127.0.0.1:6379/1",
768        "redis://127.0.0.1:6378/1",
769    ]
770
771The first connection string represents the primary server and the rest to
772replica servers.
773
774WARNING: Replication setup is not heavily tested in production environments.
775
776Shard client
777^^^^^^^^^^^^
778
779This pluggable client implements client-side sharding. It inherits almost all
780functionality from the default client. To use it, change your cache settings to
781something like this:
782
783.. code-block:: python
784
785    CACHES = {
786        "default": {
787            "BACKEND": "django_redis.cache.RedisCache",
788            "LOCATION": [
789                "redis://127.0.0.1:6379/1",
790                "redis://127.0.0.1:6379/2",
791            ],
792            "OPTIONS": {
793                "CLIENT_CLASS": "django_redis.client.ShardClient",
794            }
795        }
796    }
797
798WARNING: Shard client is still experimental, so be careful when using it in
799production environments.
800
801Herd client
802^^^^^^^^^^^
803
804This pluggable client helps dealing with the thundering herd problem. You can read more about it
805on link: `Wikipedia <http://en.wikipedia.org/wiki/Thundering_herd_problem>`_
806
807Like previous pluggable clients, it inherits all functionality from the default client, adding some
808additional methods for getting/setting keys.
809
810.. code-block:: python
811
812    CACHES = {
813        "default": {
814            "BACKEND": "django_redis.cache.RedisCache",
815            "LOCATION": "redis://127.0.0.1:6379/1",
816            "OPTIONS": {
817                "CLIENT_CLASS": "django_redis.client.HerdClient",
818            }
819        }
820    }
821
822This client exposes additional settings:
823
824- ``CACHE_HERD_TIMEOUT``: Set default herd timeout. (Default value: 60s)
825
826Pluggable serializer
827~~~~~~~~~~~~~~~~~~~~
828
829The pluggable clients serialize data before sending it to the server. By
830default, django-redis serializes the data using the Python ``pickle`` module.
831This is very flexible and can handle a large range of object types.
832
833To serialize using JSON instead, the serializer ``JSONSerializer`` is also
834available.
835
836.. code-block:: python
837
838    CACHES = {
839        "default": {
840            "BACKEND": "django_redis.cache.RedisCache",
841            "LOCATION": "redis://127.0.0.1:6379/1",
842            "OPTIONS": {
843                "CLIENT_CLASS": "django_redis.client.DefaultClient",
844                "SERIALIZER": "django_redis.serializers.json.JSONSerializer",
845            }
846        }
847    }
848
849There's also support for serialization using `MsgPack`_ (that requires the
850msgpack library):
851
852.. code-block:: python
853
854    CACHES = {
855        "default": {
856            "BACKEND": "django_redis.cache.RedisCache",
857            "LOCATION": "redis://127.0.0.1:6379/1",
858            "OPTIONS": {
859                "CLIENT_CLASS": "django_redis.client.DefaultClient",
860                "SERIALIZER": "django_redis.serializers.msgpack.MSGPackSerializer",
861            }
862        }
863    }
864
865.. _MsgPack: http://msgpack.org/
866
867Pluggable Redis client
868~~~~~~~~~~~~~~~~~~~~~~
869
870django-redis uses the Redis client ``redis.client.StrictClient`` by default. It
871is possible to use an alternative client.
872
873You can customize the client used by setting ``REDIS_CLIENT_CLASS`` in the
874``CACHES`` setting. Optionally, you can provide arguments to this class by
875setting ``REDIS_CLIENT_KWARGS``.
876
877.. code-block:: python
878
879    CACHES = {
880        "default": {
881            "OPTIONS": {
882                "REDIS_CLIENT_CLASS": "my.module.ClientClass",
883                "REDIS_CLIENT_KWARGS": {"some_setting": True},
884            }
885        }
886    }
887
888
889Closing Connections
890~~~~~~~~~~~~~~~~~~~
891
892The default django-redis behavior on close() is to keep the connections to Redis server.
893
894You can change this default behaviour for all caches by the ``DJANGO_REDIS_CLOSE_CONNECTION = True``
895in the django settings (globally) or (at cache level) by setting ``CLOSE_CONNECTION: True`` in the ``OPTIONS``
896for each configured cache.
897
898Setting True as a value will instruct the django-redis to close all the connections (since v. 4.12.2), irrespectively of its current usage.
899
900.. code-block:: python
901
902    CACHES = {
903        "default": {
904            "BACKEND": "django_redis.cache.RedisCache",
905            "LOCATION": "redis://127.0.0.1:6379/1",
906            "OPTIONS": {
907                "CLIENT_CLASS": "django_redis.client.DefaultClient",
908                "CLOSE_CONNECTION": True,
909            }
910        }
911    }
912
913SSL/TLS and Self-Signed certificates
914~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
915
916In case you encounter a Redis server offering a TLS connection using a
917self-signed certificate you may disable certification verification with the
918following:
919
920.. code-block:: python
921
922    CACHES = {
923        "default": {
924            "BACKEND": "django_redis.cache.RedisCache",
925            "LOCATION": "rediss://127.0.0.1:6379/1",
926            "OPTIONS": {
927                "CLIENT_CLASS": "django_redis.client.DefaultClient",
928                "CONNECTION_POOL_KWARGS": {"ssl_cert_reqs": None}
929            }
930        }
931    }
932
933
934License
935-------
936
937.. code-block:: text
938
939    Copyright (c) 2011-2015 Andrey Antukh <niwi@niwi.nz>
940    Copyright (c) 2011 Sean Bleier
941
942    All rights reserved.
943
944    Redistribution and use in source and binary forms, with or without
945    modification, are permitted provided that the following conditions
946    are met:
947    1. Redistributions of source code must retain the above copyright
948       notice, this list of conditions and the following disclaimer.
949    2. Redistributions in binary form must reproduce the above copyright
950       notice, this list of conditions and the following disclaimer in the
951       documentation and/or other materials provided with the distribution.
952    3. The name of the author may not be used to endorse or promote products
953       derived from this software without specific prior written permission.
954
955    THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS`` AND ANY EXPRESS OR
956    IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
957    OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
958    IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
959    INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
960    NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
961    DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
962    THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
963    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
964    THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
965