简体   繁体   English

Django-redis-cache无法从Redis获取数据

[英]Django-redis-cache failing to fetch data from redis

I have a question regarding the working of this package. 我对这个程序包的工作有疑问。 How does it writes to redis db ? 它如何写入redis db?

This is my settings for redis - 这是我对Redis的设置-

CACHES = {
     'default': {
    'BACKEND': 'redis_cache.RedisCache',
    'LOCATION': '/var/run/redis/redis.sock',
    'OPTIONS': {
        'DB': 2,
    },
},
}

This is my views file, 这是我的意见档案,

def postview(request):
    print("Working")
   #post_list = Post.objects.all()
    if cache.get("posts") == None:
            post_list = Post.objects.all()
            print("going to be cached")
            a = cache.get("aman")
            print("aman ", a)
            cache.set("posts", post_list, timeout=60*100*10)
            print("cached")
    else :
            post_list = cache.get("posts")
            aman = cache.get("aman")
            print(aman, " aman's job")
            print("already present in cache")
    context = {"post_list" : post_list}
    print("Problem")
    return render(request, 'post_list.html', context)

@cache_page(60*15*10, key_prefix="cache_redis")
def testview(request):
    post_list = cache.get("posts")
    print("post_list is", post_list)
    return render(request, 'post_list.html', {"post_list":post_list})

@cache_page(60*25*10, key_prefix="cache_test")
def new(request):
    print("Hey")
    print("cache_page is working")
    return HttpResponse("Hello, I am Mohammed")

This is my redis -cli , 这是我的redis -cli,

luvpreet@DHARI-Inspiron-3542:~/test_venv_wrapper/test_redis/cache_redis$ redis-cli
127.0.0.1:6379> select 2
 OK
127.0.0.1:6379[2]> set "a" "aman"
 OK
127.0.0.1:6379[2]> set ":1:a" "theman"
 OK
 127.0.0.1:6379[2]> keys *
 1) "a"
 2)":1:views.decorators.cache.cache_page..GET.ad00468064711919773512f81be0dbc4.d41d8cd98f00b204e9800998ecf8427e.en-us.UTC"
 3) ":1:posts"
 4) ":1:a"
 5) ":1:aman"
 6) ":1:views.decorators.cache.cache_header.cache_test.ad00468064711919773512f81be0dbc4.en-us.UTC"
 7) ":1:views.decorators.cache.cache_header..ad00468064711919773512f81be0dbc4.en-us.UTC"
 8) ":1:b"
 9)":1:views.decorators.cache.cache_page.cache_test.GET.ad00468064711919773512f81be0dbc4.d41d8cd98f00b204e9800998ecf8427e.en-us.UTC"
10) "aman"
127.0.0.1:6379[2]> get ":1:a"
"theman"
127.0.0.1:6379[2]> get "a"
"aman"

This is the corresponding redis-cli monitor 这是对应的redis-cli监视器

luvpreet@DHARI-Inspiron-3542:~/test_venv_wrapper/test_redis/cache_redis$ redis-cli monitor
OK
1491412249.001149 [0 unix:/var/run/redis/redis.sock] "INFO"
1491412249.086196 [0 127.0.0.1:44984] "select" "2"
1491412250.001249 [0 unix:/var/run/redis/redis.sock] "INFO"
1491412257.001426 [0 unix:/var/run/redis/redis.sock] "INFO"
1491412257.423536 [2 127.0.0.1:44984] "set" "a" "aman"
1491412258.001311 [0 unix:/var/run/redis/redis.sock] "INFO"
1491412269.001211 [0 unix:/var/run/redis/redis.sock] "INFO"
1491412269.820886 [2 127.0.0.1:44984] "set" ":1:a" "theman"
1491412270.000741 [0 unix:/var/run/redis/redis.sock] "INFO"
1491412272.955386 [2 127.0.0.1:44984] "keys" "*"
1491412273.001121 [0 unix:/var/run/redis/redis.sock] "INFO"
1491412340.991928 [2 127.0.0.1:44984] "get" ":1:a"
1491412341.002001 [0 unix:/var/run/redis/redis.sock] "INFO"
1491412344.106985 [2 127.0.0.1:44984] "get" "a"
1491412345.001677 [0 unix:/var/run/redis/redis.sock] "INFO"

