БСсплатная ΠΊΠΎΠ½ΡΡƒΠ»ΡŒΡ‚Π°Ρ†ΠΈΡ

ΠžΠΏΠΈΡˆΠΈΡ‚Π΅ Π·Π°Π΄Π°Ρ‡Ρƒ ΠΈΠ»ΠΈ Ρ†Π΅Π»ΡŒ. ΠžΡ‚Π²Π΅Ρ‡Ρƒ с практичСским ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠΌ шагом β€” бСсплатно, Π±Π΅Π· ΠΎΠ±ΡΠ·Π°Ρ‚Π΅Π»ΡŒΡΡ‚Π².

Или Π²Ρ‹Π±Π΅Ρ€ΠΈΡ‚Π΅ врСмя Π² Calendly

Π‘Π½ΠΈΠΆΠ΅Π½ΠΈΠ΅ p95 latency Π² Django: N+1, кСши ΠΈ вынос Π² ΠΎΡ‡Π΅Ρ€Π΅Π΄ΠΈ

Π§Ρ‚ΠΎ ломаСтся Π² ΠΏΡ€ΠΎΠ΄Π΅

ΠŸΡ€Π΅Π΄ΡΡ‚Π°Π²ΡŒΡ‚Π΅ сСбС: ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»ΠΈ ΠΆΠ°Π»ΡƒΡŽΡ‚ΡΡ Π½Π° ΠΌΠ΅Π΄Π»Π΅Π½Π½ΡƒΡŽ Ρ€Π°Π±ΠΎΡ‚Ρƒ прилоТСния, Π° ΠΌΠ΅Ρ‚Ρ€ΠΈΠΊΠΈ ΠΏΠΎΠΊΠ°Π·Ρ‹Π²Π°ΡŽΡ‚, Ρ‡Ρ‚ΠΎ 95% запросов ΠΎΠ±Ρ€Π°Π±Π°Ρ‚Ρ‹Π²Π°ΡŽΡ‚ΡΡ с Π·Π°Π΄Π΅Ρ€ΠΆΠΊΠΎΠΉ Π±ΠΎΠ»Π΅Π΅ 2 сСкунд. ΠŸΡ€ΠΈ этом сСрвСры Π½Π΅ ΠΏΠ΅Ρ€Π΅Π³Ρ€ΡƒΠΆΠ΅Π½Ρ‹, Π° Π±Π°Π·Π° Π΄Π°Π½Π½Ρ‹Ρ… Ρ€Π°Π±ΠΎΡ‚Π°Π΅Ρ‚ ΡΡ‚Π°Π±ΠΈΠ»ΡŒΠ½ΠΎ. Π’ Ρ‡Π΅ΠΌ ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌΠ°?

Часто ΠΏΡ€ΠΈΡ‡ΠΈΠ½ΠΎΠΉ ΠΌΠΎΠΆΠ΅Ρ‚ Π±Ρ‹Ρ‚ΡŒ классичСская ошибка N+1, ΠΊΠΎΠ³Π΄Π° для получСния Π΄Π°Π½Π½Ρ‹Ρ… выполняСтся слишком ΠΌΠ½ΠΎΠ³ΠΎ запросов ΠΊ Π±Π°Π·Π΅. НапримСр, ΠΏΡ€ΠΈ Π·Π°Π³Ρ€ΡƒΠ·ΠΊΠ΅ списка Π·Π°ΠΊΠ°Π·ΠΎΠ² для ΠΊΠ°ΠΆΠ΄ΠΎΠ³ΠΎ Π·Π°ΠΊΠ°Π·Π° Π΄ΠΎΠΏΠΎΠ»Π½ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎ Π·Π°ΠΏΡ€Π°ΡˆΠΈΠ²Π°ΡŽΡ‚ΡΡ связанныС Π΄Π°Π½Π½Ρ‹Π΅, Ρ‚Π°ΠΊΠΈΠ΅ ΠΊΠ°ΠΊ информация ΠΎ ΠΊΠ»ΠΈΠ΅Π½Ρ‚Π°Ρ… ΠΈΠ»ΠΈ Ρ‚ΠΎΠ²Π°Ρ€Π°Ρ…. Π­Ρ‚ΠΎ ΠΏΡ€ΠΈΠ²ΠΎΠ΄ΠΈΡ‚ ΠΊ Π»Π°Π²ΠΈΠ½ΠΎΠΎΠ±Ρ€Π°Π·Π½ΠΎΠΌΡƒ росту количСства SQL-запросов.

