2011-09-01 71 views
0

我们现在使用Redis作为我们的Django应用程序的内存缓存(我们以前使用过memcached,性能没有太大的区别,因为我们使用Redis,因为磁盘转储功能)。Django缓存性能

问题是,在我看来,Django缓存的性能很糟糕。我们认为,有102个缓存命中(没有丢失),它需要81毫秒(只是缓存部分,用Django调试工具栏测量)。在我看来 - 这是非常多的时间。我知道,对数据库进行查询将花费10倍的时间(甚至100倍),但即使这样,缓存性能也不好。

我们在不同的主机上运行Redis(和之前的memcached),在本地网络中与其他服务器连接。

有什么办法可以调整Django中的缓存性能吗?

+0

难道这81毫秒花费从缓存中取出东西吗?还是包含其他内容?你在缓存什么? HTML片段还是酸洗复杂的对象或模型实例? –

+0

如果81 ms是完整请求,直到您在远程主机上收到响应,那么时间确实相当不错。:) –

+0

81毫秒仅用于获取缓存内容。完整请求(缓存,不可缓存的SQL,模板解析等)大约需要250-300 ms。我们缓存不同的东西,从小块文本(多数)到更大的HTML块。 – ThomK

回答

2

问题很可能是每个页面需要检索的项目数量,而不是缓存本身的性能。 102缓存呼叫意味着网络延迟时间浪费了很多时间。在完全控制代码的情况下,你可以用多线程或流水线来解决这个问题,但在这种情况下,你没有这个选择 - 使用框架意味着以更低性能为代价获得更简单的代码。

最简单的修复方法可能是将redis缓存移动到Web服务器上 - 本地请求速度更快。这会使缓存失效变得复杂化,但是您可以通过复制来修复这个问题 - 要么执行所有写入主节点的操作,并从本地从属设备读取数据,以便所有节点具有相同的缓存,或者使用用于复制当你需要使一个对象失效时,del命令给所有的从站。

要看的另一件事是,如果性能实际上是一个问题。根据个人用户的体验,300ms加载页面并不算太差。如果这意味着您无法在所有用户中处理超过3页的页面,这只是一个问题 - 在这种情况下,不可能出现瓶颈是网络延迟而不是CPU或本地I/O。

2

主机之间的网络延迟可能是原因。在本地主机上与Redis进行简单通信对于小键和值需要+ 200us(微秒)。 Memcached也通过网络进行通信,因此会遇到同样的延迟问题。根据您分享的号码,每个请求大约需要800us。

并非所有缓存都通过网络进行通信。更快的方法是将缓存的一部分直接存储到进程的内存中。如果你使用多个网络服务器,那么他们每个人都有自己的缓存,但如果你一直路由请求(通过IP,用户名等),你可以减少缓存未命中。假设您已将数据库移至单独的主机,您的网络服务器上可能会有可用的磁盘循环。

如果您想尝试此方法,请考虑使用DiskCache,这是一个Apache2许可的磁盘和文件支持缓存库,采用纯Python编写,并与Django兼容。 DiskCache包含许多cache benchmarksDjango cache benchmarks。键和小值被存储器映射到Django进程内存中,因此检索速度非常快(比您的设置快3-12倍)。如基准测试中所示,“get”延迟甚至比Memcached(本地主机上)少。还有一些可调的settings,您可以根据自己的喜好进行自定义。