La descarga está en progreso. Por favor, espere

La descarga está en progreso. Por favor, espere

Escalado horizontal ilimitado ¿en SQL Server?

Similar presentations


Presentation on theme: "Escalado horizontal ilimitado ¿en SQL Server?"— Presentation transcript:

1 Escalado horizontal ilimitado ¿en SQL Server?
Alberto López Grande Escalado horizontal ilimitado ¿en SQL Server?

2 BIG Thanks to SQLSatMadrid sponsors
Platinum Gold

3 Sponsor sessions at 10:15 & 13:00
Don’t miss them, they might be getting distributing some awesome prizes! Also XBOX One & Raffle prizes at 17:45

4 About me… @qwalgrande Dpto. Sistemas Estructurados en GCOTS

5 Introducción La tendencia, el futuro, el pasado… … La turra
No hace mucho, conversando con un compañero, Bernabé, me comentó “últimamente, cada vez oigo más que vuelven los mainframes, los superordenadores, todo concentrado”. Yo no es que lo oiga mucho, aunque quizá si escuchara más pues a lo mejor.

6 Elasticidad, flexibilidad, pago por uso
Dinámico… … evolucionar… … agilidad… …. On demand… Lo que observo desde hace ya muchos años es la tendencia justo a todo lo contrario, viajar hacia la virtualización, a la nube, la atomización de los datacenters, el “pagar por lo consumido” y “flexibilidad en el dimensionado”, poder crecer, pero también encoger, de forma ágil y bajo demanda. Y debe ser en todas las aristas, en tamaño de almacenamiento, potencia en el procesado, concurrencia, y por supuesto, licencias/pasta.

7 Escalado vertical Scale-up, sólo hace falta dinero. ¿Y cuando ya no “da pa’ más”? ¿Y cuando la nube no es una opción? Ese crecer y encoger nos plantea un conjunto de problemáticas bastante curiosas, en lo que respecta a los datos. Meter más procesadores o más memoria lo sabe hacer cualquiera, contratar el bicho más gordo sólo requiere dinero. Pero llega un punto en el que ni por esas da para cubrir. Otras veces el punto está en que para soportar el pico de carga más elevado, se debe desperdiciar una capacidad para el resto de los momentos. Si estamos hablando de una infraestructura pequeña o mediana, esto se resuelve en la nube de forma más que holgada, con simple escalado vertical. Ya no es tan fácil cuando hablamos de un entorno empresarial grande, donde abastecer de almacenamiento y músculo no es tan fácil y también donde llevar cosas a la nube no es algo trivial. Aquí ya tenemos que valorar el escalado vertical y también el escalado horizontal.

8 Los buenos tiempos Como viejuno que soy, cuento batallitas de “los buenos tiempos”. Dentro de esos “buenos tiempos”, han sido varias las veces en las que padre me trajo a casa el mejor y mayor servidor que el dinero podía comprar para meter ahí SQL Server. Eran épocas de vacas gordas, pero también de intentar alcanzar el máximo de procesamiento posible. Así, tuvimos esos maquinotes de Unisys, con los procesadores de i64, 64 bytes, pero de los duros, los Montecito. O ese rac con la gran “X” roja, con 8 numas, asimétricos además…. Qué hostia cuando migramos a 2005, en fin. Historias de hace muchos años.

9 La lata de tomate Se convirtió en barrica… … y ésta en container… …. y con éste, la tomatina (por la concurrencia) La sensación era haber llegado al tope. Y sin embargo, había que seguir creciendo, no ya tanto en capacidad de tratar operaciones por segundo, sino en la capacidad de albergar ingentes cantidades de datos, para vete a saber qué. Y que estén disponibles ahí, para, igualmente, vete a saber qué. Los actuales sistemas de data warehouse de grandes dimensiones pasan por tener un tamaño problemático para casi todo. Para respaldarlo, para moverlo, para consumirlo. Así que tenemos que explorar nuevas vías para resolverlo.