Π”Ρ€ΡƒΠ³ΠΎΠΉ частый сцСнарий β€” отсутствиС ΠΊΠ΅ΡˆΠΈΡ€ΠΎΠ²Π°Π½ΠΈΡ. Π”Π°ΠΆΠ΅ Ссли Π΄Π°Π½Π½Ρ‹Π΅ Ρ€Π΅Π΄ΠΊΠΎ ΠΌΠ΅Π½ΡΡŽΡ‚ΡΡ, ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ ΠΊΠ°ΠΆΠ΄Ρ‹ΠΉ Ρ€Π°Π· обращаСтся ΠΊ Π±Π°Π·Π΅, Ρ‡Ρ‚ΠΎ ΡƒΠ²Π΅Π»ΠΈΡ‡ΠΈΠ²Π°Π΅Ρ‚ Π·Π°Π΄Π΅Ρ€ΠΆΠΊΠΈ. НаконСц, тяТСлыС Ρ„ΠΎΠ½ΠΎΠ²Ρ‹Π΅ Π·Π°Π΄Π°Ρ‡ΠΈ, Ρ‚Π°ΠΊΠΈΠ΅ ΠΊΠ°ΠΊ гСнСрация ΠΎΡ‚Ρ‡Π΅Ρ‚ΠΎΠ² ΠΈΠ»ΠΈ ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠ° Π±ΠΎΠ»ΡŒΡˆΠΈΡ… объСмов Π΄Π°Π½Π½Ρ‹Ρ…, ΠΌΠΎΠ³ΡƒΡ‚ Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ основныС рСсурсы, замСдляя ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΡƒ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒΡΠΊΠΈΡ… запросов.

Π§Ρ‚ΠΎ ΠΌΠ΅Π½ΡΡ‚ΡŒ тСхничСски

Π§Ρ‚ΠΎΠ±Ρ‹ ΡΠ½ΠΈΠ·ΠΈΡ‚ΡŒ p95 latency, Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΎ ΡƒΡΡ‚Ρ€Π°Π½ΠΈΡ‚ΡŒ ΠΊΠΎΡ€Π½Π΅Π²Ρ‹Π΅ ΠΏΡ€ΠΈΡ‡ΠΈΠ½Ρ‹ ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌΡ‹. Π’ΠΎΡ‚ провСряСмый чСклист:

1. Π˜Π΄Π΅Π½Ρ‚ΠΈΡ„ΠΈΠΊΠ°Ρ†ΠΈΡ ΠΈ устранСниС N+1 запросов

Ошибка N+1 запросов Π²ΠΎΠ·Π½ΠΈΠΊΠ°Π΅Ρ‚, ΠΊΠΎΠ³Π΄Π° ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ выполняСт Π΄ΠΎΠΏΠΎΠ»Π½ΠΈΡ‚Π΅Π»ΡŒΠ½Ρ‹ΠΉ запрос ΠΊ Π±Π°Π·Π΅ Π΄Π°Π½Π½Ρ‹Ρ… для ΠΊΠ°ΠΆΠ΄ΠΎΠ³ΠΎ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π° Π² основном запросС. НапримСр, Π² Django это часто случаСтся ΠΏΡ€ΠΈ доступС ΠΊ связанным ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π°ΠΌ Π² Ρ†ΠΈΠΊΠ»Π΅. Рассмотрим ΠΏΡ€ΠΈΠΌΠ΅Ρ€:


