-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathindex.html
More file actions
506 lines (494 loc) · 25.1 KB
/
index.html
File metadata and controls
506 lines (494 loc) · 25.1 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="generator" content="pandoc">
<title>Dynamo: Amazon’s Highly Available Key-value Store</title>
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent">
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no, minimal-ui">
<link rel="stylesheet" href="./reveal.js/css/reset.css">
<link rel="stylesheet" href="./reveal.js/css/reveal.css">
<style>
code{white-space: pre-wrap;}
span.smallcaps{font-variant: small-caps;}
span.underline{text-decoration: underline;}
div.column{display: inline-block; vertical-align: top; width: 50%;}
div.hanging-indent{margin-left: 1.5em; text-indent: -1.5em;}
ul.task-list{list-style: none;}
</style>
<link rel="stylesheet" href="./reveal.js/css/theme/simple.css" id="theme">
<!-- Printing and PDF exports -->
<script>
var link = document.createElement( 'link' );
link.rel = 'stylesheet';
link.type = 'text/css';
link.href = window.location.search.match( /print-pdf/gi ) ? './reveal.js/css/print/pdf.css' : './reveal.js/css/print/paper.css';
document.getElementsByTagName( 'head' )[0].appendChild( link );
</script>
<!--[if lt IE 9]>
<script src="./reveal.js/lib/js/html5shiv.js"></script>
<![endif]-->
</head>
<body>
<div class="reveal">
<div class="slides">
<section id="title-slide">
<h1 class="title">Dynamo: Amazon’s Highly Available Key-value Store</h1>
<p class="author"><div class="line-block">del Mazo, Federico - 100029<br />
Mermet, I. Javier - 98153<br />
Ventura, Julián - 102391</div></p>
</section>
<section>
<section id="dynamo-amazons-highly-available-key-value-store" class="title-slide slide level1">
<h1>Dynamo: Amazon’s highly available key-value store</h1>
<p><img data-src="./img/dynamodb.png" /></p>
</section>
<section id="motivación" class="slide level2">
<h2>Motivación</h2>
<ul>
<li>Query model
<ul>
<li>Operaciones simples</li>
<li>Costos asociados a un RDBMS</li>
</ul></li>
<li>Propiedades <code>ACID</code>
<ul>
<li>Disponibilidad pobre</li>
</ul></li>
<li>Eficiencia</li>
<li>Otras asunciones
<ul>
<li>No-hostil</li>
</ul></li>
</ul>
<aside class="notes">
<p>Muchos servicios dentro de Amazon tienen ciertos requisitos para los cuales una DB relacional esta lejos de ser ideal. Por complejidad, costo de mantenimiento, decisiones de diseño.</p>
<p>Utilizan items unívocamente identificados por una clave, haciendo operaciones simples de lectura y escritura. Las operaciones se hacen sobre elementos individuales y no hay necesidad de un esquema relacional.</p>
<p>La experiencia en Amazon demuestra que los almacenamientos de datos que proveen garantías ACID tienden a proveer una disponibilidad pobre. Dynamo se enfoca en aplicaciones que operan con consistencia mas débil si esto resulta en una disponibilidad mas alta. No provee ninguna garantía de aislamiento.</p>
<p>El sistema se diseño en base a la necesidad de ser ejecutado sobre hardware commodity, con requisitos de latencia medidos en el percentil 99.9 de la distribución. Los servicios deben poder configurar Dynamo de modo tal que puedan alcanzar sus requisitos de latencia y throughput.</p>
<p>El entorno se asume como no-hostil y no hay requisitos de seguridad.</p>
</aside>
</section>
<section id="sla-y-problemas-de-negocio" class="slide level2">
<h2>SLA y Problemas de negocio</h2>
<ul>
<li>99.9th percentile</li>
<li>Lógica liviana
<ul>
<li>Rol importante de los Data Stores</li>
<li>Manejo del estado</li>
</ul></li>
<li>Control
<ul>
<li>Durabilidad</li>
<li>Consistencia</li>
</ul></li>
<li>Tradeoffs
<ul>
<li>Funcionalidad</li>
<li>Performance</li>
<li>Costo-beneficio</li>
</ul></li>
</ul>
<aside class="notes">
<p>En Amazon, los SLAs se expresan medidos sobre el percentil 99.9, basados en un análisis de costo beneficio.</p>
<p>La mayoría de los servicios de amazon tienen una lógica liviana, por tanto los sistemas de almacenamiento juegan un rol importante ene establecer su SLA. El componente principal de un sistema se vuelve el manejo del estado. Una de las consideraciones principales de Dynamo es permitir que los servicios tengan control sobre las propiedades del sistema, como durabilidad y consistencia, y dejar que decidan sobre los tradeoffs entre funcionalidad, performance y relación costo-beneficio.</p>
</aside>
</section>
<section id="consideraciones-de-diseño" class="slide level2">
<h2>Consideraciones de diseño</h2>
<ul>
<li>Data store eventualmente consistente</li>
<li>Resolución de conflictos
<ul>
<li>Aplicación</li>
<li>Data store</li>
</ul></li>
<li>Always writable</li>
</ul>
<aside class="notes">
<p>Dynamo esta diseñado para ser un data store eventualmente consistente: todas las actualizaciones llegan a todas las replicas eventualmente.</p>
<p>Una consideración importante es cuando realizar el proceso de resolución de conflictos de actualización. También el quien: el data store o la aplicación. El data store tiene opciones limitadas, se utiliza una sencilla como “gana la ultima escritura”. Las aplicaciones conocen mejor el esquema de datos.</p>
<p>Se orienta al espacio de diseño de un data store siempre disponible para escrituras.</p>
</aside>
</section>
<section id="principios-clave" class="slide level2">
<h2>Principios clave</h2>
<ul>
<li>Escalabilidad incremental</li>
<li>Simetría</li>
<li>Decentralización</li>
<li>Heterogeneidad</li>
</ul>
<aside class="notes">
<p>Otros principios de diseño:</p>
<ul>
<li>Escalabilidad incremental: Dynamo debe poder escalar de a un nodo, con mínimo impacto en operaciones tanto del sistema como de operadores del sistema.</li>
<li>Simetría: Todos los nodos de Dynamo deben tener el mismo conjunto de responsabilidades que sus pares. Esto simplifica el proceso de aprovisionamiento y mantenimiento.</li>
<li>Descentralización: es una extensión de la simetría, el diseño debe favorecer técnicas descentralizadas par-a-par por sobre un control centralizado.</li>
<li>Heterogeneidad: El sistema debe ser capaz de explotar la heterogeneidad de la infraestructura sobre la que corre.</li>
</ul>
</aside>
</section></section>
<section>
<section id="arquitectura-de-sistema" class="title-slide slide level1">
<h1>Arquitectura de Sistema</h1>
<p>“DynamoDB can be characterized as a zero-hop DHT, where each node routes a request to the appropiate node directly”</p>
<p><img src="./img/architecture.png" alt="architecture" width="450"/></p>
<aside class="notes">
<p>Inspiraciones:</p>
<ul>
<li>SistemasP2P</li>
<li>File systems distribuidos (ej: google file system)</li>
<li>Databases distribuidas (ej: bigtable)</li>
</ul>
<p>Tomar lo bueno, descartar lo malo, buscando cumplir:</p>
<ul>
<li>Always Writeable</li>
<li>All nodes are to be trusted</li>
<li>No complex relational schemas ni hierarchical namespaces</li>
<li>Latency sensitive: 99.9% read/write ops in a few hundred ms</li>
</ul>
</aside>
</section>
<section id="interfaz" class="slide level2">
<h2>Interfaz</h2>
<ul>
<li>Define dos simples funciones
<ul>
<li><code>get(key)</code> -> <code>(object, context)</code></li>
<li><code>put(key, context, object)</code> -> <code>()</code></li>
</ul></li>
</ul>
<aside class="notes">
<ul>
<li>La función get devuelve un contexto</li>
<li>El contexto
<ul>
<li>Es una serie de bytes</li>
<li>Es opaco al usuario</li>
<li>Contiene metadata de la bdd que ayuda a versionado.</li>
</ul></li>
<li>La función put necesita el contexto para determinar el objeto a retornar</li>
<li>Esto es así porque Dynamo almacena objetos inmutables con versionado.</li>
</ul>
</aside>
</section>
<section id="particionado" class="slide level2">
<h2>Particionado</h2>
<p>Distribuir los datos de forma uniforme entre los nodos</p>
<p><br />
</p>
<h4 id="solución-naive">Solución Naive</h4>
<ul>
<li>Función de hash: <code>H(k) = f(k) % n_nodos_sistema</code></li>
<li>Problema: Al modificar cantidad de nodos hay que recalcular todos los hashes!</li>
</ul>
<p><br />
</p>
<h4 id="solución-de-dynamo">Solución de Dynamo</h4>
<ul>
<li>Técnica de hashing consistente
<ul>
<li>Función de hash: <code>H(k) = f(k) % m</code>
<ul>
<li><code>m</code> >> <code>n_nodos_sistema</code></li>
</ul></li>
<li>Se ordenan los nodos en una topología de anillo, de forma aleatoria.</li>
<li>Cada nodo administra claves del rango previo</li>
</ul></li>
<li>Nodos virtuales o tokens</li>
</ul>
<aside class="notes">
<ul>
<li>Utilizar un mecanismo similar al de una tabla de hash, atada al número de nodos es poco eficiente.</li>
<li>Se usa hashing consistente
<ul>
<li>El valor de m debe elegirse tal que sea mucho mayor a la cantidad de nodos del sistema</li>
<li>El orden de los nodos en la versión inicial es aleatoria, permitiendo rangos de distinto tamaño.</li>
<li>Si no hay replicación cada nodo almacena únicamente los objetos de su rango previo</li>
</ul></li>
</ul>
</aside>
</section>
<section id="particionado-1" class="slide level2">
<h2>Particionado</h2>
<p><img src="./img/consistent-hashing-physical.png" alt="consistent-hashing-physical" width="600"/></p>
<aside class="notes">
<ul>
<li><p>El espacio de direcciones de la función de hash es de 0 a M</p></li>
<li><p>Se desea almacenar o leer de un objeto cuya clave K tiene valor de hash 27.</p></li>
<li><p>El objeto es responsabilidad del nodo B.</p></li>
<li><p>Si aparece un nodo X entre A y B, entonces B deberá cederle claves de su rango (Entre A y X)</p></li>
<li><p>Si el nodo B sale, entonces deberá cederle sus claves al nodo C</p></li>
<li><p>Optimización de tokens:</p>
<ul>
<li>Los nodos que se ven en la imagen pasan a ser virtuales (denominados tokens)</li>
<li>Cada nodo físico del sistema es multiplexado en varios nodos virtuales, se le asignan tokens.</li>
<li>La cantidad de tokens de un nodo depende de sus recursos</li>
<li>Esto mejora la distribución de carga en el sistema.</li>
</ul></li>
</ul>
</aside>
</section>
<section id="replicado" class="slide level2">
<h2>Replicado</h2>
<p><img data-src="./img/replication.png" /></p>
<ul>
<li><p>El coordinador replica a los <code>N</code>-1 siguientes nodos del anillo</p></li>
<li><p>Todos los nodos conocen las responsabilidades del resto</p></li>
<li><p>Los datos se distribuyen en nodos físicos, no virtuales</p></li>
</ul>
<aside class="notes">
<ul>
<li>El coordinador es el que esta a cargo del write (y guarda su copia ademas de replicar)</li>
<li>N es un parámetro configurable</li>
<li>La lista de nodos a cargo de guardar una key es la <em>preference list</em> (segundo item: todos los nodos pueden determinar la preference list de todas las keys)</li>
<li>Los N nodos sucesores pueden ser virtuales, por eso se implementa un sistema de skippear posiciones, asegurandose que los datos se distribuyan en nodos físicos</li>
</ul>
</aside>
</section>
<section id="versionado-de-datos" class="slide level2">
<h2>Versionado de datos</h2>
<p>Consistencia <em>eventual</em> -> Si opero <em>YA</em>, genero una inconsistencia entre nodos</p>
<p>Cómo hago un <em>merge</em> de las distintas versiones?</p>
<p><br />
</p>
<ul>
<li>Syntactic Reconciliation: Si una versión nueva supera la antigua, simplemente la reemplaza</li>
<li>Semantic Reconciliation: Si no hay manera obvia de elegir la versión superadora, el cliente decide qué hacer
<ul>
<li>Reglas de negocio -> <em>Shopping Cart</em></li>
<li>“Last Write Wins” -> <em>Session Info</em></li>
</ul></li>
</ul>
<aside class="notes">
<ul>
<li>Si no tengo fallas, la replicación esta acotada en tiempo</li>
<li>Si tengo fallas, los updates pueden tardar muucho en aparecer en todas las replicas</li>
<li>Es como git: No quiero perder datos nunca.
<ul>
<li>Syntactic Reconciliation -> FastForward</li>
<li>Semantic Reconciliation -> Merge a manopla</li>
</ul></li>
<li>El merge pasa a ser responsabilidad de la capa de aplicación -> todas las aplicaciones son conscientes de que pueden existir muchas versiones de la data</li>
<li>Add to Cart -> nunca quiero perder lo que un usuario agregó -> el merge es semántico por regla de negocio</li>
</ul>
</aside>
</section>
<section id="versionado-de-datos-1" class="slide level2">
<h2>Versionado de datos</h2>
<p>Una versión? Un Vector Clock!</p>
<p><code>(nodo, contador)</code></p>
<p><img data-src="./img/versioning.png" /></p>
<aside class="notes">
<ul>
<li>Cada versión es inmutable</li>
<li>Para evitar una lista enorme de vector clocks, el tercer elemento de la tupla es un timestamp que usas para truncar</li>
</ul>
</aside>
</section>
<section id="ejecución-de-operaciones" class="slide level2">
<h2>Ejecución de Operaciones</h2>
<h3 id="en-busca-del-coordinador">En Busca del Coordinador</h3>
<ul>
<li>Cualquier nodo puede recibir peticiones de usuario sobre cualquier clave.</li>
<li>Al momento de recibir una petición sobre una clave <code>k</code>, el nodo deberá:
<ul>
<li>Resolverla únicamente si pertenece a la preference list de dicha clave.</li>
<li>Caso contrario, deberá enrutar a algún nodo saludable de los primeros <code>N</code> de la lista de preferencia.</li>
</ul></li>
<li>La lista de preferencia se transmite de nodo a nodo a través de un protocolo de chisme.</li>
</ul>
<aside class="notes">
<ul>
<li>Cualquier nodo puede recibir peticiones de usuario sobre cualquier clave.</li>
<li>Al momento de recibir una petición sobre una clave k, el nodo deberá:
<ul>
<li>Resolverla únicamente si pertenece a la preference list de dicha clave.</li>
<li>Enrutar a algún nodo saludable de los primeros N de la lista de preferencia.</li>
</ul></li>
<li>Dicha información se transmite de nodo a nodo a través de un protocolo de chisme.</li>
</ul>
</aside>
</section>
<section id="ejecución-de-operaciones-1" class="slide level2">
<h2>Ejecución de Operaciones</h2>
<h3 id="resolviendo-la-consulta">Resolviendo la Consulta</h3>
<ul>
<li>Se busca lograr un balance entre performance, availability y durability, que sea configurable</li>
<li>Se logra a través de un <em>Sloppy Quorum</em>
<ul>
<li>Se configuran dos valores, <code>R</code> y <code>W</code>.</li>
<li>Ante una lectura, <code>R</code> nodos deberán responder antes de darla por finalizada.</li>
<li>Ante una escritura, <code>W</code> nodos deberán responder antes de darla por finalizada.</li>
</ul></li>
<li>Al recibir una petición, el coordinador:
<ul>
<li>Resolverá la petición localmente.</li>
<li>Enviará la petición a los primeros <code>N</code> nodos saludables de la preference list.</li>
<li>Esperará a la respuesta de <code>W</code>-1 o <code>R</code>-1 nodos, si se trata de una escritura o lectura.</li>
<li>Responderá al usuario.</li>
</ul></li>
<li>Al aumentar <code>W</code> se reduce performance y availability, pero mejora durability</li>
<li>Al aumentar <code>R</code> se reduce performance y availability, pero mejora consistency.</li>
<li>Estos valores se configuran en función de la aplicación y los SLAs</li>
</ul>
<aside class="notes">
<ul>
<li>Dynamo implementa un Sloppy Quorum para la resolución de peticiones de lectura y escritura.</li>
<li>El administrador de la bdd podrá configurar dos valores, R y W.</li>
<li>El nodo coordinador de la petición buscará ejecutarla de forma local y luego replicarla para los N nodos de la lista de preferencia</li>
<li>Si se trata de una lectura, el nodo coordinador no la dará por finalizada hasta que al menos R-1 nodos le contesten.</li>
<li>De forma similar, si se trata de una escritura, esta no culminará hasta que al menos W-1 nodos contesten.</li>
<li>Al realizar una lectura, se ejecutará el algoritmo Syntactic Reconciliation.</li>
<li>En ambos casos nos encontraremos limitados por la latencia del último nodo en responder, sea de los R-1 o W-1</li>
<li>Aumentar o disminuir estos valores implica un tradeoff.</li>
<li>Al aumentar W o R no solo se reduce la performance, sino que también puede reducirse la availability</li>
<li>Al disminuir W o R mejora la performance y availability, pero empeora la durability</li>
<li>Se juega con estos valores en función de la aplicación y los SLA.</li>
</ul>
</aside>
</section></section>
<section>
<section id="manejo-de-fallas-hinted-handoff" class="title-slide slide level1">
<h1>Manejo de fallas: Hinted Handoff</h1>
</section>
<section id="sloppy-quorum" class="slide level2">
<h2><em>Sloppy</em> Quorum</h2>
<aside class="notes">
<p>Si Dynamo usara un enfoque tradicional de quorum, no podría estar disponible durante fallas de servidores o particiones de red. Su durabilidad seria reducida incluso bajo las condiciones mas simples de fallo. Por ello no enfuerza membresía estricta de quorum, usa sloppy quorum: todas las operaciones de lectura y escritura se hacen en los primeros N nodos funcionales de la lista de preferencia. No necesariamente son los primeros N encontrados moviéndose por el anillo de hashing.</p>
</aside>
</section>
<section id="data-center-failure" class="slide level2">
<h2>Data center failure</h2>
<aside class="notes">
<p>Un sistema de almacenamiento altamente disponible tiene que ser capaz de manejar fallas de un data center entero. Dados cortes de electricidad, de enfriamiento, red o desastres naturales.</p>
</aside>
</section>
<section id="replication-across-multiple-data-centers" class="slide level2">
<h2>Replication across multiple data centers</h2>
<aside class="notes">
<p>La lista de preferencia de una clave se construye de modo tal que los nodos de almacenamiento se distribuyen en varios data centers conectados por enlaces de alta velocidad.</p>
</aside>
</section></section>
<section>
<section id="manejo-de-fallas-permanentes-sincronización-de-réplicas" class="title-slide slide level1">
<h1>Manejo de fallas permanentes: Sincronización de réplicas</h1>
</section>
<section id="fallas-momentáneas" class="slide level2">
<h2>Fallas momentáneas</h2>
<aside class="notes">
<p>Hinted handoff funciona mejor cuando el churn de membresía del sistema es bajo (es decir, se mantienen dentro del mismo) y las fallas de nodos son momentáneas.</p>
</aside>
</section>
<section id="protocolo-anti-entropía" class="slide level2">
<h2>Protocolo anti-entropía</h2>
<ul>
<li>Arboles Merkle
<ul>
<li>Detección de inconsistencias</li>
<li>Minimizar transferencia de datos</li>
<li>Nodos que dejan o se unen</li>
</ul></li>
</ul>
<aside class="notes">
<p>Dynamo implementa un protocolo anti entropía para mantener las replicas sincronizadas, utilizando arboles Merkle para detectar inconsistencias entre replicas mas rápidamente y minimizar la cantidad de data transferida. Cada nodo mantiene un árbol Merkle para cada rango de claves (el set de claves cubiertas por un nodo virtual) que almacena. Permitir que los nodos puedan comparar si las claves dentro de un rango esta actualizadas. Si no, recorren el árbol y y sincronizan adecuadamente. La desventada es que muchas claves cambian cuando un nodo se une o deja el sistema, requiriendo que los arboles se recalculen.</p>
</aside>
</section></section>
<section>
<section id="membresía-y-detección-de-fallas-pertenencia-al-anillo" class="title-slide slide level1">
<h1>Membresía y Detección de fallas: Pertenencia al anillo</h1>
</section>
<section id="mecanismo-explicito" class="slide level2">
<h2>Mecanismo explicito</h2>
<aside class="notes">
<p>Las fallas de nodos en Amazon suelen ser momentáneas (fallas o tareas de mantenimiento) y raramente significan una salida permanente. Por tanto, no amerita rebalancear la asignación de particiones o reparación de las replicas que no se pueden alcanzar.</p>
<p>Por esto, se utiliza un mecanismo explicito para inicia la adición y remoción de nodos de un anillo de Dynamo. UN administrador usa una CLI o el navegador para conectarse a un nodo de Dynamo y enviar un cambio de membresía para unirlo a un anillo o removerlo de un anillo.</p>
</aside>
</section>
<section id="gossip-based-protocol" class="slide level2">
<h2>Gossip based protocol</h2>
<aside class="notes">
<p>Un protocolo basado en rumores propaga los cambios de membresía y mantiene una vista eventualmente consistente de membresía. Cada nodo contacta un par elegido al azar cada segundo y los dos nodos reconcilian cambios persistidos de historial de cambios de membresía.</p>
</aside>
</section>
<section id="startup" class="slide level2">
<h2>Startup</h2>
<aside class="notes">
<p>Cuando un nodo arranca, elige su set de tokens (nodos virtuales en el espacio de hashing consistente) y hace un mapa de nodos a sus token sets. Los mapas de cada nodo se reconcilian durante el mismo intercambio que reconcilia historiales de cambios de membresía. Esto significa que la información de particionado y ubicación también se propagan con el protocolo basado en rumores y cada nodo de almacenamiento esta al tanto de los rangos de tokens que manejan sus pares. Esto permite que cada nodo pueda forwardear una operación de lectura/escritura al conjunto correcto de nodos directamente.</p>
</aside>
</section></section>
<section>
<section id="membresía-y-detección-de-fallas-descubrimiento-externo" class="title-slide slide level1">
<h1>Membresía y Detección de fallas: Descubrimiento externo</h1>
</section>
<section id="anillo-lógicamente-particionado" class="slide level2">
<h2>Anillo lógicamente particionado</h2>
<aside class="notes">
<p>Una consecuencia de lo que hablamos recién es que dos nodos pueden considerarse miembros del anillo, y sin embargo ninguno estar al tanto inmediatamente del otro. Para evitar particionados lógicos, algunos nodos de Dynamo tienen el rol de semillas: nodos que se descubren por un mecanismo externo y son conocidos por todos los nodos. Todos los nodos eventualmente reconcilian su membresía con una semilla, entonces los particionados lógicos son altamente improbables. Las semillas se pueden obtener de una configuración estática o de un servicio de configuración. Típicamente son nodos funcionales del anillo de Dynamo.</p>
</aside>
</section></section>
<section>
<section id="membresía-y-detección-de-fallas-detección-de-fallas" class="title-slide slide level1">
<h1>Membresía y Detección de fallas: Detección de fallas</h1>
</section>
<section id="evitar-intentos-fallidos-de-comunicación" class="slide level2">
<h2>Evitar intentos fallidos de comunicación</h2>
<aside class="notes">
<p>En dynamo se utiliza la detección de fallas para evitara intentos de comunicarse con pares no alcanzables durante operaciones de get/put o cuando transfiriendo particiones y hinted replicas. Para evitar comunicaciones fallidas, una noción puramente local de detección de fallas alcanza, utilizando nodos alternativos para servir requests de nodos que se detectan que no responden. Cada tanto, se reintenta a los nodos que no responden. En la ausencia de requests de clientes que generen trafico entre ambos nodos, no necesitan saber si el otro es alcanzable y responde.</p>
</aside>
</section>
<section id="protocolo-de-rumores" class="slide level2">
<h2>Protocolo de rumores</h2>
<aside class="notes">
<p>Los protocolos descentralizados de detección de fallas utilizan un protocolo sencillo basado en rumores que permite que cada nodo en el sistema aprenda sobre la llegada o salida de los otros nodos.</p>
</aside>
</section></section>
<section>
<section id="agregando-y-removiendo-nodos-de-almacenamiento" class="title-slide slide level1">
<h1>Agregando y removiendo nodos de almacenamiento</h1>
</section>
<section id="asignación-de-tokens" class="slide level2">
<h2>Asignación de tokens</h2>
<aside class="notes">
<p>Cuando un nodo se agrega al sistema, se le asigna una cantidad de tokens distribuidos al azar en el anillo. Por cada rango de claves que se le asigna al nodo, puede haber una cantidad de nodos menor o igual a N que actualmente manejan las claves que caen dentro de ese rango. Dada la asignación de rangos de claves al nuevo nodo, algunos nodos existentes no tienen mas algunas de sus claves y deben transferirlas al nuevo nodo.</p>
<p>Cuando un nodo se elimina del sistema, la resignación de claves sucede en un proceso inverso.</p>
</aside>
</section>
<section id="distribución-uniforme-en-los-nodos" class="slide level2">
<h2>Distribución uniforme en los nodos</h2>
<aside class="notes">
<p>La experiencia operativa demuestra que este enfoque distribuye la carga de claves uniformemente entre los nodos de almacenamiento. Esto permite cumplir los requisitos de latencia y bootstrapping rápido.</p>
</aside>
</section>
<section id="confirmation-round" class="slide level2">
<h2>Confirmation round</h2>
<aside class="notes">
<p>Una ronda de confirmación enter el origen y el destino, se asegura que el nodo de destino no reciba ningún duplicado para un dado rango de claves.</p>
</aside>
</section></section>
<section id="preguntas" class="title-slide slide level1">
<h1>¿Preguntas?</h1>
<p><img data-src="./img/questions.png" /></p>
</section>
</div>
</div>
<script src="./reveal.js/js/reveal.js"></script>
<script>
// Full list of configuration options available at:
// https://github.com/hakimel/reveal.js#configuration
Reveal.initialize({
// Push each slide change to the browser history
history: true,
// Optional reveal.js plugins
dependencies: [
{ src: './reveal.js/lib/js/classList.js', condition: function() { return !document.body.classList; } },
{ src: './reveal.js/plugin/zoom-js/zoom.js', async: true },
{ src: './reveal.js/plugin/notes/notes.js', async: true }
]
});
</script>
</body>
</html>