Pro Yearly is on sale from $80 to $50! »

Banco Relacional ou NoSQL para escalar Séries Temporais? Use o PostgreSQL. PgConf.Brasil.2019

Banco Relacional ou NoSQL para escalar Séries Temporais? Use o PostgreSQL. PgConf.Brasil.2019

Aplicações IoT podem gerar uma imensidão de dados e daí vem a pergunta: Como escalar? O banco de dados relacional é poderoso, porém não é especializado para escalar. Porém, com o PostgreSQL e o TimescaleDB é possível escalar de maneira simples, eficiente e eficaz. O TimescaleDB é uma extensão especializada para dados de séries temporais de código aberto otimizado para consultas rápidas e complexas. Ela fala 'SQL completo' e, de forma correspondente, é fácil de usar como um banco de dados relacional tradicional, além de escalar em formas anteriormente reservadas para bancos de dados NoSQL.

Dd1b94781c19e1b00b428a24f3741dd1?s=128

eriveltonvichroski

August 03, 2019
Tweet

Transcript

  1. Banco Relacional ou NoSQL para escalar Séries Temporais? Use o

    PostgreSQL. Erivelton Vichroski
  2. Globalcode – Open4education Agenda Motivação Time-series data? TimescaleDB e sua

    Arquitetura TimescaleDB vs PostgreSQL vs NoSQL Usando o TimescaleDB Considerações Finais Dúvidas
  3. Motivação

  4. Globalcode – Open4education Motivação: IoT IoT - Internet of Things;

    Como processar uma imensidão de dados de maneira escalável sem perder os benefícios do SQL? VLC; Dispositivos de consumo para casas inteligentes; etc. Crédito imagem: https://www.researchgate.net/figure/Outline-of-the-car-positioning-system-with-VLC_fig5_216680068
  5. Então, o que é time-series data?

  6. Globalcode – Open4education Time-series data? Principais características: Centralizado no tempo:

    os dados sempre têm um registro de data e hora; Append-only: os dados são quase exclusivamente anexados (INSERTs); São Recentes: os dados do passado são raramente alterados (Ausência de UPDATEs).
  7. Máquinas industriais Inferências AI & ML Energia Time-series data estão

    presentes em diversas áreas Eventos Web/mobile Transporte & Logistica Financeiro Data Center & DevOps
  8. Exemplo de time-series data Name Tags Data CPU Host=Name,Region=West 1990-01-01

    01:02:00 70 1990-01-01 01:03:00 71 1990-01-01 01:04:00 72 1990-01-01 01:04:00 73 1990-01-01 01:04:00 100
  9. Outro exemplo Name Tags Data CPU Host=Name,Region=West 1990-01-01 01:02:00 70

    1990-01-01 01:03:00 71 1990-01-01 01:04:00 72 1990-01-01 01:04:00 73 1990-01-01 01:04:00 100 FreeMem Host=Name,Region=West 1990-01-01 01:02:00 800M 1990-01-01 01:03:00 600M 1990-01-01 01:04:00 400M 1990-01-01 01:04:00 200M 1990-01-01 01:04:00 0 2 time-series?
  10. Têm estrutura rica Tags Data Host=Name,Region=West 1990-01-01 01:02:00 1990-01-01 01:03:00

    1990-01-01 01:04:00 1990-01-01 01:04:00 1990-01-01 01:04:00 CPU 70 71 72 73 100 MemFree 800M 600M 400M 200M 0 Temp 80 81 82 83 120
  11. Consultas simples select * where time = x Tags Data

    Host=Name,Region=West 1990-01-01 01:02:00 1990-01-01 01:03:00 1990-01-01 01:04:00 1990-01-01 01:04:00 1990-01-01 01:04:00 CPU 70 71 72 73 100 MemFree 800M 600M 400M 200M 0 Temp 80 81 82 83 120
  12. Filtros complexos select * where temp > 100 Tags Data

    Host=Name,Region=West 1990-01-01 01:02:00 1990-01-01 01:03:00 1990-01-01 01:04:00 1990-01-01 01:04:00 1990-01-01 01:04:00 CPU 70 71 72 73 100 MemFree 800M 600M 400M 200M 0 Temp 80 81 82 83 120
  13. Agregações Complexas avg(mem_free) group by (cpu/10) Tags Data Host=Name,Region=West 1990-01-01

    01:02:00 1990-01-01 01:03:00 1990-01-01 01:04:00 1990-01-01 01:04:00 1990-01-01 01:04:00 CPU 70 71 72 73 100 MemFree 800M 600M 400M 200M 0 Temp 80 81 82 83 120
  14. Correlações Como a temp correlaciona-se com a memfree? Tags Data

    Host=Name,Region=West 1990-01-01 01:02:00 1990-01-01 01:03:00 1990-01-01 01:04:00 1990-01-01 01:04:00 1990-01-01 01:04:00 CPU 70 71 72 73 100 MemFree 800M 600M 400M 200M 0 Temp 80 81 82 83 120
  15. Lookup de tags Data 1990-01-01 01:02:00 1990-01-01 01:03:00 1990-01-01 01:04:00

    1990-01-01 01:04:00 1990-01-01 01:04:00 CPU 70 71 72 73 100 Host 1 2 3 4 5 Region 91 91 93 93 95 Region é armazenada na “tabela de tags”
  16. Globalcode – Open4education Time-series data? Com responder as perguntas com

    eficiência? IoT: Como as leituras do sensor de temperatura estão mudando com o tempo? DevOps: Qual é o consumo de memória para cada um dos meus contêineres ontem? Real-Time: Quantos 500 errors cada um dos endpoints da minha API está retornando?
  17. Retenção de Dados + Agregações Granularidade . raw 15 min

    dia Retenção 1 semana 1 mês forever
  18. TimescaleDB

  19. Globalcode – Open4education TimescaleDB? Banco especializado para Time-series data; Open

    source - Apache 2.0 , TSL e Commercial; Primeira versão em JAN-2017. O que ele “vende”?
  20. Globalcode – Open4education TimescaleDB? Fácil de Usar; Escalável; Confiável.

  21. Globalcode – Open4education TimescaleDB? Fácil de Usar Interface SQL completa

    (é PostgreSQL) ; Conecta-se a qualquer cliente ou ferramenta que fale com o PostgreSQL; Recursos orientados a tempo, API e otimizações; Políticas robustas de retenção de dados.
  22. Globalcode – Open4education TimescaleDB? Escalável Particionamento de tempo e espaço

    são transparentes (scaling up - single node and scaling out); Elevadas taxas de escrita; Operações paralelizadas; 100 bilhões linhas / nó.
  23. Globalcode – Open4education TimescaleDB? Confiável Projetado a partir do PostgreSQL,

    empacotado como uma extensão; É PostgreSQL; Opções flexíveis de gerenciamento. (compatível com o ecossistema e ferramentas do PostgreSQL).
  24. Globalcode – Open4education TimescaleDB? Confiável Projetado a partir do PostgreSQL,

    empacotado como uma extensão; É PostgreSQL; Opções flexíveis de gerenciamento. (compatível com o ecossistema e ferramentas do PostgreSQL).
  25. Arquitetura

  26. Globalcode – Open4education Arquitetura O TimescaleDB é implementado como uma

    extensão no PostgreSQL; Migração do PostgreSQL para o Timescale é simples.
  27. Hypertable

  28. Dados mais antigos

  29. Dados mais antigos

  30. Dados mais antigos

  31. Particionamento Time-space (para ambos scaling up & out) Time (Dados

    mais antigos)
  32. Space Time (Dados mais antigos) (hash partitioning) Particionamento Time-space (para

    ambos scaling up & out)
  33. Chunk (sub-table) Space Time (Dados mais antigos) (hash partitioning) Particionamento

    Time-space (para ambos scaling up & out)
  34. Particionamento automático Time-space Chunks

  35. Chunks Particionamento automático Time-space

  36. Hypertable Abstraction Chunks Hypertable • Indexes • Triggers • Constraints

    • UPSERTs • Table mgmt Não exporta FK
  37. Retenção automática de dados SELECT add_drop_chunks_policy(hypertable, interval); SELECT drop_chunks(hypertable, interval);

  38. Diversas automatizações • Política da Ordenação • Política de Retenção

    • Política de Tiering • Política de Agregação Contínua
  39. Automatização de Agregação Contínua Granularidade . raw 15 min dia

    Retenção 1 semana 1 mês forever
  40. Com pg_prometheus TimescaleDB + PostgreSQL Prometheus Grafana

  41. Chunks

  42. Chunks são “right-sized” Chunks recentes (hot) cabem na memória RAM

  43. SELECT time, temp FROM data WHERE time > now() -

    interval ‘7 days AND device_id = ‘12345’ Evita querying chunks via exclusão de constraint
  44. Evita querying chunks via exclusão de constraint SELECT time, device_id,

    temp FROM data WHERE time > ‘2017-08-22 18:18:00+00’
  45. Evita querying chunks via exclusão de constraint SELECT time, device_id,

    temp FROM data WHERE time > now() - interval ’24 hours’ Plain PostgreSQL<12 não excluí chunks
  46. Políticas eficientes de retenção de dados SELECT time, device_id, temp

    FROM data WHERE time > now() - interval ’24 hours’ Drop chunks, ao invés de deletar linhas ⇒ Evita vacuuming
  47. Por que o relacional sofre para escalar?

  48. Time-series Principalmente UPDATEs Escritas randomicamente distribuídas • Transações para múltiplas

    primary keys Principalmente INSERTs Escritas para o intervalo de tempo recente Escritas associadas com um timestamp e primary key OLTP
  49. Postgres 9.6.2 on Azure standard DS4 v2 (8 cores), SSD

    (premium LRS storage) Each row has 12 columns (1 timestamp, indexed 1 host ID, 10 metrics)
  50. Postgres 9.6.2 on Azure standard DS4 v2 (8 cores), SSD

    (premium LRS storage) Each row has 12 columns (1 timestamp, indexed 1 host ID, 10 metrics)
  51. O custo de manter a B-tree no Insert 1 1

    20 20 10 10 1 1 10 10 13 4 13 4 24 24 29 29 25 25 5 5 Insert batch: 17 17 8 8 Capacidade Memória: 2 NÓS EM MEMÓRIA ESCRITA EM DISCO
  52. O custo de manter a B-tree no Insert 1 1

    20 20 10 10 1 1 10 10 13 4 13 4 24 24 29 29 25 25 5 5 Insert batch: 17 17 8 8 Capacidade memória: 2 NÓS EM MEMÓRIA ESCRITA EM DISCO
  53. 1 1 20 20 10 10 1 1 10 10

    13 4 13 4 24 24 29 29 25 25 Insert batch: 8 8 5 5 17 17 O custo de manter a B-tree no Insert Capacidade memória: 2 NÓS EM MEMÓRIA ESCRITA EM DISCO
  54. 10 10 13 4 13 4 O custo de manter

    a B-tree no Insert 1 1 20 20 10 10 1 1 24 24 29 29 25 25 Insert batch: 8 8 5 5 17 17 Capacidade memória: 2 NÓS EM MEMÓRIA ESCRITA EM DISCO
  55. O desafio de escalar • Índices escrevem de forma randômica

    na B-tree – Examplo: BTREE(device_id, time DESC) • Portanto, em tabelas gigantes teremos: – Índices não cabem na memória – Escritas para locais aleatórios da B-tree – Causa swapping Device: A Time: 01:01:01 Device: Z Time: 01:01:01 Device, Time DESC
  56. Globalcode – Open4education Como o TimescaleBD diz que resolve? Chunk

    = sub-tabela interna; O tamanho do índice ↔ tamanho de cada chunk; As inserções ocorrem nos chunks mas recentes. (cabe na memória e evita acesso ao disco)
  57. Scaling Up & Scale Out

  58. Single node: Scaling up via adição de discos • Inserts

    +rápidos • Paralelização de queries Como Benefícios Chunks espalhados em muitos discos (elastically!) com RAID or via tablespaces distintos
  59. Globalcode – Open4education Scaling Out TimescaleDB suporta streaming replication integrada

    ao PostgreSQL; Não é recomendável usar a replicação lógica.
  60. Globalcode – Open4education Scaling Out TimescaleDB suporta streaming replication integrada

    ao PostgreSQL; Não é recomendável usar a replicação lógica.
  61. Globalcode – Open4education Scaling Out

  62. Globalcode – Open4education Scaling Out

  63. TimescaleDB x PostgreSQL

  64. Simples de começar com a Hipertable CREATE TABLE conditions (

    time timestamptz, temp float, humidity float, device text ); SELECT create_hypertable('conditions', 'time', ‘device', 4, chunk_time_interval => interval '1 week’); INSERT INTO conditions VALUES ('2017-10-03 10:23:54+01', 73.4, 40.7, 'sensor3'); SELECT * FROM conditions; time | temp | humidity | device ------------------------+------+----------+--------- 2017-10-03 11:23:54+02 | 73.4 | 40.7 | sensor3
  65. — Set new chunk time interval SELECT set_chunk_time_interval('conditions', interval '24

    hours’); — Set new number of space partitions SELECT set_number_partitions('conditions', 6); Reparticionamento é simples
  66. PG doesn’t know to use the index Otimização de queries

    CREATE INDEX ON readings(time); SELECT date_trunc(‘minute’, time) as bucket, avg(cpu) FROM readings GROUP BY bucket ORDER BY bucket DESC LIMIT 10; Timescale tem funcões para time
  67. Globalcode – Open4education TimescaleDB x PostgreSQL Não é verdade para

    o PosgreSQL12
  68. Globalcode – Open4education TimescaleDB x PostgreSQL Não é verdade para

    o PosgreSQL12
  69. Globalcode – Open4education TimescaleDB x PostgreSQL 12 Crédito imagem: Simon

    Riggs, 2ndQuadrant.
  70. TimescaleDB x NoSQL

  71. Simplicidade de stack VS TimescaleDB (com JOINS) RDBMS NoSQL Aplicações

    Aplicações
  72. Globalcode – Open4education TimescaleDB x NoSQL NoSQL + LSMTs(Log Structured

    MergeTree) têm seu “custo” para time-series: Consultas complexas são menos poderosas; Ausência de JOINS; Perda do ecossistema SQL.
  73. Armazenamento de valor-chave com pesquisa de chave indexada tem elevadas

    taxas de escritas NoSQL é campeão: Log-Structured Merge Trees + • Compactação de dados • Abordagem comum para time- series: use key <name, tags, field, time>
  74. Log-Structured Merge Tree 5 5 Insert batch: 17 17 8

    8 Memtable 1 3 4 5 7 9 10 1 3 4 5 7 9 10 1 2 3 5 7 9 10 11 1 2 3 5 7 9 10 11 sstables Older
  75. Insert batch: 8 17 5 8 17 5 Memtable 1

    3 4 5 7 9 10 1 3 4 5 7 9 10 1 2 3 5 7 9 10 11 1 2 3 5 7 9 10 11 sstables Older Log-Structured Merge Tree
  76. Log-Structured Merge Tree Insert batch: Memtable 1 3 4 5

    7 9 10 1 3 4 5 7 9 10 1 2 3 5 7 9 10 11 1 2 3 5 7 9 10 11 sstables Older 5 8 17 5 8 17
  77. Problemas com consultas não-KV Se buscar a key 5: Para

    depois de encontrá-lo no primeiro sstable 1 3 4 5 7 9 10 1 3 4 5 7 9 10 1 2 3 5 7 9 10 11 1 2 3 5 7 9 10 11 sstables Dados mais antigos 5 8 17 5 8 17 Se buscar por dados no intervalo de 5-10: É necessário scan em todas sstables Requer estruturas de dados (em memória) para mapear tags para keys Problema de cardinalidade alta ⇒ Prob
  78. Quando o TimescaleDB não é eficiente?

  79. Globalcode – Open4education Quando não usar o TimescaleDB?

  80. Globalcode – Open4education Usando o TimescaleDB Algumas demonstrações:

  81. Globalcode – Open4education Usando o TimescaleDB Instalação: root@tdc18-timescaledb ~]# sudo

    yum install timescaledb postgresql.conf: shared_preload_libraries = 'timescaledb' [postgres@tdc18-timescaledb data]$ psql -d benchmark psql (10.3) Digite "help" para ajuda. benchmark=#CREATE EXTENSION timescaledb;
  82. Globalcode – Open4education Usando o TimescaleDB Criar uma hypertable: CREATE

    TABLE conditions ( time timestamptz NOT NULL, temp float, humidity float, device text ); SELECT create_hypertable('conditions', 'time', 'device', 4, chunk_time_interval => interval '1 week'); INSERT INTO conditions VALUES ('2017-10-03 10:23:54+01', 73.4, 40.7, 'sensor3'); SELECT * FROM conditions; time | temp | humidity | device -----------------------+------+----------+--------- 2017-10-03 11:23:54+02 | 73.4 | 40.7 | sensor3
  83. Globalcode – Open4education Usando o TimescaleDB Mantenção automática da hypertable:

    teste=# SELECT chunk_id,ranges FROM chunk_relation_size_pretty('conditions'); chunk_id | ranges +---------------------------------------------------------------------------------- 1 | {"['2017-09-27 21:00:00-03','2017-10-04 21:00:00... teste=# INSERT INTO conditions VALUES ('2017-10-11 10:23:54+01', 73.4, 40.7, 'sensor3' teste=# SELECT chunk_id,ranges FROM chunk_relation_size_pretty('conditions'); chunk_id | ranges +---------------------------------------------------------------------------------- 1 | {"['2017-09-27 21:00:00-03','2017-10-04 21:00:00... 2 | {"['2017-10-04 21:00:00-03','2017-10-11 21:00:00...
  84. Globalcode – Open4education Usando o TimescaleDB Explain – Exclusão de

    constraints timescale=# explain SELECT date_trunc('day', pickup_datetime) as day, avg(fare_amount) FROM rides WHERE passenger_count > 1 AND pickup_datetime < '2016-01-08' GROUP BY day ORDER BY day; QUERY PLAN ------------------------------------------------------------------------------------------------------------------------------------------------------------------------- ----------------- Finalize GroupAggregate (cost=111571.10..111623.77 rows=200 width=40) Group Key: (date_trunc('day'::text, _hyper_1_6_chunk.pickup_datetime)) -> Gather Merge (cost=111571.10..111617.77 rows=400 width=40) Workers Planned: 2 -> Sort (cost=110571.08..110571.58 rows=200 width=40) Sort Key: (date_trunc('day'::text, _hyper_1_6_chunk.pickup_datetime)) -> Partial HashAggregate (cost=110560.43..110563.43 rows=200 width=40) Group Key: date_trunc('day'::text, _hyper_1_6_chunk.pickup_datetime) -> Result (cost=0.43..109061.13 rows=299860 width=13) -> Parallel Append (cost=0.43..105312.88 rows=299860 width=13) -> Parallel Index Scan using _hyper_1_6_chunk_rides_passenger_count_pickup_datetime_idx on _hyper_1_6_chunk (cost=0.43..35457.47 rows=28315 width=13) Index Cond: ((passenger_count > '1'::numeric) AND (pickup_datetime < '2016-01-08 00:00:00'::timestamp without time zone)) -> Parallel Index Scan using _hyper_1_2_chunk_rides_passenger_count_pickup_datetime_idx on _hyper_1_2_chunk (cost=0.43..29349.27 rows=148788 width=13) Index Cond: ((passenger_count > '1'::numeric) AND (pickup_datetime < '2016-01-08 00:00:00'::timestamp without time zone)) -> Parallel Index Scan using _hyper_1_1_chunk_rides_passenger_count_pickup_datetime_idx on _hyper_1_1_chunk (cost=0.42..20122.63 rows=107501 width=13) Index Cond: ((passenger_count > '1'::numeric) AND (pickup_datetime < '2016-01-08 00:00:00'::timestamp without time zone)) -> Parallel Index Scan using _hyper_1_5_chunk_rides_passenger_count_pickup_datetime_idx on _hyper_1_5_chunk (cost=0.42..18884.21 rows=15256 width=13) Index Cond: ((passenger_count > '1'::numeric) AND (pickup_datetime < '2016-01-08 00:00:00'::timestamp without time zone))
  85. Dúvidas? eriveltonvichroski@gmail.com