# ΠŸΡ€ΠΈΠΌΠ΅Ρ€ N+1 ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌΡ‹
orders = Order.objects.all()
for order in orders:
    print(order.customer.name)  # ΠΊΠ°ΠΆΠ΄Ρ‹ΠΉ Ρ€Π°Π· выполняСтся ΠΎΡ‚Π΄Π΅Π»ΡŒΠ½Ρ‹ΠΉ SQL-запрос для customer

Π’ этом случаС для ΠΊΠ°ΠΆΠ΄ΠΎΠ³ΠΎ Π·Π°ΠΊΠ°Π·Π° выполняСтся ΠΎΡ‚Π΄Π΅Π»ΡŒΠ½Ρ‹ΠΉ запрос для получСния Π΄Π°Π½Π½Ρ‹Ρ… ΠΎ ΠΊΠ»ΠΈΠ΅Π½Ρ‚Π΅. Если Ρƒ нас 100 Π·Π°ΠΊΠ°Π·ΠΎΠ², это ΠΏΡ€ΠΈΠ²Π΅Π΄Π΅Ρ‚ ΠΊ 101 запросу (1 запрос для получСния всСх Π·Π°ΠΊΠ°Π·ΠΎΠ² ΠΈ 100 запросов для получСния Π΄Π°Π½Π½Ρ‹Ρ… ΠΎ ΠΊΠ»ΠΈΠ΅Π½Ρ‚Π°Ρ…).

Как ΠΈΡΠΏΡ€Π°Π²ΠΈΡ‚ΡŒ

Для устранСния этой ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌΡ‹ Π² Django ΠΌΠΎΠΆΠ½ΠΎ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ ΠΌΠ΅Ρ‚ΠΎΠ΄Ρ‹ select_related ΠΈ prefetch_related:


# Π˜ΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅ΠΌ select_related для "ΠΆΠ°Π΄Π½ΠΎΠΉ" Π·Π°Π³Ρ€ΡƒΠ·ΠΊΠΈ связанных Π΄Π°Π½Π½Ρ‹Ρ…
orders = Order.objects.select_related('customer').all()
for order in orders:
    print(order.customer.name)  # Π΄Π°Π½Π½Ρ‹Π΅ ΠΎ customer ΡƒΠΆΠ΅ Π·Π°Π³Ρ€ΡƒΠΆΠ΅Π½Ρ‹

select_related ΠΏΠΎΠ΄Ρ…ΠΎΠ΄ΠΈΡ‚ для "ΠΎΠ΄ΠΈΠ½-ΠΊ-ΠΎΠ΄Π½ΠΎΠΌΡƒ" ΠΈΠ»ΠΈ "ΠΌΠ½ΠΎΠ³ΠΈΠ΅-ΠΊ-ΠΎΠ΄Π½ΠΎΠΌΡƒ" связСй. Для "ΠΌΠ½ΠΎΠ³ΠΈΠ΅-ΠΊΠΎ-ΠΌΠ½ΠΎΠ³ΠΈΠΌ" ΠΈΠ»ΠΈ "ΠΎΠ΄ΠΈΠ½-ΠΊΠΎ-ΠΌΠ½ΠΎΠ³ΠΈΠΌ" связСй Π»ΡƒΡ‡ΡˆΠ΅ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ prefetch_related, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ выполняСт ΠΎΡ‚Π΄Π΅Π»ΡŒΠ½Ρ‹ΠΉ запрос, Π½ΠΎ ΠΎΠΏΡ‚ΠΈΠΌΠΈΠ·ΠΈΡ€ΡƒΠ΅Ρ‚ Π΅Π³ΠΎ:


