Skip to content

Commit c2ca125

Browse files
committed
added estimations
1 parent 2d5c3dd commit c2ca125

File tree

81 files changed

+941
-220
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

81 files changed

+941
-220
lines changed

book.adoc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ Camilo A. Castro <https://github.com/clsource[@clsource]>
1919
:ext-relative:
2020
:source-linenums-option:
2121
:source-highlighter: highlight.js
22-
:highlightjs-languages: css, javascript, markdown, ruby, wren, elixir, erlang, swift, rust, python, yaml
22+
:highlightjs-languages: css, javascript, markdown, ruby, wren, elixir, erlang, swift, rust, python, yaml, sql, text, sh
2323
:highlightjs-theme: srcery
2424
:highlightjsdir: highlight
2525
:stem: latexmath

book/chapters/systemd/chapter.adoc

Lines changed: 178 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ El almacenamiento y transferencia de datos comunmente se mide en _Bytes_ y poten
3030

3131
La siguiente tabla muestra la unidad de volumen de datos.
3232

33+
[options="header"]
3334
|===
3435
| Potencia | Valor Aproximado | Nombre | Abreviación
3536
| 1 | 1 Uno (bit) | Bit | b
@@ -41,6 +42,24 @@ La siguiente tabla muestra la unidad de volumen de datos.
4142
| 50 | 1 Cuatrillón (bits)| Petabyte | 1 PB
4243
|===
4344

45+
==== Tipos de Datos
46+
47+
Los tipos de datos que pueden ser usados en una base de datos tienen una cantidad
48+
de almacenamiento definido. Va a cambiar dependiendo del motor de base de datos usado. La siguiente tabla muestra un aproximado de los tipos de datos más comunes.
49+
50+
[options="header"]
51+
|===
52+
| Tipo de Dato | Tamaño de Almacenamiento | Descripción
53+
| boolean (booleano) | 1 byte | verdadero o falso.
54+
| smallint (entero pequeño) | 2 bytes | Un entero con valores acotados.
55+
| integer (entero) | 4 bytes | Un número entero tradicional.
56+
| bigint (entero grande) | 8 bytes | Un número entero con mayor capacidad. Para números aún más grandes.
57+
| float (decimal) | 4 bytes | Un número decimal con 6 decimales de precisión.
58+
| double (decimal con doble precisión) | 8 bytes | Un número decimal con 15 decimales de precisión.
59+
| varchar (caracteres variable) | (4 + n) byte | Se suma la cantidad de caracteres más 4 para obtener el total de espacio requerido.
60+
| blob (binario) | variable | Un archivo binario almacenado. El tamaño dependerá de cada archivo.
61+
|===
62+
4463
==== Números de Latencia
4564

4665
La latencia nos indica cuánto se demora un proceso desde que se hace la petición hasta recibir una respuesta. A mayor cantidad de latencia, mayor será el tiempo que necesitemos esperar para obtener una respuesta. El tiempo de retraso de las latencias puede crear ineficiencias, especialmente en las operaciones en tiempo real.
@@ -49,11 +68,169 @@ Los siguientes gráficos contienen números aproximados, ya que según el avance
4968