10 El ejemplo web Con webs, escalar horizontalmente es fácil Con bases de datos, no. Lo malo aquí es que se pretende trasladar a una base de datos lo que se hace con un servidor web. Esto es, si tengo un servidor web, pongo una granja con 4, pero que mañana puedan ser 40 y pasado 20. ¿No podemos hacer lo mismo con la base de datos? ¿Cuál es la respuesta? Que con tiempo y dinero, todo se puede. Eso sí, hay que tener en cuenta que los servidores web permiten de forma ágil hacer esto porque son copias iguales que no tienen modificaciones frecuentes. Lo que pasa con las bases de datos es que se leen, claro está, pero también se escribe en ellas y amigo, para la lectura, mal que bien, pero para la escritura, ya no es tan fácil repartir la carga. Y tampoco para la memoria, ni para ampliar y luego al rato encoger.

11 Cambios profundos Arquitectura, aplicaciones Y mentalidad. ¿Es posible? ¿Es asequible? ¿Es flexible? ¿Es “ilimitado”? Son retos grandes que requieren de cambios profundos en la arquitectura, en las aplicaciones y en la mentalidad, que siempre es lo que más cuesta. Hoy hablaremos sobre eso, sobre la escalabilidad horizontal en SQL Server. ¿Es posible? ¿Es asequible? ¿Es flexible? ¿Es “ilimitado”?

12 Acotando el escenario Múltiples copias de los datos… Fuera. (AlwaysOn, replicación merge) Como esto es muy amplio, vamos a acotarlo un poco primeramente. Por una parte, no me interesa mucho el caso “clásico” de replicación de la información, esto es, no me interesa tener más de una copia de todos los datos. Quiero un sistema en el que todos los datos estén, y que estén repartidos. Por hacer un breve repaso, estas problemáticas las resolveríamos con técnicas como secundarios de Always On, replicación merge, y ese tipo de cosas, que como digo, no me interesan. Esos escenarios están bien descritos, hay literatura en abundancia. Sólo recordar que hay pocos infiernos peores que lidiar con una replicación merge.

13 Acotando el escenario Azure SQL Database Elastic Pool… Fuera ¿Pero qué es? (al final si da tiempo) También voy a descartar el caso Azure SQL Database Elastic Pool, aunque este os lo voy a contar, como solución aislada, ya que me parece interesante. [Contar Azure SQL Database Elastic Pool]

14 Acotando el escenario (ahora lo que sí)
On premise Grandes dimensiones “N” nodos, compartiendo lecturas, quizá escrituras. Me quedo con una situación en el que los datos están on premise, y quiero construir el servicio con un número indeterminado de nodos que den el servicio de bases de datos, compartiendo las lecturas y si es posible también las escrituras, particionando los datos, con mecanismos que posibiliten añadir más leña al fuego si fuera preciso.

15 Sharding, el concepto Pedazo, fragmento, trozo, miaja’, alícuota. Dividir una base de datos grande en muchas pequeñas y manejables. Introduzco aquí un palabro. Shard podemos traducirlo por pedazo, fragmento, trozo, miaja, alícuota. En tecnología de bases de datos, sharding significa dividir una base de datos muy grande en muchas bases de datos más pequeñas y manejables.

16 Shard key Dividir es fácil: ¿Y dónde los puse? La clave.
Geográficamente. Temporalmente. Por round robin. ¿Y dónde los puse? La clave. Lo de trocear es aparentemente fácil. Puedes dividir tus datos de forma lógica (geográficamente, por tiempo o por round robin), la gracia y dificultad está en hacer de tal forma que luego cuando se soliciten datos, sepas dónde ir a buscarlos. No hay que ser un maestro en el diseño, esto consiste en definir un atributo, o clave (shard key) que vaya en todas las tablas. Y luego una tablita que te indique, para cada clave, dónde ir a buscar los datos, pudiendo estos estar divididos entre bases de datos, entre servidores. La primera casuística puede ser adecuada para una circunstancia, y es para emplear SQL Server Express y contar con un conjunto de bases de datos de menos de 10 Gb. Tiene sus notables limitaciones y no entraré en ello, pero os lo dejo como un apunte, si alguien tiene interés, que me lo diga luego y le doy alguna pista.

17 Tabla de claves Como os conté al inicio, el enfoque era hacia entornos grandes, y en esas circunstancias, realizar divisiones de bases de datos para dejarlas en el mismo servidor por este motivo, no tiene mucho sentido que digamos. Si queremos jugar a esto, con emplear particionado, suficiente, si bien es algo que a mí particularmente me parece que tiene un campo de aplicación bastante limitado: poco beneficio para un aumento significativo del coste de mantenimiento, siempre en primera instancia. Bien aprovechado y exprimido, se le puede sacar un ENORME partido. Pero sigamos con lo nuestro. Teníamos que nuestro modelo de datos debía contar con un atributo adicional que nos dijera de dónde proceden los datos y un maestro, una guía de claves que nos dijera dónde ir a buscar los datos en función de esa clave de reparto.