# Π˜ΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅ΠΌ prefetch_related для "Π»Π΅Π½ΠΈΠ²ΠΎΠΉ" Π·Π°Π³Ρ€ΡƒΠ·ΠΊΠΈ связанных Π΄Π°Π½Π½Ρ‹Ρ…
orders = Order.objects.prefetch_related('items').all()
for order in orders:
    for item in order.items.all():
        print(item.name)

Π’Π°ΠΆΠ½ΠΎ ΠΏΠΎΠΌΠ½ΠΈΡ‚ΡŒ, Ρ‡Ρ‚ΠΎ select_related ΠΈ prefetch_related Π½Π΅ всСгда взаимозамСняСмы. ΠžΡˆΠΈΠ±ΠΎΡ‡Π½Ρ‹ΠΉ Π²Ρ‹Π±ΠΎΡ€ ΠΌΠΎΠΆΠ΅Ρ‚ привСсти ΠΊ ΡƒΠ²Π΅Π»ΠΈΡ‡Π΅Π½ΠΈΡŽ объСма Π΄Π°Π½Π½Ρ‹Ρ…, ΠΏΠ΅Ρ€Π΅Π΄Π°Π²Π°Π΅ΠΌΡ‹Ρ… ΠΈΠ· Π±Π°Π·Ρ‹, Ρ‡Ρ‚ΠΎ Ρ‚ΠΎΠΆΠ΅ Π½Π΅Π³Π°Ρ‚ΠΈΠ²Π½ΠΎ скаТСтся Π½Π° ΠΏΡ€ΠΎΠΈΠ·Π²ΠΎΠ΄ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎΡΡ‚ΠΈ.

Как ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΈΡ‚ΡŒ

  • Π˜ΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠΉΡ‚Π΅ django-debug-toolbar, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΡƒΠ²ΠΈΠ΄Π΅Ρ‚ΡŒ, сколько запросов выполняСтся для ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠΈ страницы.
  • ΠŸΡ€ΠΈΠΌΠ΅Π½ΠΈΡ‚Π΅ ΠΌΠ΅Ρ‚ΠΎΠ΄ .query ΠΊ QuerySet, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΏΠΎΡΠΌΠΎΡ‚Ρ€Π΅Ρ‚ΡŒ сгСнСрированный SQL.
  • ΠŸΡ€ΠΎΠ²Π΅Ρ€ΡŒΡ‚Π΅ ΠΏΠ»Π°Π½ выполнСния запросов с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ EXPLAIN Π² вашСй Π±Π°Π·Π΅ Π΄Π°Π½Π½Ρ‹Ρ…, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΡƒΠ±Π΅Π΄ΠΈΡ‚ΡŒΡΡ, Ρ‡Ρ‚ΠΎ индСксы ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡŽΡ‚ΡΡ эффСктивно.

2. Π’Π½Π΅Π΄Ρ€Π΅Π½ΠΈΠ΅ ΠΊΠ΅ΡˆΠΈΡ€ΠΎΠ²Π°Π½ΠΈΡ

Если ваши Π΄Π°Π½Π½Ρ‹Π΅ Ρ€Π΅Π΄ΠΊΠΎ ΠΌΠ΅Π½ΡΡŽΡ‚ΡΡ, Π½ΠΎ Π°ΠΊΡ‚ΠΈΠ²Π½ΠΎ Π·Π°ΠΏΡ€Π°ΡˆΠΈΠ²Π°ΡŽΡ‚ΡΡ, ΠΊΠ΅ΡˆΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅ ΠΌΠΎΠΆΠ΅Ρ‚ Π·Π½Π°Ρ‡ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎ ΡΠ½ΠΈΠ·ΠΈΡ‚ΡŒ Π·Π°Π΄Π΅Ρ€ΠΆΠΊΠΈ. Π’ Django Π΅ΡΡ‚ΡŒ нСсколько ΡƒΡ€ΠΎΠ²Π½Π΅ΠΉ ΠΊΠ΅ΡˆΠΈΡ€ΠΎΠ²Π°Π½ΠΈΡ:

