`
san_yun
  • 浏览: 2662988 次
  • 来自: 杭州
文章分类
社区版块
存档分类
最新评论

Launching a High Performance Django Site

 
阅读更多

Are the brakes on your Django app?

When building an application using an application framework like Django... the priority is often to get the application working first and optimize it later. The trade off is between getting it done and getting it done for 1 million users. Here's a check list of things you can do to make sure your application can be optimized quickly when you put on your optimization hat. Note, most applications don't need all of this since most applications do not get anywhere near enough traffic to justify even bothering. But if you're lucky enough to need to optimize your Django app, I hope this post can help you.

Note, my background is in building very large high traffic sites for companies such as Fanball.com, AOL Fantasy Sports, eBay.ca, PGATour and NASCAR. All of those sites were built using ColdFusion/Microsoft SQLServer or MySQL or Oracle and I only recently jumped into Django. If you're familiar with fantasy sports, you know that you usually rush to a site to set your line up just before a sporting event starts and then you check your score when an event is live. This traffic is extremely high during those peak times, so much so that Fanball.com used to be a top 1000 site according to Alexa during football season. Being new to Django I wished I could have found a post like this when trying to launch a high traffic site.

Caching and Managers
You probably built your app using managers right? Even if you're not building the application for a large number of users, you should be using managers anyway to help reuse code. If you are using managers, going back to retrofix your code to use memcache or some other type of caching is straight forward. Be sure to use cMemcache in your production environment. And be sure NOT to mix cMemcache and the regular memcache python library . The keys they generate are not 100% compatible. You'll be able to read keys from either, but cMemcache won't write keys that regular memcache can always read. I'm not sure why that's true, but you've been warned.

Dog Piling and Caching
This is a big deal. No matter how good you're caching objects, you need to make sure only ONE process is refreshing the cache. There are several ways to handle this. Mint Cache is a good solution. Another solution is to use managers that ONLY read the cached objects, and have a separate process refresh the cache. You can use signals to flag that an object needs to be refreshed. Or you could refresh it on a timed interval.

Health Check for Load Balancers
You have two options to survive a server going down. One is to have a hot spare waiting to be put online. In this scenario the load balancer should do this automatically. Another, is to have that hot swappable server already online and make sure that your load can always be handled with at least 1 server down. I prefer the later solution as this guarantees that the "idle" server is actually functional under load. Opinions vary. Avoid auto shutting down a server from a load balancer. You could cause a death spiral very easily this way.

Access Servers Directly
It's important to be able to access the servers directly, even if you are behind a load balancer. This will often be the only way to reliably test unusual problem that might be happening in production. To do this, make sure the servers are configured to answer at a special URL directly. For example web1.mysite.com. You should have web1.mysite.com in your HOSTS or in your local DNS server. If you can't get to the server directly because of a firewall, try using a free VPN like Hamachi to get through.

Connection Caching
Be sure to have some sort of connection pooling or connection caching. I was able to get SQLAlchemy installed within 30 minutes. It's easy to setup. Make sure that the database timeout value (base.py) in the SQLAlchemy matches the timeout value for the connection at the database.

Avoid Thread Thrashing
Keep those threads alive! Check your Apache settings and make sure that you don't have thread thrashing. You don't want Apache killing and starting threads on you. Every time you do that, Django needs to initialize... an expensive process. Any objects you might have built in memory need to be rebuilt. The database connection needs to be established again. These are all things you only want to do once. Would you boot up your machine every single time you want to send an email? You probably leave it on during working hours. Same thing applies here. Leave those threads on. Here's an example of settings I've used with Apache on a 4 CPU server.

StartServers 20
ServerLimit 20
MinSpareServers 20
MaxClients 20
MaxRequestsPerChild 100000

Note that MaxRequestsPerChild COULD be set to 0 and have the thread never reset, but just in case there's a memory leak somewhere (I have yet to see one) I have it reset every 100k requests. Don't just set the ServerLimit and MaxClients connections to some crazy high number. Remember, there's only so much memory on the server to go around. If you start to swap memory, your server is dead. Additionally, if your server is already CPU bound (85% CPU utilization), setting these numbers higher is not going to help. You'll just increase the overhead of switching between all the processes.

Cache Templates
In a production environment, you should cache templates.Here's a great snippet to do that.

Note About Load Testing
There are two ways to test how your application is going to perform under load. The more expensive, more time consuming and least accurate number can be had with load testing software. You can start to unit test certain parts with software as simple as ab which comes with Apache. You can start to spend some real money on expensive load testing suites with nice reports and that allowing load testing from multiple clients so that you can effectively test against a load balanced farm. Load testing is a completely different test, but just remember that load testing is in fact the least accurate and the most expensive way to load test an application. You can spend lots of time and money building script that try to get close to a real world scenario but will never actually be real. The advantage is that you will get back some useful data and you can do this before a single user hits a web page. A better approach, if it's possible, is to gradually roll-out the application. Gradually increase both the number of users and the number of expensive features. This is not always possible, but usually.. it is.

Reverse DNS and Mutexes
This might sound obvious, but be sure your DBA has checked this one. MySQL likes to do reverse DNS lookups on the IP when it receives a connection. Either start MySQL with --skip-name-resolve or be sure that reverse DNS is configured properly. Also, if you're going to have a large number of connections (probably one per apache thread + a few extra) be sure the mutex count in the OS is set high enough. We've had to raise it to 1000 on a very large installation.

Miscellaneous
Here's a few things covered in other posts , but that I feel I need to include in here because.. well. it's very low hanging fruit. Remember to reduce the number of queries. If you're doing something like this in a template team.player.name and you're not using select_related() or not creating your own object, that means that django will automatically query the data for you. This is a huge problem if it's in a loop. Additionally, try to combine ORM calls if it makes sense. Try to go to the database as little as possible. It's often easy to browse through the queries on a page and see where often used lookups can be cached or different ORM calls can be combined.

Be sure to monitor your disk space. You probably want to turn of most logging on Apache.

Also, please don't serve your images and static content through Python. It's like using your flat bed to transport a letter.

Conclusion
You've already chosen Django and Python so you know you have room to improve performance. Plan ahead. You don't have to slow down development to optimize the application for those mythical million users, but use managers whenever possible. Keep an eye on that query count at the bottom of the page.

If all else fails and you're under the gun, ask . The IRC channel can really help when things are happening right now.

分享到:
评论

相关推荐

    Django 1.0 Website Development.pdf

    A word about Django terminology 25 URLs and views: creating the main page 26 Creating the main page view 26 Creating the main page URL 27 Models: designing an initial database schema 31 The link ...

    电子商务英文课件:ch15 Launching a Successful Online Business.ppt

    电子商务英文课件:Launching a Successful Online Business.ppt 电子商务是指通过互联网进行商业活动的新型商业模式。Launching a Successful Online Business是电子商务的关键组成部分,涉及到在线业务的启动、...

    numactl-2.0.7 解决 mongodb 启动报警告的问题

    ** We suggest launching mongod like this to avoid performance problems: ** numactl --interleave=all mongod [other options] 解决方案:(1)http://oss.sgi.com/projects/libnuma/ 下载numactl-2.0.7.tar....

    The Launching Framework in Eclipse

    ### Eclipse中的启动框架 #### 概述 在集成开发环境(IDE)中,启动(运行或调试)正在开发中的代码的能力是基本且重要的。由于Eclipse更多地被视为一个工具平台而非单一工具,其启动功能完全依赖于当前安装的插件...

    Understanding the Overheads of Launching CUDA Kernels.pdf

    理解CUDA核启动开销 在GPU计算领域,CUDA核(Kernel)扮演着至关重要的角色。然而,在启动CUDA核时,存在着许多潜在的开销,这些开销可能会对程序的性能产生影响。因此,了解和理解CUDA核启动开销对于优化GPU计算...

    AT32f403a的FreeRTOS移植

    AT32F403A是一款由雅特力科技(A特力A)推出的高性能ARM Cortex-M4内核微控制器,具有浮点运算单元(FPU)和数字信号处理器指令集,适用于各种嵌入式应用,包括工业控制、通信设备以及消费电子等。FreeRTOS则是一个...

    Design Engineer’s Guide to OpenVPX

    Act one was the launching of a new high density platform for critical embedded computing applications. Leveraging the wildly popular VMEbus in 3U and 6U Eurocard formats, VPX added the capability of ...

    Matlab class for launching and managing asynchronous processes

    "Matlab class for launching and managing asynchronous processes" 提供了一种高效的方式来启动和管理这些任务,使得用户可以在主MATLAB工作环境中进行其他操作,而不必等待某个任务完成。这个压缩包可能包含了一...

    Understanding the Overheads of Launching CUDA Kernels (Poster17-moc)-计算机科学

    • Implicit barriers: launching separate kernels (impacts performance)I Alternative ways to achieve the same goal • Grid synchronization or multi-grid synchronization [2] • Higher performance might ...

    org.eclipse.jdt.launching_3.6.1.v20111006_r372.jar

    解决myeclipse10运行出现:CreateProcess error=87, ²ÎÊý´í 的问题,直接替换myeclipse安装路径\Common\plugins

    Docker快速上手指南

    通过一个您已经熟悉的任何一种主流的发行版 Linux 虚拟机,就可以开始一个快速简单的 Rancher 测试体验。 建议虚拟机的规格:1vcpu,不小于 4GB 内存,一块能够连通互联网的网卡。本文编写的 测试机是 AWS 虚拟机上...

    django-producthunt-project

    Django 2的新增功能* Uses Python 3* Start Page after launching django development server is different* on_delete is required* URL no longer Regex* Responsive Admin* Auth function changes: - user.is_...

    Win10安装软件提示“Error launching installer”的解决方法.docx

    ### Win10安装软件提示“Error launching installer”的解决方法 #### 故障现象与原因分析 在使用Windows 10操作系统的过程中,用户可能会遇到在安装软件时弹出“Error launching installer”错误提示的情况。这一...

    ADC.zip_k20 board_k20单片机_launching k20 lab_scm

    标题中的"ADC.zip_k20 board_k20单片机_launching k20 lab_scm"揭示了这个压缩包文件的主要内容,它涉及到K20单片机在实验板上的应用,具体是关于ADC(模拟到数字转换)的实现,并且提到了软件配置管理(SCM)的过程...

    Six Sigma(六质管理) 第一个90天

    This book offers leaders a proven turnkey approach to launching a Six Sigma initiative in 90 days and using it to transform your company within a year. Drawing on their experience with fifty Six ...

    Managed Directx 9 Kick Start - Graphics And Game Programming

    Launching Applications Using a Lobby Making Your Application Lobby Aware Adding Voice Chat to Your Sessions In Brief Chapter 21. Achieving Maximum Performance Using Value Types as Objects...

    prof-t07-the-untold-stor-of-8200-a-launching-point-for-women-

    标题中的"8200"通常指的是以色列国防军的一个情报单位,它在培养网络安全专家方面具有重要地位。这个单位以其严谨的训练和高度的技术要求而闻名,为许多未来的网络安全专业人士提供了起点,包括女性。...

Global site tag (gtag.js) - Google Analytics