Багато невеликих запитів порівняно з декількома великими запитами (API Design)


49

В даний час я працюю над проектом в організації таким чином:

  • Клієнт - отримує дані з основного сервера через REST api.
  • Сервер - запитує дані з різних інших серверів через сторонні API
  • Сторонні API - сервіси, які не знаходяться під моїм контролем, які надають дані серверу (Reddit, Hackernews, Quora тощо)

Для аргументації скажімо, що спочатку клієнту потрібен перелік елементів із кожного стороннього API. З цього списку буде обраний пункт, в який момент клієнту необхідно побачити повний вміст продукту, а також відповіді (тобто коментарі) до елемента. Я намагаюся вирішити між трьома варіантами:

Ля карт

У такому підході у мене на сервері були б три окремі кінцеві точки: одна для отримання списку елементів, одна для отримання основного вмісту для елемента та одна для отримання відповідей на елемент.

  • Плюси: я ніколи не надсилаю більше запитів, ніж потрібно, запитів має бути мало, тому вони, як правило, повинні бути швидшими.
  • Мінуси: я повинен зробити багато запитів. Вибравши елемент зі списку, користувачеві, можливо, доведеться почекати, перш ніж побачити основний вміст, а потім ще довше чекати, щоб побачити відповіді.

Кеш-сервер на стороні сервера

У цьому запиті я б здійснив єдиний дзвінок на свій сервер, щоб "отримати" всі дані для всіх джерел. Дані будуть кешовані на сервері. Тоді клієнт матиме ті ж кінцеві точки REST, що і раніше, за винятком того, що між дзвінками не чекатиме багато часу, оскільки мій сервер вже має дані і просто повинен його подати клієнту.

  • Плюси: все ще просто реалізувати на стороні клієнта, але без проблем із затримкою
  • Мінуси: трохи більше залученого боку сервера, і перший дзвінок може зайняти дійсно дуже довго.

Кеш на стороні клієнта

Цей сценарій схожий на попередній, за винятком того, що клієнт лише коли-небудь робить один запит на сервер: дайте мені всі дані. Звідси відповідальність за збереження даних та їх використання належить клієнту.

  • Плюси: проста реалізація сервера, дуже швидка після першого дзвінка
  • Мінуси: перший виклик буде дуже повільним, складнішим є реалізація на стороні клієнта

Я не впевнений, який найкращий підхід, чи, можливо, я пропускаю очевидне рішення. Будь-яка порада буде дуже вдячна!


Мені здається, це вибір між свіжістю та швидкістю. Що віддають перевагу ваші зацікавлені сторони та кінцеві користувачі?
Ерк

Відповіді:


27

Слід пам’ятати про очікувану затримку мережі (тобто час пінг) між вашими клієнтами та вашим сервером. У ситуації з високою затримкою з інакше хорошою пропускною здатністю багато невеликих запитів будуть виконуватись значно гірше, ніж один великий.

Нещодавно я співпрацював над проектом веб-додатків, що підтримується багато командами, в якому одна з команд знаходиться в Індії (решта - у США). У нас в офісі США розміщений єдиний екземпляр бази даних, до якого розробники підключають екземпляри нашого локального веб-сервера. Мій стіл знаходиться, можливо, на відстані п’ятдесяти футів і два локальних стрибки від екземпляра бази даних, і продуктивність чудова.

Коли ми вперше розпочали роботу з розробниками в Індії, вони зазнали величезних термінів очікування, запустивши програму та перейшовши на сторінку. Ми говоримо тут десять хвилин очікування. Виявляється, це було через те, що ~ 200 мс пінг часу від своїх столів до нашого сервера баз даних розробників отримували багато, багато коротких запитів до бази даних. Мій локальний пінг на 0,5 мс був настільки банальним, що чат між веб-сервером та сервером баз даних ніколи не мав значення. Це був перший раз, коли ми мали географічний поділ між веб-сервером та сервером баз даних.