ΠšΠ΅ΡˆΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅ Π½Π° ΡƒΡ€ΠΎΠ²Π½Π΅ прСдставлСний

Π­Ρ‚ΠΎ самый простой способ ΠΊΠ΅ΡˆΠΈΡ€ΠΎΠ²Π°Π½ΠΈΡ. Π’Ρ‹ ΠΌΠΎΠΆΠ΅Ρ‚Π΅ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ Π΄Π΅ΠΊΠΎΡ€Π°Ρ‚ΠΎΡ€ @cache_page, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΊΠ΅ΡˆΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ вСсь Π²Ρ‹Π²ΠΎΠ΄ прСдставлСния:


from django.views.decorators.cache import cache_page

@cache_page(60 * 15)  # ΠšΠ΅ΡˆΠΈΡ€ΡƒΠ΅ΠΌ Π½Π° 15 ΠΌΠΈΠ½ΡƒΡ‚
def my_view(request):
    # ...

Однако этот ΠΌΠ΅Ρ‚ΠΎΠ΄ ΠΏΠΎΠ΄Ρ…ΠΎΠ΄ΠΈΡ‚ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ для прСдставлСний, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ Π½Π΅ зависят ΠΎΡ‚ состояния ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»Ρ, Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, для ΠΏΡƒΠ±Π»ΠΈΡ‡Π½Ρ‹Ρ… страниц.

ΠšΠ΅ΡˆΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅ Π½Π° ΡƒΡ€ΠΎΠ²Π½Π΅ Π΄Π°Π½Π½Ρ‹Ρ…

Для Π±ΠΎΠ»Π΅Π΅ Ρ‚ΠΎΠ½ΠΊΠΎΠ³ΠΎ контроля ΠΌΠΎΠΆΠ½ΠΎ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ django.core.cache для ΠΊΠ΅ΡˆΠΈΡ€ΠΎΠ²Π°Π½ΠΈΡ ΠΎΡ‚Π΄Π΅Π»ΡŒΠ½Ρ‹Ρ… ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ΠΎΠ² ΠΈΠ»ΠΈ Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚ΠΎΠ² вычислСний:


from django.core.cache import cache

def get_expensive_data(param):
    cache_key = f"expensive_data_{param}"
    data = cache.get(cache_key)
    if not data:
        data = calculate_expensive_data(param)
        cache.set(cache_key, data, 60 * 15)  # ΠšΠ΅ΡˆΠΈΡ€ΡƒΠ΅ΠΌ Π½Π° 15 ΠΌΠΈΠ½ΡƒΡ‚
    return data

ΠŸΡ€ΠΈ использовании ΠΊΠ΅ΡˆΠΈΡ€ΠΎΠ²Π°Π½ΠΈΡ Π²Π°ΠΆΠ½ΠΎ ΡƒΡ‡ΠΈΡ‚Ρ‹Π²Π°Ρ‚ΡŒ ΡΡ‚Ρ€Π°Ρ‚Π΅Π³ΠΈΡŽ ΠΈΠ½Π²Π°Π»ΠΈΠ΄Π°Ρ†ΠΈΠΈ кСша, Ρ‡Ρ‚ΠΎΠ±Ρ‹ Π΄Π°Π½Π½Ρ‹Π΅ ΠΎΡΡ‚Π°Π²Π°Π»ΠΈΡΡŒ Π°ΠΊΡ‚ΡƒΠ°Π»ΡŒΠ½Ρ‹ΠΌΠΈ. НапримСр, ΠΌΠΎΠΆΠ½ΠΎ ΠΎΡ‡ΠΈΡ‰Π°Ρ‚ΡŒ кСш ΠΏΡ€ΠΈ ΠΈΠ·ΠΌΠ΅Π½Π΅Π½ΠΈΠΈ связанных ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ΠΎΠ² ΠΈΠ»ΠΈ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ ΠΊΠΎΡ€ΠΎΡ‚ΠΊΠΈΠ΅ Π²Ρ€Π΅ΠΌΠ΅Π½Π° ΠΆΠΈΠ·Π½ΠΈ (TTL).