18 Modelo ejemplo Os voy a proponer un modelo simple, donde nuestro modelo de partida es idéntico al modelo “sharding”, en el que agregamos un campo más a la clave primaria que sea la shard key, y esto lo trasladamos a todas las tablas: [modelo de datos de facturas, líneas de factura, clientes, productos] Bueno, a todas no, ya que las tablas puramente auxiliares, como “productos”, pero aplicable a países, provincias, tablas de direcciones (callejero), y un largo etc. Es decir, aquello que por tamaño no tenga sentido dividir. Nuestro nuevo modelo, será el siguiente: [mismo modelo con la shard key añadida] A este modelo le falta una tabla más, la de las shard keys: [pintar la tabla, con su clave, la descripción, campos adicionales de ubicación, etc.]

19 Escrituras Un punto de entrada. N puntos de entrada. - Reparto por rangos. - Reparto por round robin. Y ahora que tenemos nuestro mini modelo, vamos a empezar a explotarlo. Empezaremos por las escrituras. Una de las decisiones que debemos tomar es si deseamos repartir las escrituras o por el contrario queremos concentrarlas en el online para luego hacer el traslado según y cuando convenga en un lote. Ambas fórmulas son perfectamente válidas, ya que un modelo, hasta de la más alta concurrencia, se puede preparar con un único punto de entrada o con N puntos. Dentro de los N puntos, puede ser un reparto por rangos o por round robin. Vamos a estos tres modelos.

20 Reparto por round robin
No es tan “al azar”: - Nodo disponible. - Volumen de llenado. - Nivel de concurrencia. - Datos relacionados. - Fidelización de la sesión. Supongamos que tengo un modelo de reparto en round robin, esto es, cuando se da la necesidad de insertar, tomo un destino “al azar” y allí que meto los datos. En ese “al azar” no es tal, ya que lo condicionaremos por cuestiones como: Qué nodos estén disponibles. No voy a mandar nada a un nodo que está caído. Qué volumen de llenado tiene el nodo. Qué nivel de concurrencia tiene el nodo. Si hay datos relacionados existentes, puede interesar concentrar. Si en pasos previos trabajé con un nodo en una misma sesión, puede interesar seguir con él. La concurrencia, como siempre, es lo más difícil de probar. El resto de cuestiones, no tanto.

21 Reparto por round robin
Algoritmo sencillo y muy rápido. Si se basa en el destino, consulta adicional. Se elige, se construye la cadena de conexión y envío los datos. A la postre, es currarnos un algoritmo de reparto con el que nos sintamos cómodos. Ese algoritmo debe ser sencillo, y muy rápido, un “top 1” con algunos filtros sobre la tabla de claves. Esto puede basarse o no en el destino, esto es, puede elegir entre nodos perfectamente al azar, descartando los que no estén disponibles, sin lanzar ninguna query, o sin lanzar una cada vez. Si se basa en el destino, ya tengo una primera consulta que ejecutar. Una vez elegido el nodo, se construye la cadena de conexión y allí que mando los datos.

22 Reparto por rangos Igual que round robin, pero por rangos. El algoritmo de elección condicionado por el rango. Menos paralelismo. La opción de rangos es igualita que esta, pero donde la elección del nodo se basa en los propios rangos, que pueden ser por distribución geográfica o por lo que sea, pero en el fondo no hay diferencias. Eso sí, existirá una lógica que permita conocer a priori dónde acabaron los datos. La distribución, al no tan ser aleatoria, pierde algo de paralelismo.

23 Nodo principal, nodos secundarios
Escrituras no repartidas. Cuando se complete o en batch  mover y vaciar. Luego tenemos la opción que he llamado “nodo principal vs resto de nodos”. En esta fórmula no tendríamos repartidas las inserciones “on line”, todas irían a un servidor principal. Este servidor irían cargándose de datos y cuando estuviera completo, se tendría que orquestar un proceso de volcado e inicialización para agregar un nodo adicional, dejando el principal nuevamente vacío para seguir recibiendo las inserciones.