Рішення в нашому випадку полягало в клонуванні сервера баз даних та витримці копії в Індії, але справа тут у тому, щоб пам’ятати, що якщо ваш клієнт і сервер далеко один від одного, затримка мережі буде помножена на кількість комунікацій через дріт. Пропускна здатність після встановлення з'єднання, як правило, значно менше турбує.


2

Ці три варіанти не є взаємовиключними, ви можете використовувати комбінацію кешів на стороні клієнта та сервера. Однак деякі дані, як-от коментарі, можуть стати несвіжими, якщо зберігати їх у кеші занадто довго. Зважаючи на те, що ви не можете перевірити, чи це так, вам, ймовірно, варто взагалі утриматися від його зберігання. З іншого боку, вміст зазвичай не змінюється кардинально, тому не було б шкоди кешувати його на стороні сервера, а потім попередньо встановлювати частину на стороні клієнта, щоб зменшити затримку.


1

На основі лише інформації, яку ви дали, варіант 1, тому що

  • за допомогою одного запиту клієнта ви змішуєте яблука та апельсини, і кошик з фруктами може бути дуже великим.

  • кешування - це компроміс, де ви отримуєте продуктивність, але потенційно втрачаєте послідовність (несвіжі дані). Якщо у вас немає виявлених проблем з продуктивністю, проблеми синхронізації, як правило, не варто ризикувати.


0

Я завжди знаходив кілька великих прохань бути більш ефективними та масштабованими. Але є компроміси у всіх підходах, тому це залежить від потреб сервера та клієнта. Ви можете скористатися іншим варіантом, який полягає у тому, щоб клієнт вказав цілий діапазон або набір даних для вилучення - це не обов'язково всі дані, але деякий діапазон, який налаштовується з часом, щоб відповідати наявної пропускної здатності.


0

Я б (майже) знижував варіант 3. Вибір між 1 і 2 залежить від двох речей:

  • (А) наскільки великий результат одного, загального результату
  • (B) скільки деталей результату зазвичай використовує клієнт / користувач у цьому сеансі.

Прийняти рішення легко, якщо A і B є крайнощами:

  • Якщо A великий, а B малий, обов'язково перейдіть до варіанту 1 (A la Carte).
  • Якщо A малий і B великий, перейдіть до 2 (кеш на стороні сервера) або навіть 3 (кеш на стороні клієнта).

Для будь-яких інших варіантів A / B (великих / малих) вам доведеться застосувати розсуд. Я часто надаю як грубі, так і тонкі кінцеві точки для задоволення різних випадків використання від різних клієнтів.


0

Як завжди в програмуванні, це залежить.

Отже, справжнє питання: що слід враховувати, приймаючи рішення про а / п / с або комбінацію трьох?

Я б сказав, що справжніми дискримінаційними факторами є деталі щодо впровадження сторонніх API, які ви використовуєте. Як приклад слід розглянути: швидкі вони чи повільні? Чи змінюються дані часто і несподівано? Вони "балакані" чи відпочивають?

У випадку швидкого, простого виклику служб, при цьому дані змінюються настільки часто, що кеш-пам'ять вашого сервера створюватиме проблеми з кеш-пам'яттю, будь-ласка, скористайтеся варіантом 1: більше запитів, без кешу, лише за потреби.

Якщо ваші зовнішні дані зміняться передбачуваним способом, або ви обмежені у використанні, або просто ви можете отримати кращий досвід користування кешуванням даних на вашому сервері, перейдіть з 2. Але майте на увазі, що кеш не вільний: це має витрати на налагодження, і іноді користувачі скаржаться, що не бачать оновлень.

Варіант 3, я б розглядав лише, якщо даних не багато, але в такому випадку навіть варіанти 1 або 2 можуть працювати, і ви зберігаєте більше логіки на сервері, тому я б дотримувався 1 або 2.

Просто мій 2с.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.