ΠšΠ΅ΡˆΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅ Π½Π° ΡƒΡ€ΠΎΠ²Π½Π΅ Π±Π°Π·Ρ‹ Π΄Π°Π½Π½Ρ‹Ρ…

НСкоторыС Π±Π°Π·Ρ‹ Π΄Π°Π½Π½Ρ‹Ρ…, Ρ‚Π°ΠΊΠΈΠ΅ ΠΊΠ°ΠΊ PostgreSQL, ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΈΠ²Π°ΡŽΡ‚ собствСнныС ΠΌΠ΅Ρ…Π°Π½ΠΈΠ·ΠΌΡ‹ ΠΊΠ΅ΡˆΠΈΡ€ΠΎΠ²Π°Π½ΠΈΡ. НапримСр, Π²Ρ‹ ΠΌΠΎΠΆΠ΅Ρ‚Π΅ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ pg_stat_statements для Π°Π½Π°Π»ΠΈΠ·Π° часто выполняСмых запросов ΠΈ настройки индСксов ΠΈΠ»ΠΈ ΠΌΠ°Ρ‚Π΅Ρ€ΠΈΠ°Π»ΠΈΠ·ΠΎΠ²Π°Π½Π½Ρ‹Ρ… прСдставлСний для ускорСния ΠΈΡ… выполнСния.

Как ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΈΡ‚ΡŒ

  • Π˜ΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠΉΡ‚Π΅ инструмСнты ΠΌΠΎΠ½ΠΈΡ‚ΠΎΡ€ΠΈΠ½Π³Π° кСша, Ρ‚Π°ΠΊΠΈΠ΅ ΠΊΠ°ΠΊ django-debug-toolbar, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΡƒΠ±Π΅Π΄ΠΈΡ‚ΡŒΡΡ, Ρ‡Ρ‚ΠΎ кСш Π΄Π΅ΠΉΡΡ‚Π²ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ΡΡ.
  • ΠŸΡ€ΠΎΠ²Π΅Ρ€ΡΠΉΡ‚Π΅ ΠΌΠ΅Ρ‚Ρ€ΠΈΠΊΠΈ кСш-Ρ…ΠΈΡ‚ΠΎΠ² ΠΈ ΠΏΡ€ΠΎΠΌΠ°Ρ…ΠΎΠ² (cache hits/misses), Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΎΡ†Π΅Π½ΠΈΡ‚ΡŒ ΡΡ„Ρ„Π΅ΠΊΡ‚ΠΈΠ²Π½ΠΎΡΡ‚ΡŒ ΠΊΠ΅ΡˆΠΈΡ€ΠΎΠ²Π°Π½ΠΈΡ.
  • ВСстируйтС ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ ΠΏΠΎΠ΄ Π½Π°Π³Ρ€ΡƒΠ·ΠΊΠΎΠΉ с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ инструмСнтов Π²Ρ€ΠΎΠ΄Π΅ locust ΠΈΠ»ΠΈ wrk, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΡƒΠ²ΠΈΠ΄Π΅Ρ‚ΡŒ, ΠΊΠ°ΠΊ ΠΊΠ΅ΡˆΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅ влияСт Π½Π° ΠΏΡ€ΠΎΠΈΠ·Π²ΠΎΠ΄ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎΡΡ‚ΡŒ.

3. Вынос тяТСлых Π·Π°Π΄Π°Ρ‡ Π² ΠΎΡ‡Π΅Ρ€Π΅Π΄ΠΈ