24 Pros y contras nodo principal
Contras: Asegurar disponibilidad nodo principal Pros: Mucho más fácil de gestionar Pros: Responde todos requerimientos… Contras:.. Menos quizá la concurrencia Algo común: la shard key cambia (en otros casos no es seguro que cambie). Algo que ya os tendría que haber saltado es el aspecto de la disponibilidad. Al tener un único punto de entrada, hay que proteger bastante más este servidor, con opciones como el failover cluster. Y sin paños calientes, esta vía es mucho más fácil de administrar y gestionar, ya que tiene un nodo “online” y una serie de nodos “históricos”. Cada nuevo histórico que haga falta agregar, se puede hacer manualmente. También se puede optar por contar con procesos de “vaciado y reparto” de datos a múltiples nodos en horas de menor carga.

25 Mezcla de todas Pool pequeño de servidores de entrada. Pool grande servidores de almacenamiento frío. Todas las virtudes y puede que todos los problemas. A priori, es la solución más potente. Otra opción que podría plantearse sería una mezcla de ambas. Esto es tener un pool pequeño de servidores de entrada (digamos 4), que se repartirían las inserciones por round robin. Y luego un pool grande de servidores (digamos 100) con datos anteriores o datos ya en frío. Esta vía cuenta, lógicamente, con las virtudes de ambos enfoques a cambio de los posibles problemas que tienen y que en según qué circunstancias, podrían retroalimentarse para mal. Eso sí, te cubre la disponibilidad, la concurrencia, la escalabilidad, en fin, todo. Como ya se atisba, deberemos dotarnos de un set de herramientas que nos permitan las operaciones de movimiento de datos entre nodos, para igualar su volumen, vaciar uno de ellos, crear un nuevo nodo y agregarlo al pool. Ya profundizaremos en esa cuestión, porque es de bastante importancia.

26 La lectura Reto en rendimiento. ¿Vistas “union all”? No es opción. Gestión de índices. Repartida la escritura, repartiditos tenemos los datos. Y ahora habrá que consumirlos. Este punto es el más interesante para el rendimiento, ya que entenderéis que crear vistas “unión all” que combinen datos de N servidores es demencial. Y nos expone ante la mayor limitación, opino, de este sistema y es que aquí los índices, hay que crearlos y mantenerlos por nuestras propias herramientas.

27 ¿Dónde están los datos? Si tengo 100 servidores, ¿lanzo 100 consultas? Límite inferior (bien hecho, no está tan mal) Tratemos de mejorarlo. ¿Cómo sé yo en qué servidor están los datos de un cliente, si tengo 100 servidores en los que buscar? ¿Tendré que lanzar la consulta 100 veces a 100 servidores diferentes? Bueno, pues ese será nuestro límite inferior de rendimiento y lo que logremos mejorar de ahí, eso que nuestro sistema habrá ganado. Por cierto, os recuerdo que es justa y exactamente eso lo que propone el Elastic Database Tool, select de unión.

28 Índices ¿Qué es un índice? Aplicado al reparto.
Nuestro problema aquí son los índices. ¿Alguno no sabe lo que es un índice? Lo voy a contar igualmente, pero no os avergoncéis. Un índice es un subconjunto de campos ordenado de los datos de una tabla, con un apuntador a la tabla en sí que permita localizar las filas y obtener el resto de campos de dicha tabla. Ejemplo práctico: Tengo mi tabla de cliente, cuya clave primaria es… La shard key y el número de cliente. Mis búsquedas se realizan por DNI, así que creo un índice, que incluya ese campo, el DNI, pero también debe acoplársele la shard key y el número de cliente, para que cuando ya haya localizado el registro por DNI, pueda ir a la tabla, que está ordenada por la clave primaria (ya que como casi siempre y en este caso así es, coincide con el índice clustered) y recuperar el nombre, apellidos, etc.

29 Mantener los índices Aquí el motor no lo hace solo.
En prácticamente cualquier motor de bases de datos, los índices se automantienen. Cuando hay una inserción, se inserta en la tabla y en el índice (esto puede generar fragmentación y otros problemas, requiere de tareas administrativas para mantenerlos), pero es algo que el motor va a hacer por nosotros. En nuestro caso no será así, ya que los datos no están en un único servidor, están repartidos. Así que eso que hace el motor “solo”, lo tenemos que orquestar nosotros. Con cada inserción, tenemos que insertar por partida doble, para consolidar datos de tablas que serán nuestros índices: [tabla repartida y tabla de índices]