This means that data which I am manually inserting into the database 2 is available and I can fetch that through redis-cli. 这意味着可以手动插入数据库2中的数据,并且可以通过redis-cli进行获取。

But when I try to fetch this manually entered data from the django-app python shell, This happens, 但是,当我尝试从django-app python shell获取手动输入的数据时,就会发生这种情况,

>>> from django.core.cache import cache
>>> cache.get("a")
Traceback (most recent call last):
   File "<console>", line 1, in <module>
   File "/usr/local/lib/python2.7/dist-packages/redis_cache/backends/base.py", line 33, in wrapped
     return method(self, client, key, *args, **kwargs)
   File "/usr/local/lib/python2.7/dist-packages/redis_cache/backends/base.py", line 259, in get
     value = self.get_value(value)
   File "/usr/local/lib/python2.7/dist-packages/redis_cache/backends/base.py", line 210, in get_value
     value = self.deserialize(value)
   File "/usr/local/lib/python2.7/dist-packages/redis_cache/backends/base.py", line 197, in deserialize
     return self.serializer.deserialize(value)
   File "/usr/local/lib/python2.7/dist-packages/redis_cache/serializers.py", line 42, in deserialize
     return pickle.loads(force_bytes(value))
UnpicklingError: could not find MARK

Here is the redis-cli monitor corresponding to it, 这是与之相对应的redis-cli监视器,

OK
1491413058.004167 [0 unix:/var/run/redis/redis.sock] "INFO"
1491413059.002746 [0 unix:/var/run/redis/redis.sock] "INFO"
1491413060.663292 [2 unix:/var/run/redis/redis.sock] "GET" ":1:a"
1491413061.001167 [0 unix:/var/run/redis/redis.sock] "INFO"

Why cannot I access the data written manually ? 为什么不能访问手动写入的数据? I know that it adds a prefix to the data written through django. 我知道它为通过django写入的数据添加了前缀。 The prefix is ":1:key_name" . 前缀是":1:key_name" That's why I added 2 keys namely "a" and ":1:a". 这就是为什么我添加了两个键,即“ a”和“:1:a”的原因。 So that when I try to access the "a", it will call ":1:a". 这样,当我尝试访问“ a”时,它将调用“:1:a”。

But this error comes up. 但是出现此错误。 So, it definitely might be writing data to redis by some other way. 因此,它肯定是通过其他方式将数据写入Redis。 Please tell me about the error and also tell me the way in which it writes data. 请告诉我有关错误的信息,并告诉我其写入数据的方式。

The error you are gettting is not a data retreival error, the data is being retreived, but it is not in correct pickle format. 您得到的错误不是数据检索错误,正在检索数据,但不是正确的泡菜格式。

  • When you are setting data manually, it is being set in byte format, not pickled format. 当您手动设置数据时,它是以字节格式而不是腌制格式设置的。
  • When you set data through django-redis, your data is first serialized using cPickle, and then stored into redis as pickled string. 通过django-redis设置数据时,首先使用cPickle序列化数据,然后将其作为腌制字符串存储到redis中。

  • When you retreive the data stored through django-redis, it is retreived as the pickle serialized string, and then deserialized into corresponding python datatype. 检索通过django-redis存储的数据时,会将其检索为pickle序列化的字符串,然后反序列化为相应的python数据类型。

  • Your manually entered data is string type, but not in correct pickle format, hence though it gets retreived, it cannot be converted into corresponding python type, and you get the pickling error. 您手动输入的数据是字符串类型,但不是正确的泡菜格式,因此尽管检索了该数据,但无法将其转换为相应的python类型,并且出现了酸洗错误。
  • The solution is to use django-redis itself in the django shell or your code to store and retreive data, entering data manually breaks the serialization contract. 解决方案是在django shell或代码中使用django-redis本身来存储和检索数据,手动输入数据会破坏序列化协定。

Example: 例:

>>> from django.core.cache import cache
>>> cache.set("THE_KEY","aman")
True
>>> cache.get("THE_KEY")
'aman'
>>> 
dhruv@dhruvpathak:~$ redis-cli
127.0.0.1:6379> keys *
 1) ":1:THE_KEY"
127.0.0.1:6379> get ":1:THE_KEY"
"\x80\x02U\x04amanq\x01."
127.0.0.1:6379> set "THE_MANUAL_KEY" "aman"
OK
127.0.0.1:6379> get "THE_MANUAL_KEY" 
"aman"

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM