我们现在正在使用Redis作为Django应用程序的内存缓存(之前我们使用过memcached,并且性能没有太大差异,我们使用Redis因为磁盘转储功能)。
问题是,在我看来,Django缓存的性能非常糟糕。我们有视图,有102个缓存命中(没有未命中),它需要81毫秒(只是缓存部分,用Django调试工具栏测量)。在我看来 - 这是一个巨大的时间。我知道,对DB进行查询会花费10倍的时间(甚至100倍),但即便如此,缓存性能也不好。
我们在不同的主机上运行Redis(以及之前的memcached),在本地网络中与其他服务器连接。
有没有办法在Django中调整缓存性能?
答案 0 :(得分:4)
问题很可能是每个页面需要检索的项目数量,而不是缓存本身的性能。 102缓存调用意味着网络延迟丢失了大量时间。通过多线程或流水线操作可以完全控制代码,但在这种情况下,您没有这个选项 - 使用框架意味着获得更简单的代码,代价是边缘情况下的性能降低。
最简单的修复方法可能是将redis缓存移动到Web服务器上 - 本地请求要快得多。这会使缓存失效变得复杂,但您可以通过复制来解决这个问题 - 要么对主节点进行所有写入操作,要么从本地从属节点读取所有节点都具有相同的缓存,要么在本地写入用于复制a的主节点当您需要使对象无效时,对所有从属执行del命令。
要看的另一件事是性能是否真的是一个问题。加载页面300ms在个人用户体验方面也不算太差。这只是一个问题,如果它意味着你不能在所有用户每秒处理超过3页 - 在这种情况下,瓶颈是网络延迟而不是CPU或本地I / O。
答案 1 :(得分:3)
主机之间的网络延迟可能是原因。只需在localhost上与Redis通信,对于小键和值,需要+ 200us(微秒)。 Memcached还通过网络进行通信,因此遇到了相同的延迟问题。根据您分享的数字,每个请求大约需要800us。
并非所有缓存都通过网络进行通信。更快的方法是将缓存的一部分内存映射到进程的内存中。如果您使用多个Web服务器,那么它们每个都有自己的缓存,但如果您一致地路由请求(通过IP,用户名等),您可以减少缓存未命中。假设您已将数据库移动到单独的主机上,您的Web服务器上可能有备用磁盘周期。
如果您想尝试这种方法,请考虑使用DiskCache,一个Apache2许可磁盘和文件支持的缓存库,用纯Python编写,并与Django兼容。 DiskCache包含许多cache benchmarks和Django cache benchmarks。键和小值被内存映射到Django进程内存中,因此检索速度非常快(比您的设置快3-12倍)。如基准测试中所示,“get”延迟甚至小于Memcached(在localhost上)。您还可以根据自己的喜好自定义一些可调settings。