30 Comparativa de rendimiento
select shard_key, numcliente from TablaIndiceClienteDNI with(nolock) where DNI = ‘12345’ Select nombre, apellidos, dni from Clientes with(nolock) where shard_key = 23 and numcliente = 4123 Ya que la alternativa es ir a buscar el cliente a cada una de las 100 instancias. Comparemos el rendimiento: [select shard_key, numcliente from TablaIndiceClienteDNI with(nolock) where DNI = ‘12345’ Esto devuelve la shard key 23 y numcliente 4123 Se construye la conexión (con el shard key) Select nombre, apellidos, dni from Clientes with(nolock) where shard_key = 23 and numcliente = 4123 ] Es decir, dos o tres consultas, que van por clave, en la práctica cuesta más conectar y desconectar que otra cosa.

31 Siguiente fase, inner join
select shard_key, numfactura from TablaIndiceFacturasNumCliente with(nolock) where numcliente = 4123 Siguiente punto. Quiero obtener todas las facturas de un cliente. Lo primero, obtener el cliente, que ya lo hicimos antes. Segundo, obtener las facturas: [select shard_key, numfactura from TablaIndiceFacturasNumCliente with(nolock) where numcliente = 4123] Esto devuelve un conjunto de filas, que pueden tener varios shard_key diferentes. Se puede optar por una select de unión o por lanzar varias y resumir en la capa de aplicación los diferentes recordsets obtenidos.

32 Siguiente fase, inner join
(tengo datos en el servidor 12, el 25 y el 47) select campo1, campo2, campo3 From openquery (server12, ‘select campo1, campo2, campo3 from Facturas with(nolock) where shard_key = 12 and numfactura in (234, 235, 554)’ ) s12 Union all From openquery (server25, ‘select campo1, campo2, campo3 from Facturas with(nolock) where shard_key = 25 and numfactura in (522, 121, 923, 778)’ ) s25 From openquery (server47, ‘select campo1, campo2, campo3 from Facturas with(nolock) where shard_key = 47 and numfactura in (65, 1097)’ ) s47 Cuando decimos “select de unión”, desde luego no nos referimos a que exista una vista que por linked server realice la abstracción y luego aplicar el filtro, sino en construir esa sentencia: Se puede hacer lo mismo, pasando todos los números de factura a todas las ubicaciones, eso no variará mucho el resultado.

33 Vienen curvas Cada búsqueda requiere un trabajo a medida. ¿Dónde están las tablas de índices? - Servidor índices (ojo disponibilidad). - Repetir tablas (100 millones son 2Gb). De cualquier forma, más problemas. Lo que sí se observa es que cada búsqueda requiere de un trabajo casi a medida. Y efectivamente así es, y eso no es diferente a cualquier otra funcionalidad que se quiera implementar. Un procedimiento almacenado que realice su operativa. Más trabajo, claro, pero tampoco mucho más. Otro aspecto a considerar es dónde están esas tablas de índices. En este caso, podemos tener un “servidor de índices” o también repetir el contenido de los índices en todos los nodos, ya que su tamaño será pequeño y manejable. Por ejemplo, el índice del DNI, contendrá el DNI (10 bytes), la shardkey (2 bytes) y el numcliente (8 bytes y me estoy pasando). Total 20 bytes, con lo que caben 400 filas por página de 8 Kb. Así que para 100 millones de filas necesitas 2Gb de espacio, sin comprimir, que si lo comprimes será muchísimo menos. Así, las consultas a los índices podrán hacerse en todos los nodos, si está repetido, o todas al mismo (que tendrá que tener su pool o su cluster por disponibilidad). Aquí sí convendría ir con ojo para elegir la forma en que se llevan los datos a todas partes. Hay sistemas automáticos tipo replicación, otros más artesanales como CDC, ya va por gustos.

