Capas de acceso a datos .net escalables de verdad contra SQL Server

Post on 23-Jan-2018

131 views 0 download

Transcript of Capas de acceso a datos .net escalables de verdad contra SQL Server

“Capas de acceso a datos .NET escalables de verdad contra SQL Server”

Enrique Catalá Bañuls@enriquecatalaecatala@solidq.comenrique@enriquecatala.com

MAD · NOV 24-25 · 2017

Temario

MAD · NOV 24-25 · 2017

1. Propuesta de problema2. Patrones de acceso a datos3. Objetos4. Concurrencia5. Almacenamiento

Enrique Catalá Bañuls

▪ Ingeniero Informático

▪ Microsoft Data Platform MVP

▪ Mentor en SolidQ

▪ Tuning y alta disponibilidad

ecatala@solidq.com www.solidq.com

@enriquecatala www.enriquecatala.com

Enrique Catala - ecatala@solidq.com - @enriquecatala

Mínimo

coste

Datos IoT

masivos en

formato

propietario

Procesamiento

complejo

previo

historificado

Historificado

no

dependiente

del nº de

eventos

Explotación de

datos

simultanea

¿De qué va esta

sesión?

Enrique Catala - ecatala@solidq.com - @enriquecatala

Mínimo

coste

Datos IoT

masivos en

formato

propietario

Procesamiento

complejo previo

historificado

Historificado no

dependiente del

nº de eventos

Explotación de

datos

simultanea

Problema a solucionar: Planteamientos

•C# y SQL Server

¿Tecnología a utilizar?

•Elijamos

¿Patron de acceso a datos?

•Patrones

Concurrencia

•Elijamos

¿Modelo de almacenamiento?

Tipología de

acceso

Por conjuntos Por cursores

Patrones de

bajo nivel

Dinámico

Adhoc

Parametrizable

Estático

Stored

procedures

Arquitecturas

Modelo

conectividad

Conectada

Desconectada

Modelo de

desarrollo

Manual

ORM

Enrique Catala - ecatala@solidq.com - @enriquecatala

DEMO1

ADHOC

VS

PREPARED QUERIES

Enrique Catala - ecatala@solidq.com - @enriquecatala

DEMO2

ROW BY ROW

VS

BATCH

Generalmente es preferible hacer menos operaciones a la BBDD con mas conjuntos de filas

Enrique Catala - ecatala@solidq.com - @enriquecatala

DEMO3

LIST

VS

DICTIONARY

List<T>

O(n)

Dictionary<T,U>

O(1)

System.Collections.Concurrent

Proteje acceso a variables

Utiliza patrones como ReaderWriterLockSlim

Evita lock(this)

No dejes hilos

huerfanos

Concurrency Visualizerfor VS

Consideraciones concurrencia

Enrique Catala - ecatala@solidq.com - @enriquecatala

