2013-01-22 31 views
7

Chúng tôi đang sử dụng django để tạo một json webservice front-end cho mysql. Chúng ta có apache và django chạy trên một cá thể EC2 và MySQL chạy trên một cá thể RDS. Chúng tôi đã bắt đầu hiệu suất điểm chuẩn bằng cách sử dụng băng ghế dự bị apache và có một số hiệu suất thực sự kém. Chúng tôi cũng nhận thấy rằng trong khi chạy các thử nghiệm, ví dụ apache/django của chúng tôi đi đến 100% sử dụng CPU ở tải rất thấp và trường hợp MySQL không bao giờ được sử dụng trên 2% cpu.Có cách nào để tăng tốc độ chức năng xác thực trong django không?

Chúng tôi đang cố gắng để làm cho cảm giác này và cô lập các vấn đề, vì vậy chúng tôi đã làm một số xét nghiệm ab:

  1. Một yêu cầu cho một trang html tĩnh từ apache - ~ 2000 yêu cầu/giây.
  2. Yêu cầu thực hiện hàm python nhỏ trong django và không có tương tác db - ~ 1000 yêu cầu/giây.
  3. Yêu cầu thực hiện một trong các chức năng dịch vụ web django của chúng tôi gọi xác thực và sau đó thực hiện truy vấn rất đơn giản để tìm nạp một bản ghi từ bảng - 11 yêu cầu/giây
  4. Giống như 3, nhưng đã nhận xét cuộc gọi để xác thực - - 95 yêu cầu/giây.

Tại sao xác thực quá chậm? Có phải nó đang ghi dữ liệu vào db, tìm kiếm một tỷ chữ số pi, cái gì?

Chúng tôi muốn giữ cuộc gọi để xác thực trong các chức năng này, bởi vì chúng tôi không muốn để chúng mở cho bất kỳ ai có thể đoán url, v.v. Có ai ở đây nhận thấy rằng xác thực chậm và ai có thể đề xuất một cách để khắc phục nó?

Cảm ơn bạn rất nhiều!

+0

Hãy thử một vài điều: tải xuống django-debug-toolbar và đọc đầu ra. Xem loại truy vấn mà nó đang thực hiện. Hãy thử django-profile và đọc thời gian thực hiện chức năng. Cuối cùng, có được newrelic ... thậm chí phiên bản miễn phí sẽ cho bạn thấy sự cố hữu ích cho mỗi lượt xem func. Vui mừng khi nghe một số kết quả! –

Trả lời

7

Tôi không có chuyên gia về xác thực và bảo mật nhưng sau đây là một số ý tưởng về lý do tại sao điều này có thể xảy ra và có thể là cách bạn có thể tăng hiệu suất một chút.

Vì mật khẩu được lưu trữ trong db, để bảo mật lưu trữ, mật khẩu văn bản thô tục không được lưu nhưng thay vào đó, băm của chúng được lưu trữ. Bằng cách này, bạn vẫn có thể xác thực người dùng đăng nhập bằng cách so sánh băm được tính toán từ mật khẩu đã nhập với mật khẩu được lưu trữ trong db. Điều này làm tăng tính bảo mật để nếu một bên độc hại sẽ nhận được một bản sao của db, cách duy nhất để giải mã các mật khẩu thô là bằng cách sử dụng các bảng cầu vồng hoặc tấn công brute-force.

