Jump to content

Вікідані/Примітки/Поширення змін

From Meta, a Wikimedia project coordination wiki
This page is a translated version of the page Wikidata/Notes/Change propagation and the translation is 100% complete.

Цей документ є чернеткою і його не слід сприймати як остаточну архітектуру.

Цей документ описує, як Вікібаза поширює зміни в репозиторії до будь-якої клієнтської вікі.

Загальний огляд

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

Припущення та термінологія

Дані, що обробляються репозиторієм Wikibase, структуровані в деякі сутності. Кожна сутність виглядає як окрема вікісторінка зі структурованими даними. Є кілька типів сутностей, але один з них особливо важливий у цьому контексті: це елементи. Елементи особливі тим, що вони пов'язані зі сторінками статей у кожній клієнтській вікі (напр., у кожній Вікіпедії). Для детальнішої інформації, див. Первісна модель даних.

Механізм поширення ґрунтується на припущенні, що кожен елемент даних у репозиторії Вікіданих має щонайбільше одне посилання до кожної клієнтської вікі, і що лише один елемент у репозиторії може посилатися на конкретну сторінку в конкретній клієнтській вікі. Таким чином, будь-яка сторінка будь-якої клієнтської вікі може бути поєднана щонайбільше з одним елементом даних у репозиторії.

(Див. коментар на сторінці обговорення щодо наслідків обмеження просування змін для випадків, коли сторінка Вікіпедії та елемент Вікіданих мають зв'язок 1:1)

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

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

Підтимка сторонніх клієнтів, тобто клієнтських вікі та інших користувачів крім Вікімедії, наразі несуттєва й не розроблятиметься. Однак, її слід мати на увазі, ухвалюючи дизайнерські рішення.

Ведення журналів змін

Кожна зміна, що робиться в репозиторії, записується до таблиці ("таблиці змін", а саме wb_changes) у базі даних репозиторію. Таблиця змін поводиться подібно до таблиці нових редагувань MediaWiki, у тому сенсі, що вона містить зміни за певних час (напр., за день чи тиждень), а старіші записи періодично вилучаються. Проте, на відміну від таблиці нових редагувань, wb_changes містить інформацію, необхідну для звітування та повторення змін у клієнтській вікі: окрім інформації про те, коли й ким зроблено зміну, вона містить також структурні відмінності від попередньої версієї сутності.

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

Надсилання змін

Зміни у репозиторії (напр. wikidata.org) надсилаються до клієнтських вікі (напр. Вікіпедій) з допомогою диспетчерського скрипта. Цей скрипт запитує таблицю wb_changes щодо змін, і надсилає їх до клієнтських вікі через дописування відповідних завдань у список завдань клієнта.

Скрипт диспетчера розроблено таким чином, що дозволяє будь-якій кількості екземплярів запускатися та розподіляти навантаження без попереднього знання один про одного. Вони координуються через базу даних репозиторію за допомогою таблиці wb_changes_dispatch:‎

  • chd_client: назва бази даних клієнта (основний ключ).
  • chd_latest_change: ID останньої зміни, яка була надіслана до клієнта.
  • chd_touched: часова мітка, яка показує, коли зміни було надіслано до клієнта.
  • chd_lock_name: назва глобального блокування, використаного диспетчером, що зараз оновлює цього клієнта (або NULL).

Диспетчер працює, роблячи такі кроки:

  1. Блокування та ініціалізація
    1. Виберіть клієнта для оновлення зі списку відомих клієнтів.
    2. Запустіть транзакцію бази даних на головній базі даних репозиторію.
    3. Зчитайте рядок заданого клієнта з wb_changes_dispatch (якщо відсутній, припустимо, що chd_latest_change = 0).
    4. Якщо chd_lock_name не дорівнює null, викличте IS_FREE_LOCK(chd_lock_name) на головній базі даних клієнта.
    5. Якщо це повертає 0, інший диспетчер утримує блокування. Вийдіть (або спробуйте іншого клієнта).
    6. Виберіть ім'я блокування (dbname.wb_changes_dispatch.client або щось подібне) та використовуйте GET_LOCK(), щоб отримати це блокування на головній базі даних клієнта.
    7. Оновити рядок клієнта в wb_changes_dispatch новою назвою блокування в chd_lock_name.
    8. Зафіксувати транзакцію БД на головній базі даних репозиторію.‎
  2. Виконати відправку
    1. Отримати n змін з ідентифікаторами > chd_latest_change з wb_changes у базі даних репозиторію. n – це налаштований розмір пакета.
    2. Фільтрувати зміни для тих, що стосуються цієї вікі клієнта (необов'язково, і може виявитися складним у складних випадках, наприклад, кешованих запитах).
    3. Надсилати відповідні завдання сповіщення про зміни до черги завдань вікі клієнта.‎
  3. Зареєструвати та розблокувати
    1. Запустити транзакцію БД на головній базі даних репозиторію.
    2. Оновити рядок клієнта в wb_changes_dispatch з chd_lock_name=NULL та оновити chd_latest_change та chd_touched.
    3. Викликати RELEASE_LOCK(), щоб зняти глобальне блокування, яке ми утримували.
    4. Зафіксувати транзакцію БД у головній базі даних репозиторію.‎

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

Завдання сповіщень про зміни

Диспетчер публікує завдання сповіщень про зміни до черги завдань вікі клієнта. Ці завдання містять список змін вікіданих. Під час обробки такого завдання вікі клієнта виконує такі кроки:‎

  1. Якщо клієнт підтримує локальний кеш даних сутності, оновити його.
  2. Знайти, які сторінки потрібно повторно відобразити після зміни. Визнати їх недійсними та очистити з веб-кешів. За бажанням, запланувати завдання повторного відображення (або оновлення посилань) або навіть безпосередньо повторно відобразити сторінку.
  3. Знайти, які сторінки мають зміни, які не потребують повторного відображення вмісту, але впливають на вивід сторінки, і тому потребують очищення веб-кешу (це може бути випадком змін мовних посилань).
  4. Вставити сповіщення про відповідні зміни в таблицю recentchanges клієнта. Для цього послідовні редагування одним і тим самим користувачем одного й того ж елемента можуть бути об'єднані.
  5. Можливо, також вставити "нульовий запис" в історію відповідних сторінок, тобто таблицю редагувань.‎
(Див. коментар на сторінці обговорення щодо нових редагувань versus таблиця історії)

Об'єднання подій

Описана вище система означає кілька записів у базу даних для кожної зміни - і потенційно багато читань, залежно від того, що потрібно для відображення сторінки. І це відбувається на кожній клієнтській вікі (можливо, сотнях) для кожної зміни в репозиторії. Оскільки редагування в репозиторії Wikibase, як правило, дуже дрібнозернисте (наприклад, встановлення мітки або додавання посилання на сайт), це може швидко стати проблематичним. Об’єднання оновлень може допомогти вирішити цю проблему:‎

Як пояснено в розділі Відправлення, записи в стрічці змін обробляються пакетами (за замовчуванням не більше 100 записів одночасно).‎

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