Speaker : Bruno Bonnin - @_bruno_b_
Stream processing et SQL
GDPR
Data Governance
Data Fabric
Streams
Sources:
● IoT
● Monitoring
● Click streams
● Finance
● Jeux en ligne
● ...
Flot continue et sans fin
de données
Largement adopté par tous (même si on peut/veut l’éviter…)
○ Développeur
○ Architecte data
○ Data scientist
○ Et des beaucoup moins techniques !!
Pourquoi SQL in 2018 ?
C’est un standard !
Les streams sont des données comme les autres !
Alors pourquoi ne pas utiliser SQL pour
les requêter ?
SQL vs. Stream processing
Relational Algebra / SQL Stream Processing
Relations (or tables) are bounded
(multi-)sets of tuples.
A stream is an infinite sequences of
tuples.
A query that is executed on batch data
(e.g., a table in a relational database)
has access to the complete input data.
A streaming query cannot access
all data when is started and has to
"wait" for data to be streamed in.
A batch query terminates after it
produced a fixed sized result.
A streaming query continuously
updates its result based on the
received records and never
completes.
Source: https://ci.apache.org/projects/flink/flink-docs-release-1.6/dev/table/streaming.html
Requêter en SQL un stream ?
weblogs
url status
/help 200
Compter les nombres
de requêtes pour
chaque URL
/help 1
/help 1
/products 1
/help 1
/products 2
/products 200
/products 500
Réception ➜ Traitement ➜ Mise à jour du résultat
SELECT
url,
count(*) as nb_req
FROM
weblogs
GROUP BY
url
SQL et Stream processing
Apache Calcite
Apache Calcite
● Catalogue des metadatas
● Parsing SQL
● Validation des requêtes SQL
● Optimisation des requêtes SQL
○ Plan d’exécution
● Adaptateurs pour différentes sources de données (MongoDB, Elastic, …)
Pour les streams: définition d’un minimum de mots-clés
et de fonctions pour les requêter
L’exécution des requêtes est à la charge du système utilisant
Calcite
THE keyword !
SELECT STREAM * FROM weblogs;
weblogs est un stream
Requêtes ne se terminant pas
Sur quelles données ? de maintenant à ...
SELECT STREAM url, status_code, nb_bytes FROM weblogs;
SELECT STREAM url, nb_bytes FROM weblogs WHERE status = 500;
Jointure avec une table
Et si la table bouge ?
Une solution: stocker
l’historique dans la table
pour l’utiliser dans la
requête
SELECT STREAM cmd.id_pizza, piz.prix
FROM commandes_pizza AS cmd
JOIN pizzas AS piz
ON cmd.id_pizza = piz.id_pizza;
Simple pour une table qui
ne change pas
SELECT STREAM cmd.id_pizza, piz.prix
FROM commandes_pizza AS cmd
JOIN pizzas AS piz
ON cmd.id_pizza = piz.id_pizza
AND cmd.rowtime
BETWEEN piz.dateDebut AND piz.dateFin;
Windowing
sum() 3 12 13 8
Tumbling window
SELECT STREAM
TUMBLE_END(rowtime, INTERVAL '10' SECOND),
url,
SUM(nb_bytes) AS total_bytes
FROM weblogs
GROUP BY TUMBLE(rowtime, INTERVAL '10' SECOND), url;
1
2 3
5
4 6
7
8
t
0 10 20 30 40
Windowing
Hopping window
SELECT STREAM
HOP_END(rowtime, INTERVAL '10' SECOND, INTERVAL '15' SECOND)
AS rowtime,
SUM(nb_bytes) AS total_bytes
FROM weblogs
GROUP BY
HOP(rowtime, INTERVAL '10' SECOND, INTERVAL '15' SECOND);
sum() 6 18 21 17
1
2 3
5
4
6
7
8
t
0 10 20 30 40
9
Démo
https://github.com/bbonnin/talk-stream-processing-et-sql
Flink: en mode API
val table = tableEnv
.fromDataStream(datastream,
'ts, 'ip_address, 'url, 'status, 'nb_bytes,
'rowtime.rowtime)
.window(
Tumble over 10.second on 'rowtime as 'tenSecWindow)
.groupBy('tenSecWindow, 'url)
.select(
'url,
'tenSecWindow.end as 'time,
'url.count as 'nb_requests)
tableEnv.toAppendStream[Row](table)...
execEnv.execute()
Flink: en mode SQL (que préférez-vous ?)
tableEnv.registerDataStream("weblogs", datastream,
'ts, 'ip_address, 'url, 'status, 'nb_bytes,
'rowtime.rowtime)
val query = """
| SELECT url,
| TUMBLE_END(rowtime, INTERVAL '10' SECOND),
| COUNT(*) AS nb_requests
| FROM weblogs
| GROUP BY TUMBLE(rowtime, INTERVAL '10' SECOND), url
""".stripMargin
val table = tableEnv.sqlQuery(query)
tableEnv.toAppendStream[Row](table)...
execEnv.execute()
L’exemple Uber: Athenax
The mission of Uber is to make transportation as reliable as running
water. The business is fundamentally driven by real-time data — more
than half of the employees in Uber, many of whom
are non-technical, use SQL on a regular basis to
analyze data and power their business decisions. We are building
AthenaX, a stream processing platform built on top of Apache
Flink to enable our users to write SQL to process
real-time data efficiently and reliably at Uber’s scale.
“
”
L’exemple Uber: Athenax
- Plateforme
permettant de
créer/déployer des
traitements temps
réel basés sur du
SQL
- Basée sur Flink
Open sourcé en 2017: https://github.com/uber/AthenaX
Conclusion
« A l'horizon 2020, 70 % des organisations et des entreprises adopteront le streaming des
données pour permettre des analyses en temps réel » (Gartner)
Alors, n’oubliez pas les personnes qui vont “développer”
les traitements.
Le SQL permet de réunir tous les acteurs
autour d’un outil commun pour traiter les
données, streams ou pas !
Apache Calcite offre beaucoup d’autres possibilités comme les
jointures entre streams, update/delete/insert, … tout n’est pas implémenté !
Mais le but est de faire avancer le standard SQL.
Même Jack Ryan sauve le monde avec du SQL...
Merci !
@_bruno_b_
#JugSummerCamp
Group by, order by: quelques contraintes
SELECT STREAM status, count(*)
FROM weblogs
GROUP BY status;
Non autorisé par Calcite
Le GROUP BY doit inclure une valeur monotone
(par ex, rowtime)
SELECT STREAM status, count(*)
FROM weblogs
GROUP BY rowtime, status;
Storm
Sources de
données
Topologie Storm (= app)
spout 1
bolt 4
spout 2
bolt 1 bolt 2
bolt 3
Cluster Storm
topo1
topo2 topo4
topo3
tuple tuple
Storm SQL
CREATE EXTERNAL TABLE weblogs
(ID INT PRIMARY KEY, TS BIGINT, IP_ADDRESS VARCHAR,
URL VARCHAR, STATUS INT, NB_BYTES INT)
LOCATION 'kafka://localhost:2181/brokers?topic=weblogs'
CREATE EXTERNAL TABLE errorlogs
(ID INT PRIMARY KEY, TS BIGINT, URL VARCHAR,
STATUS INT, NB_BYTES INT)
LOCATION 'kafka://localhost:2181/brokers?topic=errorlogs'
TBLPROPERTIES
'{"producer":{"bootstrap.servers":"localhost:9092","acks":"1",
"key.serializer":"org.apache.storm.kafka.IntSerializer",
"value.serializer":"org.apache.storm.kafka.ByteBufferSerializer"
}}'
INSERT INTO errorlogs
SELECT ID, TS, URL, STATUS, NB_BYTES
FROM weblogs
WHERE STATUS >= 400
Kafka
spout
Filtre
erreurs
Kafka
producer
tupletuple
Storm SQL
Logical Plan
Table Scan
Filter
Projection
Table Modify
Physical Plan
Storm Spout
Filter
Projection
Storm Sink
INSERT INTO errorlogs
SELECT
ID, TS, URL, STATUS,
NB_BYTES
FROM weblogs
WHERE STATUS >= 400
topo.newStream()
.filter(...)
.projection(...)
.persist(...)
On retrouve Apache Calcite à
peu près par là (construction du
plan d’exécution logique)