Đây là nơi mọi thứ trở nên thú vị. Theo Định luật Moore, các máy tính đang trở nên nhanh hơn theo cấp số nhân, do đó các hàm băm tính toán trở nên rẻ hơn nhiều về mặt thời gian, đặc biệt là các hàm băm nhanh như md5 hoặc sha1. Điều này đặt ra một vấn đề bởi vì có tất cả sức mạnh tính toán hiện nay kết hợp với các hàm băm nhanh, tin tặc có thể làm cho các mật khẩu băm bị bẻ khóa tương đối dễ dàng. Để chống lại điều này, hai điều có thể được thực hiện. Một hàm lặp vòng hàm băm nhiều lần (đầu ra của hàm băm được đưa trở lại vào hàm băm). Tuy nhiên điều này không hiệu quả vì nó chỉ làm tăng độ phức tạp của hàm băm bằng hằng số. Đó là lý do tại sao phương pháp thứ hai được ưa thích hơn là làm cho hàm băm thực tế phức tạp hơn và tốn kém tính toán. Có chức năng phức tạp hơn, phải mất nhiều thời gian hơn để tính băm. Ngay cả khi nó mất một giây để tính toán, nó không phải là một việc lớn cho người dùng cuối, nhưng nó là một việc lớn đối với tấn công brute-force vì hàng triệu băm phải được tính toán. Đó là lý do tại sao bắt đầu với Django 1.4, nó sử dụng một hàm khá tốn kém tính toán gọi là PBKDF2.

Để quay lại câu trả lời của bạn. Đó là vì chức năng này, khi bạn bật xác thực, số điểm chuẩn của bạn sẽ giảm mạnh và CPU của bạn tăng lên.

Dưới đây là một số cách bạn có thể tăng hiệu suất.

  • Bắt đầu với Django 1.4, bạn có thể thay đổi chức năng xác thực mặc định (docs). Nếu bạn không cần nhiều bảo mật, bạn có thể thay đổi hàm mặc định thành SHA1 hoặc MD5. Điều này sẽ tăng hiệu suất tuy nhiên hãy nhớ rằng bảo mật sẽ yếu hơn nhiều. Ý kiến ​​cá nhân của tôi là bảo mật là quan trọng và đáng giá thêm thời gian nhưng nếu nó không được bảo đảm trong ứng dụng của bạn, đó là điều bạn có thể muốn xem xét.
  • Sử dụng phiên. Hàm băm đắt tiền chỉ được tính trên lần đăng nhập đầu tiên. Khi người dùng đăng nhập, một phiên được tạo cho phiên đó và cookie sẽ được gửi tới người dùng có id phiên. Sau đó, trên các yêu cầu tiếp theo, người dùng tải lên cookie và nếu phiên chưa hết hạn, người dùng sẽ tự động được xác thực (đừng lo lắng về bảo mật vì dữ liệu phiên được ký ...). Vấn đề là phiên xác minh là A LOT ít tốn kém tính toán so với tính toán hàm băm đắt tiền. Tôi đoán rằng trong các bài kiểm tra ab bạn không gửi cookie phiên. Hãy thử thực hiện một số thử nghiệm với việc bổ sung gửi cookie phiên và xem nó hoạt động như thế nào. Nếu việc gửi cookie không thực sự là một lựa chọn vì bạn đang tạo JSON API, thì bạn có thể sửa đổi back-end phiên để chấp nhận dữ liệu phiên thông qua một tham số GET phiên thay vì một cookie. Tuy nhiên, không chắc chắn các nhánh bảo mật là gì.
  • Chuyển sang nginx. Tôi không phải là một chuyên gia trong triển khai nhưng trong kinh nghiệm của tôi nginx là nhanh hơn và thân thiện hơn với Django so với Apache. Một lợi thế mà tôi nghĩ có thể là mối quan tâm đặc biệt với bạn là khả năng nginx có nhiều quy trình công nhân và khả năng sử dụng proxy_pass của nó đối với các yêu cầu đối với quy trình Django. Nếu bạn sẽ có nhiều quy trình công nhân, bạn có thể trỏ từng nhân viên đến một quy trình Django riêng biệt thông qua proxy_pass, điều này sẽ thêm đa xử lý vào Django một cách hiệu quả. Một lựa chọn khác là nếu bạn sử dụng một cái gì đó như máy chủ WSGI gevent, bạn có thể làm cho một hồ bơi trong quá trình Django mà cũng có thể tăng hiệu suất. Không chắc chắn nếu bất kỳ trong số này sẽ làm tăng hiệu suất của bạn đáng kể kể từ khi tải CPU của bạn đã ở 100% nhưng nó có thể là một cái gì đó để xem xét.
+0

Câu trả lời hay, cảm ơn. – HansG600

Các vấn đề liên quan