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.

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

En esta sesión aprenderemos a detectar e implementar correctamente capas de acceso a datos .NET que escalen a las capacidades HW de la máquina
¿Qué aprende nuestro público? Sacar provecho de todas las posibilidades de rendimiento que se ofrecen combinando SQL Server y .NET
Tecnología vista en esta ponencia T-SQL, C#, multihilo,…

  • Login to see the comments

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

  1. 1. “Capas de acceso a datos .NET escalables de verdad contra SQL Server” Enrique Catalá Bañuls @enriquecatala ecatala@solidq.com enrique@enriquecatala.com MAD · NOV 24-25 · 2017
  2. 2. Temario MAD · NOV 24-25 · 2017 1. Propuesta de problema 2. Patrones de acceso a datos 3. Objetos 4. Concurrencia 5. Almacenamiento
  3. 3. 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
  4. 4. 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?
  5. 5. 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?
  6. 6. 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
  7. 7. Enrique Catala - ecatala@solidq.com - @enriquecatala DEMO1 ADHOC VS PREPARED QUERIES
  8. 8. Enrique Catala - ecatala@solidq.com - @enriquecatala DEMO2 ROW BY ROW VS BATCH
  9. 9. Generalmente es preferible hacer menos operaciones a la BBDD con mas conjuntos de filas
  10. 10. Enrique Catala - ecatala@solidq.com - @enriquecatala DEMO3 LIST VS DICTIONARY
  11. 11. List<T> O(n) Dictionary<T,U> O(1)
  12. 12. System.Collections.Concurrent Proteje acceso a variables Utiliza patrones como ReaderWriterLockSlim Evita lock(this) No dejes hilos huerfanos Concurrency Visualizer for VS Consideraciones concurrencia
  13. 13. Enrique Catala - ecatala@solidq.com - @enriquecatala public void MethodWithLock() { lock (syncLock) { // código monothread } } ESTO NO SE HACE! Consideraciones concurrencia
  14. 14. 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); }
  15. 15. 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; }
  16. 16. 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(); } }
  17. 17. 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(); } }
  18. 18. 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
  19. 19. 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
  20. 20. 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); } });
  21. 21. 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); } }
  22. 22. 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
  23. 23. Enrique Catala - ecatala@solidq.com - @enriquecatala Almacenamiento in-memory Otro motor relacional Máximo rendimiento Compatibilidad Lock free
  24. 24. 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
  25. 25. 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/
  26. 26. • Evita procesados fila a fila Capas de acceso a datos • La estructura de datos importa, no es todo BBDD Complejidad 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
  27. 27. ecatala@solidq.com www.solidq.com @enriquecatala Gracias!!!

×