5069
Basado en los números de Jeff Dean y Peter Norvig (http://norvig.com/21-days.html#answers).
5170

52-
5371
image::latenciagrafico.png[Latencia Gráfico]
5472

73+
[options="header"]
74+
|===
75+
|Operation |ns |µs |ms |note
76+
|L1 cache reference |0.5 ns | | |
77+
78+
|Branch mispredict |5 ns | | |
79+
80+
|L2 cache reference |7 ns | | |14x L1 cache
81+
82+
|Mutex lock/unlock |25 ns | | |
83+
84+
|Main memory reference |100 ns | | |20x L2 cache, 200x L1 cache
85+
86+
|Compress 1K bytes with Zippy |3,000 ns |3 µs | |
87+
88+
|Send 1K bytes over 1 Gbps network |10,000 ns |10 µs | |
89+
90+
|Read 4K randomly from SSD* |150,000 ns |150 µs | |~1GB/sec SSD
91+
92+
|Read 1 MB sequentially from memory |250,000 ns |250 µs | |
93+
94+
|Round trip within same datacenter |500,000 ns |500 µs | |
95+
96+
|Read 1 MB sequentially from SSD* |1,000,000 ns |1,000 µs |1 ms
97+
|~1GB/sec SSD, 4X memory
98+
99+
|Disk seek |10,000,000 ns |10,000 µs |10 ms |20x datacenter roundtrip
100+
101+
|Read 1 MB sequentially from disk |20,000,000 ns |20,000 µs |20 ms |80x
102+
memory, 20X SSD
103+
104+
|Send packet CA -> Netherlands -> CA |150,000,000 ns |150,000 µs |150 ms
105+
|
106+
|===
107+
108+
- 1 ns = 10^-9 segundos
109+
- 1 us = 10^-6 segundos = 1,000 ns
110+
- 1 ms = 10^-3 segundos = 1,000 us = 1,000,000 ns
111+
55112
image::latencia.jpg[Latencia]
56113

114+
===== Cachés L1 y L2: 1 ns, 10 ns
115+
Normalmente están integrados en el chip del microprocesador. A menos que trabaje directamente con hardware, probablemente no necesite preocuparse por ellos.
116+
117+
===== Acceso a RAM: 100 ns
118+
Se necesitan alrededor de 100 ns para leer datos de la memoria. Redis es un almacén de datos en memoria, por lo que se necesitan unos 100 ns para leer datos de Redis.
119+
120+
===== Envía 1K bytes a través de una red de 1 Gbps: 10 us
121+
Se necesitan alrededor de 10 usuarios para enviar 1 KB de datos desde Memcached a través de la red.
122+
123+
===== Leer desde SSD: 100 us
124+
RocksDB es un almacén K/V basado en disco, por lo que la latencia de lectura es de alrededor de 100 us en SSD.
125+
126+
===== Operación de inserción de base de datos: 1 ms.
127+
La confirmación de Postgresql puede tardar 1 ms. La base de datos necesita almacenar los datos, crear el índice y vaciar los registros. Todas estas acciones toman tiempo.
128+
129+
===== Enviar paquete CA->Países Bajos->CA: 100 ms
130+
Si tenemos una llamada de larga distancia por Zoom, la latencia podría rondar los 100 ms.
131+
132+
===== Reintentar/actualizar interno: 1-10s
133+
En un sistema de monitoreo, el intervalo de actualización generalmente se establece en 5 a 10 segundos (valor predeterminado en Grafana).
134+
135+
===== Resumen
136+
137+
Al leer los datos se puede concluir las siguientes cosas:
138+
139+
- Leer de la memoria es más rápido que leer de un disco duro.
140+
- Leer del disco duro solo cuando sea obligatorio.
141+
- Los algoritmos de compresión son rápidos y se recomienda su utilización al enviar los datos por la red.
142+
- Los centros de datos de diferentes regiones requerirán más tiempo para transferir datos entre ellos.
143+
144+
==== Estimación General
145+
146+
El primer paso en el proceso de estimación es definir los objetivos.
147+
148+
- Nivel mínimo: Objetivo que no tiene grandes exigencias. ¿Cuánto es lo mínimo que el sistema necesitaría para funcionar correctamente?.
149+
150+
- Nivel promedio: Objetivo que busca definir el comportamiento normal de un sistema. ¿Cuánto es lo que necesitaría el sistema en un día normal?.
151+
152+
- Nivel crítico: Objetivo que busca definir el comportamiento exigente de un sistema. ¿Cuánto es lo que necesitaría el sistema en un día de alta exigencia?.
153+
154+
Una vez definido el objetivo y los supuestos a cumplir, se debe transformar a datos como
155+
tamaño de almacenamiento o tamaño de transferencia. Ya que normalmente son los
156+
necesarios para comparar con la tabla de precios de un proveedor de servicios. Al tener el tamaño de almacenamiento o transferencia, se puede estimar los costos monetarios necesarios para lograr los objetivos planteados.
157+
158+
===== Cantidad de Usuarios Diarios (CUD)
159+
160+
La cantidad de usuarios diarios nos ayudará a definir cuán grande es el volumen de consultas por segundo de un sistema, teniendo en consideración las operaciones que los usuarios realicen.
161+
162+
===== Consultas por Segundo (QPS: Queries per Second)
163+
164+
Una métrica común es ¿Cúantas consultas tendrá por segundo la aplicación?.
165+
Esto nos permite determinar la cantidad de almacenamiento y datos necesarios
166+
en los casos hipotéticos acordados.
167+
168+
===== Ejemplo: Red Microblogging
169+
170+
Una red microblogging similar a sistemas como Mastodon o X (Twitter).
171+
172+
====== Objetivos y Supuestos
173+
- 300 millones de usuarios activos mensuales.
174+
- 50% utiliza el sistema diariamente.
175+
- Se realizan 2 posts por día en promedio.
176+
- 10% de los posts contienen imagenes (media).
177+
- Los datos se almacenan por 5 años.
178+
179+
====== Obtención de las QPS (Querys per Second)
180+
181+
El primer paso es obtener la cantidad de usuarios diarios (CUD), para esto
182+
obtenemos el 50% de 300 millones.
183+
184+
- 300 millones (Usuarios Mensuales) * 50% (Uso diario) = 150 millones (Usuarios Diarios)
185+
186+
Sabemos que con 150 millones de usuarios diarios, cada usuario realiza 2 posts por día. Esto lo debemos transformar a segundos.
187+
188+
[text]
189+
----
190+
posts_por_dia = 150 millones usuarios * 2 posts
191+
horas_por_dia = 24
192+
segundos_por_dia = 3600
193+
194+
QPS = posts_por_dia / horas_por_dia / segundos_por_dia
195+
QPS = ~3500 Queries por Segundo.
196+
----
197+
198+
Ahora si tomamos la cantidad total de usuarios y asumiendo que todos
199+
los usuarios realizan dos posts en un mismo día
200+
201+
[text]
202+
----
203+
QPS_MAX = 2 * QPS = ~7000 Queries por Segundo.
204+
----
205+
206+
====== Almacenamiento Estimado
207+
208+
Ahora si definimos que cada post contiene la siguiente información:
209+
210+
[sql]
211+
----
212+
id varchar(64) -- cadena de caracteres de 64 bytes
213+
text varchar(140) -- cadena de caracteres de 140 bytes
214+
media blob(1MB) -- imagen de 1 MegaByte
215+
----
216+
217+
Utilizando la `QPS` podemos calcular cuánto espacio de almacenamiento necesitamos.
218+
219+
[text]
220+
----
221+
peso_imagen = 10% * 1 MB
222+
posts_por_dia * peso_imagen
223+
terabytes_por_dia = 30
224+
terabytes_en_5_anios = terabytes_por_dia * 365 * 5 // 55 PetaBytes
225+
----
226+
227+
==== Enlaces
228+
229+
- https://www.linkedin.com/posts/alexxubyte_systemdesign-coding-interviewtips-activity-7126968760971714560-aZ7T?trk=public_profile_like_view
230+
231+
- https://gist.github.com/jboner/2841832
232+
233+
57234
=== Escalado horizontal y vertical
58235

59236
La escalabilidad se refiere a la capacidad de una aplicación para manejar y soportar una mayor carga de trabajo sin sacrificar la latencia. Una aplicación necesita una potencia informática sólida para escalar bien. Los servidores deben ser lo suficientemente potentes para manejar mayores cargas de tráfico. Hay dos formas principales de escalar una aplicación: horizontalmente y verticalmente.

0 commit comments

Comments
 (0)