Stream processing et SQL

  • 1.
    Speaker : BrunoBonnin - @_bruno_b_ Stream processing et SQL
  • 2.
  • 3.
    Streams Sources: ● IoT ● Monitoring ●Click streams ● Finance ● Jeux en ligne ● ... Flot continue et sans fin de données
  • 4.
    Largement adopté partous (même si on peut/veut l’éviter…) ○ Développeur ○ Architecte data ○ Data scientist ○ Et des beaucoup moins techniques !! Pourquoi SQL in 2018 ? C’est un standard ! Les streams sont des données comme les autres ! Alors pourquoi ne pas utiliser SQL pour les requêter ?
  • 5.
    SQL vs. Streamprocessing Relational Algebra / SQL Stream Processing Relations (or tables) are bounded (multi-)sets of tuples. A stream is an infinite sequences of tuples. A query that is executed on batch data (e.g., a table in a relational database) has access to the complete input data. A streaming query cannot access all data when is started and has to "wait" for data to be streamed in. A batch query terminates after it produced a fixed sized result. A streaming query continuously updates its result based on the received records and never completes. Source: https://ci.apache.org/projects/flink/flink-docs-release-1.6/dev/table/streaming.html
  • 6.
    Requêter en SQLun stream ? weblogs url status /help 200 Compter les nombres de requêtes pour chaque URL /help 1 /help 1 /products 1 /help 1 /products 2 /products 200 /products 500 Réception ➜ Traitement ➜ Mise à jour du résultat SELECT url, count(*) as nb_req FROM weblogs GROUP BY url
  • 7.
    SQL et Streamprocessing Apache Calcite
  • 8.
    Apache Calcite ● Cataloguedes metadatas ● Parsing SQL ● Validation des requêtes SQL ● Optimisation des requêtes SQL ○ Plan d’exécution ● Adaptateurs pour différentes sources de données (MongoDB, Elastic, …) Pour les streams: définition d’un minimum de mots-clés et de fonctions pour les requêter L’exécution des requêtes est à la charge du système utilisant Calcite
  • 9.
    THE keyword ! SELECTSTREAM * FROM weblogs; weblogs est un stream Requêtes ne se terminant pas Sur quelles données ? de maintenant à ... SELECT STREAM url, status_code, nb_bytes FROM weblogs; SELECT STREAM url, nb_bytes FROM weblogs WHERE status = 500;
  • 10.
    Jointure avec unetable Et si la table bouge ? Une solution: stocker l’historique dans la table pour l’utiliser dans la requête SELECT STREAM cmd.id_pizza, piz.prix FROM commandes_pizza AS cmd JOIN pizzas AS piz ON cmd.id_pizza = piz.id_pizza; Simple pour une table qui ne change pas SELECT STREAM cmd.id_pizza, piz.prix FROM commandes_pizza AS cmd JOIN pizzas AS piz ON cmd.id_pizza = piz.id_pizza AND cmd.rowtime BETWEEN piz.dateDebut AND piz.dateFin;
  • 11.
    Windowing sum() 3 1213 8 Tumbling window SELECT STREAM TUMBLE_END(rowtime, INTERVAL '10' SECOND), url, SUM(nb_bytes) AS total_bytes FROM weblogs GROUP BY TUMBLE(rowtime, INTERVAL '10' SECOND), url; 1 2 3 5 4 6 7 8 t 0 10 20 30 40
  • 12.
    Windowing Hopping window SELECT STREAM HOP_END(rowtime,INTERVAL '10' SECOND, INTERVAL '15' SECOND) AS rowtime, SUM(nb_bytes) AS total_bytes FROM weblogs GROUP BY HOP(rowtime, INTERVAL '10' SECOND, INTERVAL '15' SECOND); sum() 6 18 21 17 1 2 3 5 4 6 7 8 t 0 10 20 30 40 9
  • 13.
  • 14.
    Flink: en modeAPI val table = tableEnv .fromDataStream(datastream, 'ts, 'ip_address, 'url, 'status, 'nb_bytes, 'rowtime.rowtime) .window( Tumble over 10.second on 'rowtime as 'tenSecWindow) .groupBy('tenSecWindow, 'url) .select( 'url, 'tenSecWindow.end as 'time, 'url.count as 'nb_requests) tableEnv.toAppendStream[Row](table)... execEnv.execute()
  • 15.
    Flink: en modeSQL (que préférez-vous ?) tableEnv.registerDataStream("weblogs", datastream, 'ts, 'ip_address, 'url, 'status, 'nb_bytes, 'rowtime.rowtime) val query = """ | SELECT url, | TUMBLE_END(rowtime, INTERVAL '10' SECOND), | COUNT(*) AS nb_requests | FROM weblogs | GROUP BY TUMBLE(rowtime, INTERVAL '10' SECOND), url """.stripMargin val table = tableEnv.sqlQuery(query) tableEnv.toAppendStream[Row](table)... execEnv.execute()
  • 16.
    L’exemple Uber: Athenax Themission of Uber is to make transportation as reliable as running water. The business is fundamentally driven by real-time data — more than half of the employees in Uber, many of whom are non-technical, use SQL on a regular basis to analyze data and power their business decisions. We are building AthenaX, a stream processing platform built on top of Apache Flink to enable our users to write SQL to process real-time data efficiently and reliably at Uber’s scale. “ ”
  • 17.
    L’exemple Uber: Athenax -Plateforme permettant de créer/déployer des traitements temps réel basés sur du SQL - Basée sur Flink Open sourcé en 2017: https://github.com/uber/AthenaX
  • 18.
    Conclusion « A l'horizon2020, 70 % des organisations et des entreprises adopteront le streaming des données pour permettre des analyses en temps réel » (Gartner) Alors, n’oubliez pas les personnes qui vont “développer” les traitements. Le SQL permet de réunir tous les acteurs autour d’un outil commun pour traiter les données, streams ou pas ! Apache Calcite offre beaucoup d’autres possibilités comme les jointures entre streams, update/delete/insert, … tout n’est pas implémenté ! Mais le but est de faire avancer le standard SQL.
  • 19.
    Même Jack Ryansauve le monde avec du SQL...
  • 20.
  • 21.
    Group by, orderby: quelques contraintes SELECT STREAM status, count(*) FROM weblogs GROUP BY status; Non autorisé par Calcite Le GROUP BY doit inclure une valeur monotone (par ex, rowtime) SELECT STREAM status, count(*) FROM weblogs GROUP BY rowtime, status;
  • 22.
    Storm Sources de données Topologie Storm(= app) spout 1 bolt 4 spout 2 bolt 1 bolt 2 bolt 3 Cluster Storm topo1 topo2 topo4 topo3 tuple tuple
  • 23.
    Storm SQL CREATE EXTERNALTABLE weblogs (ID INT PRIMARY KEY, TS BIGINT, IP_ADDRESS VARCHAR, URL VARCHAR, STATUS INT, NB_BYTES INT) LOCATION 'kafka://localhost:2181/brokers?topic=weblogs' CREATE EXTERNAL TABLE errorlogs (ID INT PRIMARY KEY, TS BIGINT, URL VARCHAR, STATUS INT, NB_BYTES INT) LOCATION 'kafka://localhost:2181/brokers?topic=errorlogs' TBLPROPERTIES '{"producer":{"bootstrap.servers":"localhost:9092","acks":"1", "key.serializer":"org.apache.storm.kafka.IntSerializer", "value.serializer":"org.apache.storm.kafka.ByteBufferSerializer" }}' INSERT INTO errorlogs SELECT ID, TS, URL, STATUS, NB_BYTES FROM weblogs WHERE STATUS >= 400 Kafka spout Filtre erreurs Kafka producer tupletuple
  • 24.
    Storm SQL Logical Plan TableScan Filter Projection Table Modify Physical Plan Storm Spout Filter Projection Storm Sink INSERT INTO errorlogs SELECT ID, TS, URL, STATUS, NB_BYTES FROM weblogs WHERE STATUS >= 400 topo.newStream() .filter(...) .projection(...) .persist(...) On retrouve Apache Calcite à peu près par là (construction du plan d’exécution logique)