34 ¿Y si no hay tabla de índice?
100 consultas pueden ser 2 segundos. Servidores vinculados entre sí. Administrar la disponibilidad ¿Qué pasa si lo que tenemos es una consulta que “no lleva” su índice? Dependerá del caso, pero no olvidemos el umbral de rendimiento, el tope inferior, esto es, lanzar 100 consultas. 100 consultas pueden ser 2 segundos si están hechas como es debido, así que la posibilidad no hay que descartarla si vemos que la alternativa de crear y consolidar índices no es posible asumirla. Así que vamos a hacer un ejemplo en el que busquemos y recuperemos todos las facturas, con sus líneas, de los clientes que se apelliden “López”, en un supuesto en el que los clientes están repartidos de forma independiente a las facturas. Aunque no lo he dicho hasta ahora, suena prácticamente obligatorio que todos los servidores estén vinculados entre sí. Este es uno de los pasos de inicialización que deberemos tener siempre a mano para el mantenimiento de nuestro tinglado. Véase, creamos el servidor, agregamos la base de datos, ahí metemos el conjunto de tablas auxiliares repetidas, agregamos logins, agregamos linked server, etc… Otro paso inicial es tener un job que vaya comprobando la disponibilidad del resto de instancias, con sp_testlinkedserver, y actualizando un campito de la tabla de sharded keys que nos filtre para no ir a consumir datos, ni a insertar, en un servidor que no esté listo para la acción. Que nos falte una porción de los datos es malo en sí mismo, pero mucho peor es tener que esperar a un timeout porque falte el 1% de los datos, y que falle todo.

35 Ejemplo inner join Buscar clientes “López” Select shard_key, numcliente from BD1.dbo.Clientes with(nolock) where Apellido1 like ‘LOPEZ%’ Primer paso, buscar todos los clientes “López”, con sus números de clientes y los incluiremos, junto con su shard_key en una estructura temporal. La sentencia básica sería: Select shard_key, numcliente from BD1.dbo.Clientes with(nolock) where Apellido1 like ‘LOPEZ%’ (de acentos ya hablamos otro día) Suponemos que hay una indexación en cada tabla para que buscar por “López” rinda aceptablemente. Igualmente, suponemos que estará indexado el campo de numcliente en la tabla de facturas.

36 Ejemplo inner join if object_id ('tempdb..#clis')<> 0 drop table #clis if object_id ('tempdb..#RecordSet')<> 0 drop table #RecordSet varchar(max) Create table #Clis (shard_key smallint not null, numcliente bigint not null, primary key clustered (shard_key, numcliente) ) = 'select shard_key, numcliente from OpenQuery(##SERVER##, ''Select shard_key, numcliente from BD1.dbo.Clientes with(nolock) where Apellido1 like ''##FILTRO##%'''') T ' declare Cur cursor static for select ServerName from ShardTable with(nolock) where IsAvailable = 1 open cur fetch next from cur while = 0 begin = insert #Clis exec end deallocate cur Declaramos variables y montamos la sentencia que nos reporte los clientes que cumplan el filtro en la lista de servidores que estén disponibles.

