Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

JS Fest 2018. Максим Климишин. Распределенные данные: CRDT-структуры данных в JS

67 views

Published on

Почему распределенные данные это сложно и как начать использовать последние разработки в поддержании консистентности данных в браузерах и мобильных клиентах, используя JS.

Published in: Education
  • Be the first to comment

  • Be the first to like this

JS Fest 2018. Максим Климишин. Распределенные данные: CRDT-структуры данных в JS

  1. 1. Распределенные данные: CRDT-структуры данных в JavaScript Максим Климишин Head of Software Architecture at Takeoff Technologies  / 43
  2. 2. Работа Head of Software Architecture, Takeoff Technologies, 207 CTO @ ZAKAZ.UA and CartFresh, 202 Team Lead @ oDesk (now Upwork), 200 Project Coordinator @ 42 Coffee Cups, 2009 2 / 43
  3. 3. Сообщество соорганизатор PapersWeLove Kyiv соорганизатор PyCon Ukraine сооснователь KyivJS сооснователь LvivJS соорганизатор PiterPy соорганизатор Hotcode судья UA Web Challenge 3 / 43
  4. 4. Takeoff Technologies 4 / 43
  5. 5. Зачем? 5 / 43
  6. 6. Распределенная система Поддержка конкурентных операций на нескольких устройствах Офлайн-режим Long-running SAP (Facebook/Gmail/Soundcloud-типа) 6 / 43
  7. 7. Пример распределенной системы 7 / 43
  8. 8. Пример распределенной системы схема Client 1 Client 2 Client n message1 messagen messagen message1 message1 messagen messagen+1 Figure: Server is just a client 8 / 43
  9. 9. Три проблемы конкурентности divergence (расхождение): ∪n i=1o1 i ̸= ∪m j=1o2 j causality-violations (нарушение порядка): o1 → o3 intention-violations (нарушение намерений): o1||o2 9 / 43
  10. 10. CAP Theorem 0 / 43
  11. 11. DCS Triangle Decentralized - означает децентрализованость и server-free Consistent - консистентность означает что все ноды видять одни и те же данные в одно и то же время Scale - означает что у сети есть достаточно производительности, чтобы работать в масштабах планеты  / 43
  12. 12. DCS Triangle 2 / 43
  13. 13. Strong Consistency “strong consistency” все изменения применяются последовательно (т.е. sequential with no operations overlap) в глобальном порядке Узкое горлышко : маленькая пропускная способность и большие задержки (из-за консенсуса): RAFT/PAXOS/Zab можновы брать либо availability, либо partition-tolerance 3 / 43
  14. 14. Weak Consistency никаких гарантий после записи Read-Your-Writes hack 4 / 43
  15. 15. Eventual Consistency ∀i, j : f ∈ ci ⇒ f ∈ cj, Convergence and Termination properties RIAK, MONGO, Cassandra, Couch 5 / 43
  16. 16. Strong Eventual Consistency ... То же что и Eventual Consistency and ∀i, j : ci = cj ⇒ Si ≡ Sj: Correct replicas that have delivered the same updates have equivalent state CALM: consistency as logical monotonicity 6 / 43
  17. 17. Подходи сходу Локинг Один активный участник Транзакции Tentative Транзакции Версионирование/тэггирование Выполнение в обратном порядке (reversible execution) 7 / 43
  18. 18. Conflict-Free Replicated Data Types OR CRDT 8 / 43
  19. 19. Системные уровни Надежный способ доставки сообщений (reliable multicast) Схождение состояния или консистентность 9 / 43
  20. 20. Ограничения сети Задержки Потери TCP пакетов или сообщений Нарушение порядка доставки сообщений Дубликаты Head-of-Line blocking 20 / 43
  21. 21. Решения доставки Event Stream (Pull) WebSTOMP/MQTT Aeron (Websocket) 2 / 43
  22. 22. Conflict-free replicated data types (CRDT) – типы данных без конфликтов Свойства полурешентки (⊔ or LUB – Least Upper Bound, наименьшая верхняя грань): коммутативность – ∀x, y : x y = y ⊔ x ассоциативность – x ⊔ (y ⊔ z) = (x ⊔ y) ⊔ z идемпотентность – x ⊔ x = x 22 / 43
  23. 23. Strong Eventual Consistency C = [c1, ..., cn], ∀i, j : ci = cj ⇒ si ≡ sj 23 / 43
  24. 24. Counter 1 + 1 24 / 43
  25. 25. + not idempotent 1 + 1 ̸= 1 25 / 43
  26. 26. ∪ – sets are good 1 ∪ 1 = 1 26 / 43
  27. 27. Other properties of sets (1 ∪ 2) ∪ 3 = 1 ∪ (2 ∪ 3) 1 ∪ 2 = 2 ∪ 1 27 / 43
  28. 28. CRDT: пример свойств messages = [ { tag: 1, site: '1', payload: { key: 'val' } }, { tag: 1, site: '1', payload: { key: 'val' } }, { tag: 1, site: '2', payload: { key1: 'val1' } }, { tag: 2, site: '1', payload: { key2: 'val2' } }, { tag: 0, site: '2', payload: { key0: 'val0' } } ] // idempotency, messages.reduce( (v, c) => v.filter( m => m.tag == c.tag && m.site == c.site ).length == 0 ? v.concat([c]) : v, []); // partial order messages.sort(/* ...tag, site... */) 28 / 43
  29. 29. CRDT в DCS Triangle 29 / 43
  30. 30. CRDT Transport ci CRDT State (con- vergent) Conflict Resolution Semantics Application access API Si 30 / 43
  31. 31. CRDT: Replication strategies pubsub + periodic full state update (STOMP etc.) Server Sent Events (SSE) in, Websockets out 3 / 43
  32. 32. CRDT: GCounter export class GCounter { constructor(counters) { this.counters = counters; } increment(id) { return new GCounter(Object.assign({ [id]: (this.counters[id] || 0) + 1}))} query() { return Object.values(this.counters) .reduce((a, b) => a + b, 0); } merge(counter) { let sites = Object.keys(counter.counters) .concat(Object.keys(this.counters)); return new GCounter(sites.reduce( (merged, site) => Object.assign( merged, {[site]: Math.max( merged[site] || 0, counter.counters[site] || 0)}), this.counters)); } } 32 / 43
  33. 33. CRDT: GCounter payload let counters = { 1: 0 2: 0 ... N: 0} 33 / 43
  34. 34. CRDT: PNCounter class PNCounter { constructor(p, n) { this.n = n; this.p = p} increment() { return new PNCounter(this.p.increment(), this.n); } decrement() { return new PNCounter(this.p, this.n.increment()); } query() { return this.p.query() - this.n.query(); } merge(pncounter) { return new PNCounter( this.p.merge(pncounter.p), this.n.merge(pncounter.n)); } } 34 / 43
  35. 35. CRDT: MVRegister export class MVRegister { constructor(id, register) { this.id = id; this.register = register; set(value) { return new MVRegister( this.id, Object.assign(this.register, {[this.id]: value}))} query() {return Object.values(this.register); } merge(register) { let state = this.register[this.id] === undefined ? {} : {[this.id]: this.register[this.id]}; return new MVRegister(this.id, Object.assign(register.register, state)) } } 35 / 43
  36. 36. CRDT: MVRegister Figure S1 S2 S3 set(“v”) “v” set(“v3”) “v”, “v3” Figure: MVRegister Concurrent Operation 36 / 43
  37. 37. JSON CRDT Replica p: Replica q: {“key”: “A”} {“key”: “A”} {“key”: “B”} {“key”: “C”} {“key”: {“B”, “C”}} {“key”: {“B”, “C”}} network communication doc.get(“key”) := “B”; doc.get(“key”) := “C”; Figure: Конкуретные присвоения в регистре по ключу doc.get(“key”) репликами p и q. 37 / 43
  38. 38. JSON CRDT {} {“a”: {}} {“a”: {“x”: “y”}} {mapT(“a”): {“x”: “y”}, listT(“a”): [“z”]} {} {“a”: []} {“a”: [“z”]} {mapT(“a”): {“x”: “y”}, listT(“a”): [“z”]} network communication doc.get(“a”) := {}; doc.get(“a”).get(“x”) := “y”; doc.get(“a”) := []; ...idx(0).insertAfter(“z”); Figure: Конкуретное присвоение значений разного типа одному JSON ключу 38 / 43
  39. 39. CRDT: Типы Register: LWW или Multi-Value (как Dynamo или Couchdb) Counter только растущий G-Set – множество с возможностю исключительно добавления 2P-Set – множество, где один уникальный элемент можно удалять только один раз (G-Set + Tombstones set) LWW-Element-Set – LWW на базе vector clocks OR-Set – тэгированные элементы, тэги помещаются в множество Tombstones WOOT, LOGOOT, Treedoc, RGA, LSEQ для упорядоченных списков 39 / 43
  40. 40. Инструменты Roshi by Soundcloud Riak 2.0: Counters, Flags, Sets, Registers, Maps Redis Labs CRDT Y-js – framework for offline-first p2p shared editing on structured data Swarm (and forever-in-pre-alpha tool) replikativ.io – p2p distributed system framework GUN framework: p2p distributed framework 40 / 43
  41. 41. Свой CRDT тип + Относительно мало кода + Хорошо расширяется + Работает очень предсказуемо в рамках своей модели + Консистентно даже при плохой сети (с задержкой) + Работа оффлайн - Распределенная модель тяжело заходит - Сложно заниматься GC - Дополнительный гемор в оптимизации (δ-mutation) 4 / 43
  42. 42. Кто использует CRDT? Facebook TomTom League of Legends SoundCloud Bet265 RIAK Distributed Database 42 / 43
  43. 43. Thanks @maxmaxmaxmax 43 / 43

×