public void MethodWithLock(){

lock (syncLock){

// código monothread}

}

ESTO NO SE HACE!

Consideraciones concurrencia

Enrique Catala - ecatala@solidq.com - @enriquecatala

Patrón multiples lectores, un escritor

Consideraciones concurrencia

public class MultipleReadsOneWriter{

private volatile int value;private ReaderWriterLockSlim rwls;

public MultipleReadsOneWriter(){

rwls = new ReaderWriterLockSlim(LockRecursionPolicy.NoRecursion);}

Enrique Catala - ecatala@solidq.com - @enriquecatala

Bloqueo ligero para lectores

Consideraciones concurrencia

public int ReadValue(){

int result = default(int);rwls.EnterReadLock();try{

result = value;}finally{

rwls.ExitReadLock();}return result;

}

Enrique Catala - ecatala@solidq.com - @enriquecatala

Bloqueo duro para escritores

Consideraciones concurrencia

public void WriteValue(int number){

rwls.EnterWriteLock();try{

value = number;}finally{

rwls.ExitWriteLock();}

}

Enrique Catala - ecatala@solidq.com - @enriquecatala

Tentativa de bloqueo y bloqueo posterior duro

Consideraciones concurrencia

public void WriteValueIfEqual(int compare, int number){

rwls.EnterUpgradeableReadLock();try{

int current = value;if (current == compare){

rwls.EnterWriteLock();try{

value = number;}finally{

rwls.ExitWriteLock();}

}}finally{

rwls.ExitUpgradeableReadLock();}

}

Enrique Catala - ecatala@solidq.com - @enriquecatala

Lock free

Consideraciones concurrencia

•ConcurrentDictionary

Cargar diccionarios

•Modelo desconectado

•Secuencias

Reserva de IDs•Lectura de datos IoT

• Inserción en

diccionario con ID

asignado en secuencia

Carga de eventos en

Diccionario vacío

•Código multihilo

lockfree

•Cada thread

independiente sobre el

mismo diccionario

Procesado multihilo•BCP directo

Flush a BBDD

Enrique Catala - ecatala@solidq.com - @enriquecatala

Lock free

Consideraciones concurrencia

Cargar diccionarios

•ConcurrentDictionary

Reserva de IDs

•Modelo desconectado

• Secuencias

Carga de eventos

en Diccionario vacío

•Asignación de IDs

reservados

Procesado multihilo

Flush a BBDD

protected long GetDictionaryKey(String mykey){

try{

long retorno = -1;if (!MyDictionary.TryGetValue(mykey, out retorno)){

GetNextSequenceValuesMyDictionary();}return (retorno);

}catch (Exception){

throw;}

}

EXEC sp_sequence_get_range @sequence_name = N'<sequence>' ,@range_size = range_size ,@range_first_value = range_first_value OUTPUT

Enrique Catala - ecatala@solidq.com - @enriquecatala

Lock free

Consideraciones concurrencia

Cargar diccionarios

•ConcurrentDictionary

Reserva de IDs

•Modelo desconectado

• Secuencias

Carga de eventos

en Diccionario vacío

•Asignación de IDs

reservados

Procesado multihilo

Flush a BBDD

Parallel.For(0, numeroElementosAProcesar, new ParallelOptions {

MaxDegreeOfParallelism = MAXDOP }, i =>

{try{

Event eventTmp;if (DictionaryToFlush.TryGetValue(i,out eventTmp)){

/// Your complex code goes here///... ... ... ... ... ... ... ... ... ...DictionaryToFlush.TryUpdate(i, eventTmp);

}}catch (Exception e){

exceptions.Enqueue(e);}

});

Enrique Catala - ecatala@solidq.com - @enriquecatala

Lock free

Consideraciones concurrencia

Cargar diccionarios

•ConcurrentDictionary

Reserva de IDs

•Modelo desconectado

• Secuencias

Carga de eventos

en Diccionario vacío

•Asignación de IDs

reservados

Procesado multihilo

Flush a BBDD

using (SqlBulkCopy bulkCopy = new SqlBulkCopy(cn2)){

bulkCopy.BulkCopyTimeout = 0;

bulkCopy.ColumnMappings.Add(“key", “key");bulkCopy.ColumnMappings.Add(“Value", “value");

///Libreria FastMember (NuGet) para convertir al vuelo///using (var reader =

ObjectReader.Create(cdNew.Values, “key", “Value")){

bulkCopy.DestinationTableName = “YourTable";bulkCopy.WriteToServer(reader);

}}

Enrique Catala - ecatala@solidq.com - @enriquecatala

Almacenamiento columnar

Grandes volúmenes de datos

• Bloques mínimos de 1M filas

Elevada compression

Lectura minima de datos

Optimiza cache L2

Enrique Catala - ecatala@solidq.com - @enriquecatala

Almacenamiento in-memory

Otro motor relacional

Máximo

rendimiento

Compatibilidad

Lock free

Tipología de

acceso

Por conjuntos Por cursores

Patrones de

bajo nivel

Dinámico

Adhoc

Parametrizable

Estático

Stored

procedures

Arquitecturas

Modelo

conectividad

Conectada

Desconectada

Modelo de

desarrollo

Manual

ORM

Enrique Catala - ecatala@solidq.com - @enriquecatala

DEMO: TSQL Query Analytics

DW rendimiento queries

Alertas proactivas

PowerBI para análisis a cualquier nivel

PaaS

http://www.solidq.com/es/tsql-query-analytics/

• Evita procesados fila a filaCapas de acceso a

datos

• La estructura de datos importa, no es todo BBDDComplejidad

algorítmica

• Ya no estamos en los 90. Hasta tu móvil tiene 8

núcleos ☺

Consideraciones de

concurrencia

• Elige con criterio y úsalo bienORMs

• Un motor relacional no son solo tablas,

aprovecha la tecnología eficientemente.Almacenamiento

ecatala@solidq.com

www.solidq.com

@enriquecatala

Gracias!!!