Если вашС ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ выполняСт рСсурсоСмкиС ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΈ, Ρ‚Π°ΠΊΠΈΠ΅ ΠΊΠ°ΠΊ ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠ° ΠΈΠ·ΠΎΠ±Ρ€Π°ΠΆΠ΅Π½ΠΈΠΉ, ΠΎΡ‚ΠΏΡ€Π°Π²ΠΊΠ° писСм ΠΈΠ»ΠΈ гСнСрация ΠΎΡ‚Ρ‡Π΅Ρ‚ΠΎΠ², это ΠΌΠΎΠΆΠ΅Ρ‚ Π·Π°Π½ΠΈΠΌΠ°Ρ‚ΡŒ Π·Π½Π°Ρ‡ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎΠ΅ врСмя ΠΈ Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΡƒ Π΄Ρ€ΡƒΠ³ΠΈΡ… запросов. РСшСниСм ΠΌΠΎΠΆΠ΅Ρ‚ Π±Ρ‹Ρ‚ΡŒ использованиС ΠΎΡ‡Π΅Ρ€Π΅Π΄Π΅ΠΉ Π·Π°Π΄Π°Ρ‡.

ΠŸΡ€ΠΈΠΌΠ΅Ρ€ с Celery

Π’ экосистСмС Django популярным Π²Ρ‹Π±ΠΎΡ€ΠΎΠΌ для Ρ€Π°Π±ΠΎΡ‚Ρ‹ с очСрСдями Π·Π°Π΄Π°Ρ‡ являСтся Celery. Π’ΠΎΡ‚ ΠΏΡ€ΠΈΠΌΠ΅Ρ€ использования:


from celery import shared_task

@shared_task
def send_email_task(email_address, subject, message):
    # Π›ΠΎΠ³ΠΈΠΊΠ° ΠΎΡ‚ΠΏΡ€Π°Π²ΠΊΠΈ письма
    pass

# Π’Ρ‹Π·ΠΎΠ² Π·Π°Π΄Π°Ρ‡ΠΈ
send_email_task.delay('user@example.com', 'Π’Π΅ΠΌΠ°', 'Π‘ΠΎΠΎΠ±Ρ‰Π΅Π½ΠΈΠ΅')

Π’ этом ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π΅ Π·Π°Π΄Π°Ρ‡Π° send_email_task Π±ΡƒΠ΄Π΅Ρ‚ Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½Π° Π² Ρ„ΠΎΠ½ΠΎΠ²ΠΎΠΌ Ρ€Π΅ΠΆΠΈΠΌΠ΅, Π½Π΅ блокируя основной ΠΏΠΎΡ‚ΠΎΠΊ прилоТСния.

Π’Ρ‹Π±ΠΎΡ€ Π±Ρ€ΠΎΠΊΠ΅Ρ€Π° Π·Π°Π΄Π°Ρ‡

Celery ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΈΠ²Π°Π΅Ρ‚ Ρ€Π°Π·Π»ΠΈΡ‡Π½Ρ‹Π΅ Π±Ρ€ΠΎΠΊΠ΅Ρ€Ρ‹ Π·Π°Π΄Π°Ρ‡, Ρ‚Π°ΠΊΠΈΠ΅ ΠΊΠ°ΠΊ Redis ΠΈΠ»ΠΈ RabbitMQ. Для Π±ΠΎΠ»ΡŒΡˆΠΈΠ½ΡΡ‚Π²Π° ΠΏΡ€ΠΎΠ΅ΠΊΡ‚ΠΎΠ² Redis являСтся Ρ…ΠΎΡ€ΠΎΡˆΠΈΠΌ Π²Ρ‹Π±ΠΎΡ€ΠΎΠΌ благодаря простотС настройки ΠΈ высокой ΠΏΡ€ΠΎΠΈΠ·Π²ΠΎΠ΄ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎΡΡ‚ΠΈ.