37 Ejemplo inner join --select string_Agg(Num, ',') from numeros --select stuff((select ',' + cast(num as varchar(12)) as [text()] from numeros where num < 10 order by num for xml path('')), 1, 1, null) as lista = '' + stuff((select ',' + cast(numcliente as varchar(12)) as [text()] from #Clis order by numcliente for xml path('')), 1, 1, null) + '' = 'select * from OpenQuery(##SERVER##, ''Select C.DNI, C.nombre, C.apellido1, C.apellido2, F.numfactura, F.importe, LF.Cantidad, LF.Producto from BD1.dbo.Clientes C with(nolock) inner join BD1.dbo.Facturas F with(nolock) on C.NumCliente = F.NumCliente inner join BD1.dbo.LineasFactura LF with(nolock) on F.numfactura = LF.numfactura where C.NumCliente in (' + ''') T ' Aprovechando, la función string_Agg, de 2017, está chula. Esa lista de clientes es la que tengo que buscar, a su vez, en esos mismos servidores, trayéndome ya los datos de las tres tablas, clientes, facturas y líneas de factura.

38 Ejemplo inner join create table #RecordSet (DNI varchar(10) not null, nombre varchar(100) null, apellido1 varchar(100) not null, apellido2 varchar(100) null, numfactura int not null, importe numeric (9,2) not null, Cantidad smallint not null, Producto smallint not null) declare Cur2 cursor static for select ServerName from ShardTable with(nolock) where IsAvailable = 1 open cur2 fetch next from cur2 while = 0 begin = insert #RecordSet exec end deallocate cur2 Esto lo juntamos en un mismo sitio, otra temporal

39 Ejemplo inner join select DNI, nombre, apellido1, apellido2, numfactura, importe, Cantidad, Producto from #RecordSet order by DNI, numfactura if object_id ('tempdb..#clis')<> 0 drop table #clis if object_id ('tempdb..#RecordSet')<> 0 drop table #RecordSet El código resultante es feo, cursores, tablas temporales, pero también es T-SQL. Con un poquito de C# se puede simplificar notablemente (extrayendo datos desde un procedimiento que reciba un parámetro table-valued). Y se pueden encapsular cosas en procedimientos, funciones, cosas que simplifiquen considerablemente el código. Por ejemplo, aquí se buscan clientes por apellido. Pues se puede implementar un buscador en cada tabla que permita sucesivos cruces, devolviendo las claves. Lo importante es aquí que el rendimiento será adecuado y estará repartido entre el conjunto de servidores, ya que cada pequeño fragmento le llegará de forma aislada a cada nodo, se aglutinan y se muestran en uno, pero estará todo paralelizado. A ver, una petición aislada claro que no, está serializado, pero si tenemos centenares o miles de peticiones concurrentes, tendremos un montón de sentencias ejecutadas en cada servidor, pero todas ellas simples y muy rápidas.

40 Y en un data warehouse, ¿qué?
SSIS (y además irá como un tiro) Lectura paralelizada. Ojo, que hay que hacer joins y agrupaciones en SSIS Hasta ahora hemos hablado de la lectura discreta, para su consumo online por un conjunto de aplicaciones, llamémoslas transaccionales. Pero ese no será nuestro caso más habitual. Si tenemos un volumen significativo, y seguro que lo tenemos, ya que de otro modo, para qué este viaje, nuestro principal cometido seguramente sea el de constituir el data warehouse corporativo. Y un data warehouse requiere de su capa semántica para explotarlo eficazmente, así que raro será que no haya que alimentar unos cubos de ahí, o incluso algo más modernillo, como un modelo de aprendizaje o vete a saber. En un modelo así, repartido, se hace imperativo contar con algo que aglutine, ya que de otro modo, un “group by” que tenga que cruzar datos entre todos los nodos no lo moveremos ni a tiros.

41 Herramientas Para mover datos entre nodos Otra vez SSIS Tu backoffice
El siguiente aspecto a considerar, ahora que hemos dado un repaso a cuestiones de rendimiento, concurrencia y alguna cosa más en este ejemplo de la lectura, es dotarnos de un conjunto de herramientas que nos permitan, de forma más o menos ágil, mover información entre las particiones. En esa línea, sería cuestión de preparar un conjunto de paquetes de SSIS que se ocuparan de estas cosas, que permitieran una parametrización para manejarse con soltura. Así, como parámetros tendríamos el origen, el destino, si movemos una tabla o un conjunto de ellas, si dividimos o agrupamos. Si surgen dudas sobre qué casuísticas hay, de entrada habría que cubrir las funcionalidades de partitioning. Cuanto más completa sea esta lista de utilidades, más se ganará en lo tocante a la creación de esa sensación de que está todo en un continuo y que podemos tener igual 20 nodos que 200.

42 Herramientas Añadir un nodo. Quitar un nodo.
Mover todos los datos de un nodo a otro. Repartir los datos de un nodo entre el resto (para quitarlo). Así, tendríamos: Añadir un nodo. Quitar un nodo. Mover todos los datos de un nodo a otro nodo. Repartir los datos de un nodo entre el resto (para quitarlo).

43 Herramientas: Añadir un nodo
Es inicialización: - Crear base de datos vacía - Agregar tablas maestras. - Agregar nodo en tablas de shard. - Vincular servidor. - Incluirle en el resto de tareas administrativas. Lo de añadir un nodo tiene mucha más parte de inicialización del sistema, esto es, crear la base de datos vacía, con la estructura acordada, agregar en las tablas maestras el nuevo nodo y su ubicación, agregarlo como servidor vinculado, etc. No es mucho más difícil que aquello que ya hagáis cada vez que se agrega una instancia a la granja que manejéis.

44 Herramientas: Quitar un nodo
Lo contrario, tareas de finalización: - Darlo de baja como servidor vinculado. - Quitarlo como nodo en tablas de shard. - Apagar el servidor. Lo de quitar un nodo, más de lo mismo, es tocar la parte de configuración para que el sistema sepa que ya no tendrá que ir a buscar información a ese nodo. Y apagarlo, claro.

45 Herramientas: Mover datos
Conjunto de paquetes de SSIS Recurrir a BIML, orquestadores. Entretenido, sí. Difícil, no. Lo que resta es la parte de mover datos de un lado a otro. Es algo que podremos llevar a cabo con un conjunto de paquetes de SSIS, todos muy similares, que permitan seleccionar origen, destino y forma del reparto. Si tenemos muchísimas tablas, será un poco más tedioso. Si lo orquestamos en un paquete lanzador en el que definir la operación y pasar variables, es echar un rato para prepararlo.

46 Conclusiones Nivel de experiencia alto. Nivel de madurez de la organización alto. Cambios de calado en aplicaciones. Cambios relevante en infraestructura. Equipo de administración solvente (rendimiento). Ciclo de vida de software se complica (deployments). La conclusión más evidente es que montar esta historia es un follón que requiere un nivel de experiencia y madurez en una organización alto. Implica cambios de calado en el desarrollo de las aplicaciones, ya que hay que especializar el acceso a datos. Implica cambios relevantes en infraestructura, quizá no tanto si ya contamos con cierta soltura preparando maquinitas virtuales. También has de tener un equipo de administración solvente que atienda los posibles problemas que puedan surgir derivado de esta política, los de rendimiento serán los más relevantes, porque hay que estar monitorizando una granja, un pool de instancias. No se administran igual pocas instancias grandes que muchas pequeñas. El ciclo de vida del software se complica también, ya que los DBAs acostumbramos a “contar” con que los datos están en un único punto. Ahora, algo tan simple como agregar un par de tablas a la ecuación no es ni mucho menos trivial, hay que crearla en N servidores, preparar una función de reparto para la inserción, hacer o apoyar en el acceso a los datos de la misma, etc.

47 ¿Pero esto no lo hacíamos para ahorrar?
Conclusiones Costes en desarrollo, costes en infraestructura, costes en personal, costes…. ¿Pero esto no lo hacíamos para ahorrar? Todo ello es un trabajo que suma a la factura final de la película esta que nos estamos montando. Así que la gran conclusión es atípica en este tipo de charlas que se hacen. Es posible, ya que con tiempo y dinero, todo es posible, pero ¿es buena idea? Uf, seguramente no.

48 Conclusiones Menudo follón…
Así que la gran conclusión es atípica en este tipo de charlas que se hacen. Es posible, ya que con tiempo y dinero, todo es posible, pero ¿es buena idea? Uf, seguramente no. Hay otras opciones. Pero aquí lo que buscábamos era una alternativa que tuviera un rendimiento potente. Para algo que concatene “unión all” en servidores vinculados, o preparar vistas particionadas distribuidas, no hace falta tanta complicación. Irá horrendo, pero bueno.

49 ¿Qué hay ahí fuera? NoSQL (Mongo DB, COSMO).
Oracle, la solución más completa de las tres grandes. DB2, tiene, pero le falta. Motores diseñados para esto (NuoDB) Bueno, hay temas manejables en NoSQL con Mongo DB, COSMO. Pero vamos, hablando de motores de mayores, la solución que presenta Oracle es bastante apañada. Todo esto que hemos estado comentando lo implementa de forma nativa y te esconde lo que hace por dentro para que no te enteres y te parezca transparente. Es claramente la apuesta más potente entre los tres grandes. Otros motores, en fin, hay mucho que discutir ahí. En DB2 hay cositas, pero no son claros. Hay motores diseñados desde su inicio para este fin (NuoDB), pero claro, aquí te la juegas por la poca penetrabilidad. Pero es una base de datos elástica, donde el scale-out se hace por diseño, y con otras cosas bastante potentes también.

50 ¿En qué posición queda SQL Server?
El síndrome del azulejo. Una oportunidad de negocio… En general, podemos asegurar que SQL Server es elástico como un azulejo, así que aportar flexibilidad es una tarea que corre por cuenta de la casa. Si esto se demanda (que sí), ¿no hay empresas que lo hagan y lo comercialicen? He aquí una oportunidad de negocio…

51 Preguntas… … Los “y sis” que se os ocurran. … El plan de ejecución de una sentencia a servidor vinculado. …

52 Bibliografía y citas

53 Gracias por venir El momento de aplaudir es


Download ppt "Escalado horizontal ilimitado ¿en SQL Server?"

Similar presentations


Ads by Google