django用redis缓存
#python #django #cache #redis

介绍

django是那些可以在其中投入足够的时间并注意小细节的框架之一。这是一个具有丰富功能且非常可定制的框架。我很高兴您(读者)分享最大程度地利用Django的热情。在阅读数据库访问改进时,Django中的缓存引起了我的注意。因此,我决定研究如何将Redis与Django联系起来,以替代Memcached。

设置和环境

考虑到该主题与改善数据库可访问性有关,我认为仅继续从事我们在那里使用的同一项目工作很合适。您可以在以下链接上看到有关项目设置的更多信息:
Improving Database Accessibility

为什么要使用缓存?

如上所述,缓存是一种用于加速最终用户数据访问的方法。它消除了准备数据并将其发送给用户所需的处理时间。数据提前准备好了。我们遇到了缓存,同时使用了众所周知的页面,例如Instagram,Facebook和Google如此快速而充满活力的网站,所有这些网站都使用。因此,在我们的Django项目中使用缓存并不是一个坏主意。

更快的速度 - 更快的用户满意度。缓存是一项不错的投资。随着动态网站的增长,您需要速度的需求。

现在,这完全取决于我们的需求。例如,我们可能不会构建一个完全动态的网站,但是尽管如此,我们可能会有可能受益于缓存的动态元素。众所周知,Django提供了缓存每个站点,众多和模板片段缓存(在一定程度上(以及各种接口和低级缓存),它们有利于我们有利于我们可以缓存大到小细分市场我们的项目。

应该提到的一些主题演讲。缓存需要存储/主存储空间,可能涉及其他背景过程。它的成本可能会有所不同,具体取决于我们决定放置您的数据的位置。它可以存储在RAM,远程数据库或本地存储(HDD,SSD)中 - 所有都是有效的选项,RAM是最快和最局部存储的最快。那么我们如何选择合适的一个?

如果我们被硬件瓶装,那么我们将使用未充分利用和未使用的任何硬件资源用于我们的缓存。

应该缩小我们的选择。例如,RAM通常比存储驱动器更珍贵。如果我们有很多东西,那就选择最快的选择。好的,让我们探索一些很酷的选择,看看我们为我们准备了什么。

Django的选项

Django中的缓存配置通常很简单明了。很酷的事情是,我们实际上可以使用与Django和第三方软件兼容的纯Python库。这扩大了我们的可能性。但是对于本文,我们将仅探索Redis。

Redis

像memcached一样,Redis使用RAM进行数据存储。它被描述为内存数据库或主内存数据库系统。

Redis和Memcached之间的差异

乍一看,很难注意到Redis和Memcached之间的差异。他们都提供子毫秒响应时间,允许通过内存数据库跨多个节点进行数据分布,并提供高可扩展性。但令人惊讶的是,它们有很大差异。这是一些显着的区别:

  1. 命令行:memcached是直接的,并通过telnet连接到服务器以执行命令,另一方面,Redis,提供专用的redis-cliâ,这是一个专用的命令行界面。
  2. 磁盘倾销:模因依赖于第三方工具来处理磁盘转储,而REDIS具有高度可配置的机制,例如RDB(REDIS数据库文件),这也可能涉及一些背景过程。
  3. 数据结构:备忘录将数据存储为字符串的键值对,而REDIS支持列表,Set,Hash等其他数据结构。
  4. 体系结构:Redis在使用单个核心时处理较小的数据集时显示出更好的性能。另一方面,MEMCACH是使用具有多个内核的多线程体系结构,并且在处理较大的数据集时表现出更好的性能。有关参考的更多详细信息[2]。

个人意见:在比较方法,方法,技术和其他人时,我避免宣布获胜者(即使他们很明显)。我认为每个开发人员都非常快地了解客户的请求/需求有各种形状和大小。因此,我喜欢保持自己的选择开放,一切都可以成为工具,如果我们想涵盖更多情况,那么拥有替代选择可能会派上用场。我们分析情况,预测未来需求并相应地选择软件/软件包。

安装

正式在Linux和MacOS上支持Redis。 Windows用户可以通过VM或WSL(Linux子系统)使用REDIS。现在,考虑到我有一个不支持WSL2的Windows版本,我将使用Hyper V Virtual Machine解决方案并为我的Redis设置Debian Distribution(Debian ISO版本)。首先,我们需要从其官方网站上获得Debian发行版(如果使用Intel/AMD处理器获取AMD64版本)。

超级v

在我们开始使用VM之前,我们需要配置我们的NAT。 NAT(网络地址翻译)将处理我们与VM的网络连接。如果我们打算将我们的Django项目与Redis端口联系起来,我们还将需要它。

配置NAT:

  1. Open W. Powershell担任管理员
  2. 创建NAT虚拟网络
New-VMSwitch -SwitchName "nat4debian" -SwitchType Internal
  1. 获取您新创建的NAT的IfIndex
Get-NetAdapter
  1. 配置网关
New-NetIPAddress -IPAddress 192.168.0.1 -PrefixLength 24 -InterfaceIndex 88
  1. [可选步骤–信息]打开视图网络连接
nat4debian → Status → Details → IPv4 Address (192.168.0.1) and our IPv4 Subnet Mask (255.255.240.0)

如果您需要有关上述任何步骤的解释,则可以在参考[5]中找到它们。您也可能有一个已经配置的默认开关(vethernet),可能随附了Hyper V安装。

Hyper V Manager:

  1. 动作 - 新的VM名称:Debian11 gen1启动内存:4096MB(4GB,UNCHECK DYAMIC MOMERY)â连文:Nat4Debian vhdx:默认值 - 从图像文件(.ISO)安装:debian-11.5.iso finish
  2. 运行VM并执行Debian安装

GNU/Linux&redis安装:

  1. 保持安装灯使用“安装”(非GUI选项)。请按照安装步骤进行到“网络配置”。到达那里后,输入您的IPv4地址(192.168.3.232)。如果您失败了Debian Archive Mirror Country步骤 - 您可能需要仔细检查网络配置步骤。
  2. 软件选择:仅标准系统实用程序。其他一切都应该关闭。请记住,我们保持安装轻巧和成本效益。任何不必要的背景(例如来自桌面侏儒)都是不可取的。如果您觉得需要GUI,请安装GNOME。
  3. 安装结束后,抬起终端并运行命令的REDIS安装顺序:
# Enter root (sudoer), enter your root password
su - 
# You can get it via curl (add it to apt) then just install via apt
# I will install it with snapcraft
apt update
apt install snapd
# Snap will autoupdate then install redis
snap install redis
# Test if Redis is working correctly
redis-cli ping
# Response is "PONG"

现在,就我的重新安装安装而言,redis-Cli的路径不当。如果也是您的情况,您可以进行Redis-Cli的手动运行(您的.profile中没有路径),例如:

cd /snap/redis/current/usr/bin
./redis-cli ping
# You can type 
redis-cli
# To get address and port of the server, if not started then run
./redis-server

Django实施

现在,我们的Redis服务器正在运行并运行,我们需要做的下一步是配置Django绑定到我们的服务器。 Django用REDIS库来支持Redis,并建议安装Hiredis软件包。 hiredis的软件包通过处理将作为我们的解析器的读者类来处理多块式答复,从而改善了Django和Redis之间的沟通。为了充分利用REDIS包,我们还可以使用可选的Django-Redis软件包,该软件包为可容纳的客户,串行序列化,原始访问和许多其他功能提供。

让我们安装这些软件包:

pip install redis
pip install hiredis
pip install django-redis

一旦安装了,该处理我们的设置了。

CACHES = {
    'default': {
        'BACKEND': 'django_redis.cache.RedisCache',
        'LOCATION': 'redis://127.0.0.1:6379',
        'OPTIONS': {
            'CLIENT_CLASS': 'django_redis.client.DefaultClient',
        }
    }
}

让我们创建一个基于功能的简单视图来测试我们的连接:

def test_redis(request):
    get_redis_connection("default").flushall()
    return HttpResponse()

如果运行此视图,您将获得这样的错误:

redis.exceptions.ConnectionError: Error 10061 connecting to 127.0.0.1:6379. No connection could be made because the target machine actively refused it.

这是因为我们需要通过NAT网络网关搜索REDIS。因此,我们保留了Redis端口,但通过网关访问它。在Debian中,您需要从提供的网关(192.168.0.1)创建一个IPv4地址,然后在您的设置中输入该地址。

CACHES = {
    'default': {
        'BACKEND': 'django_redis.cache.RedisCache',
        'LOCATION': 'redis://192.168.3.232:6379',
        'OPTIONS': {
            'CLIENT_CLASS': 'django_redis.client.DefaultClient',
            'PASSWORD': 'debian'
        }
    }
}

现在我们可以访问REDIS服务器。我们需要做的最后一件事是禁用Redis的保护模式:

./redis-cli
config set protected-mode no

您还可以找到一个config file-/etc/redis/â,并设置值。我们运行测试视图,应该返回``是的,我们都有redis服务器访问。

重要:完全建议使用REDIS服务时使用适当的身份验证。用于测试目的,我将跳过身份验证设置步骤。如果使用redis.py软件包,您很可能必须嵌入您的用户名和密码才能访问Redis服务器(事实上,必须)。此外,Django-REDIS软件包警告我们,Redis ACL(访问控制列表)需要在尝试访问时进行身份验证。

简单的基准测试

我们的设置完成了,让我们进行一些简单的基准测试以查看REDIS性能的好处,但是在此之前,Redis的官方页面上的记忆足迹上的快速注释:

100万个小键 - >字符串值对使用〜85MB的内存。
100万键 - >哈希值,代表一个具有5个字段的对象,使用〜160 MB的内存。

我们位于Redis服务器的环境具有4GB RAM的容量,但是我们没有限制/检查RAM REDIS实际使用了多少。我通常不喜欢让任何野外奔跑,尤其是我的公羊,所以让我们设置最大的内存重新使用以下命令:

./redis-cli
config get maxmemory
config set maxmemory 512M
# Response: OK

我的建议:始终开始小,然后在需要时增加 - RAM是一种昂贵的资源!遵循高于512m的内存足迹是一个很好的起点。分配的资源始终可以轻松调整。

让我们修复一个渲染函数视图,该视图获取所有对象(及其相关对象)。我们的商店模型现在将派上用场:

@cache_page(180)
def test_redis(request):
    # get_redis_connection("default").flushall()
    try:
        stores = Stores.objects.select_related('manager').all()
    except (Stores.DoesNotExist, ObjectDoesNotExist) as e:
        print(e)
        stores = None
        pass

    return render(request, "demo_temp.html", {'data': stores})

现在,在此视图中,第一个呼叫的缓存仅设置为设置,因此我们会注意到数据已经缓存时第二视图调用的性能差异。在我们的Redis-CLI上,我们进行检查以查看是否已经有任何数据:

./redis-cli
keys *
# It should respond with '(empty array)'
# If there is any data, empty the cache with
flushall

这些是从django-debug-toolbar收到的比较时间:

# Average of 3x repeated process to compensate for background processes from IDE
Total: 427.72ms ~ average
# Access after cache has been set
Total: 15.00ms

工作就像魅力!我们得到了理想的效果。

在哪里使用它

redis缓存服务最好远程使用,可能是在纯Linux或MacOS环境中使用,在该环境中,专用硬件资源被分配并用于REDIS(缓存)服务。如果没有背景流程与RAM分配混乱,那么REDIS服务将大大受益。但这是一个敏感的主题,我们再次需要重申以前听到的情绪。 这取决于,如我们所见,我们可以在没有问题的情况下设置REDIS在VM或Localhost上本地工作。尽管如此,从硬件的角度看,我们确实通过拿走4GB RAM并添加背景流程而导致的背景流程,这是超级V VM的结果(任何严重的/主要项目分配都需要更多,都需要更多)。

redis是可访问,可自定义且安全的。此外,Django从3.2版本到4.1版本,致力于引入越来越多的异步支持功能,使远程redis访问完全是有效的选择,具有最小的性能退化。当然,如果有可能在本地使用REDI(例如本地网络)而不是远程使用,我认为由于缺乏可能的延迟问题,这种方法对性能更加友好。异步肯定会通过使用等待来正常工作。 Redis绝对值得进行设置和硬件牺牲的投资。

附录:访问缓存

与此主题相关,如何访问REDIS中的存储数据(缓存)是另一个同样重要的主题。在参考文献[3]和[4]中找到更多信息。

参考

[1] data-flair.Training,djangoCachingâ,https://data-flair.training/blogs/django-caching/

[2] baeldung.com,memcached vsredisâ,https://www.baeldung.com/memcached-vs-redis

[3]âcons.dproject.com,cacheâ,https://docs.djangoproject.com/en/4.1/topics/cache/#accessing-the-cache

[4]redis.ioâ,在Windows上安装redis,https://redis.io/docs/getting-started/installation/install-redis-on-windows/”

[5]学习。microsoft.com,建立一个nat网络,https://learn.microsoft.com/en-us/virtualization/hyper-v-on-windows/user-guide/setup-nat-network”

[6] redis.io,什么是redis内存足迹?