Как ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΈΡ‚ΡŒ

  • Π£Π±Π΅Π΄ΠΈΡ‚Π΅ΡΡŒ, Ρ‡Ρ‚ΠΎ Π·Π°Π΄Π°Ρ‡ΠΈ Π΄Π΅ΠΉΡΡ‚Π²ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎ Π²Ρ‹ΠΏΠΎΠ»Π½ΡΡŽΡ‚ΡΡ Π² ΠΎΡ‡Π΅Ρ€Π΅Π΄ΠΈ, Π° Π½Π΅ Π² основном ΠΏΠΎΡ‚ΠΎΠΊΠ΅ прилоТСния.
  • Π˜ΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠΉΡ‚Π΅ инструмСнты ΠΌΠΎΠ½ΠΈΡ‚ΠΎΡ€ΠΈΠ½Π³Π°, Ρ‚Π°ΠΊΠΈΠ΅ ΠΊΠ°ΠΊ Flower, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΎΡ‚ΡΠ»Π΅ΠΆΠΈΠ²Π°Ρ‚ΡŒ состояниС ΠΎΡ‡Π΅Ρ€Π΅Π΄Π΅ΠΉ ΠΈ Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½ΠΈΠ΅ Π·Π°Π΄Π°Ρ‡.
  • ΠŸΡ€ΠΎΠ²Π΅Ρ€ΡΠΉΡ‚Π΅ ΠΌΠ΅Ρ‚Ρ€ΠΈΠΊΠΈ Π·Π°Π΄Π΅Ρ€ΠΆΠ΅ΠΊ выполнСния Π·Π°Π΄Π°Ρ‡, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΡƒΠ±Π΅Π΄ΠΈΡ‚ΡŒΡΡ, Ρ‡Ρ‚ΠΎ ΠΎΠ½ΠΈ Π½Π΅ становятся ΡƒΠ·ΠΊΠΈΠΌ мСстом.

Π—Π°ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅

Π‘Π½ΠΈΠΆΠ΅Π½ΠΈΠ΅ p95 latency Ρ‚Ρ€Π΅Π±ΡƒΠ΅Ρ‚ систСмного ΠΏΠΎΠ΄Ρ…ΠΎΠ΄Π°: устранСния N+1 запросов, внСдрСния эффСктивного ΠΊΠ΅ΡˆΠΈΡ€ΠΎΠ²Π°Π½ΠΈΡ ΠΈ пСрСноса тяТСлых Π·Π°Π΄Π°Ρ‡ Π² Ρ„ΠΎΠ½ΠΎΠ²Ρ‹Π΅ процСссы. Π­Ρ‚ΠΈ шаги ΠΏΠΎΠΌΠΎΠ³ΡƒΡ‚ ΡƒΠ»ΡƒΡ‡ΡˆΠΈΡ‚ΡŒ ΠΏΡ€ΠΎΠΈΠ·Π²ΠΎΠ΄ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎΡΡ‚ΡŒ вашСго Django-прилоТСния ΠΈ ΠΎΠ±Π΅ΡΠΏΠ΅Ρ‡ΠΈΡ‚ΡŒ Π±ΠΎΠ»Π΅Π΅ быстрый ΠΎΡ‚ΠΊΠ»ΠΈΠΊ для ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»Π΅ΠΉ.

Если Π²Π°ΠΌ Π½ΡƒΠΆΠ½Π° ΠΏΠΎΠΌΠΎΡ‰ΡŒ Π² ΠΎΠΏΡ‚ΠΈΠΌΠΈΠ·Π°Ρ†ΠΈΠΈ вашСго Django-прилоТСния, Π·Π°ΠΏΠΈΡˆΠΈΡ‚Π΅ΡΡŒ Π½Π° ΠΊΠΎΠ½ΡΡƒΠ»ΡŒΡ‚Π°Ρ†ΠΈΡŽ, ΠΈ я ΠΏΠΎΠΌΠΎΠ³Ρƒ Π²Π°ΠΌ Π½Π°ΠΉΡ‚ΠΈ ΠΈ ΡƒΡΡ‚Ρ€Π°Π½ΠΈΡ‚ΡŒ ΡƒΠ·ΠΊΠΈΠ΅ мСста.