SlideShare ist ein Scribd-Unternehmen logo
1 von 58
Node.js Connector
Diego DUPIN
MariaDB Connector Engineer
MariaDB Corporation
PROGRAM
- Getting started
- Best practice
- Advanced topic
- ORM
NODE.JS CONNECTORS
Existing community connectors
● mysqljs/mysql (npm mysql)
(+ Promise-mysql to have promise)
● sidorares/node-mysql2 (npm mysql2)
● mscdex/node-mariasql (npm mariasql)
New connector
● MariaDB/mariadb-connector-nodejs (npm
mariadb)
WHY A NEW CONNECTOR
● New functionalities
● Better performance
Benchmark : “SELECT * FROM mysql.user LIMIT 1” on local DB
Getting started
QUICK START - INSTALLATION
through npm.
$ npm install mariadb
To use the Connector, you need to import the package into your application code.
const mariadb = require('mariadb'); //promise implementation
or
const mariadb = require('mariadb/callback'); //callback implementation
QUICK START - CONNECTION
Promise
const mariadb = require("mariadb");
mariadb.createConnection({
user: "root",
database: "db",
host: "localhost",
port: 3306
})
.then(conn => {
console.log("Connected successful");
conn.end();
})
.catch(err => {
console.log("Error: " + err.message);
});
const mariadb = require("mariadb/callback");
const conn = mariadb.createConnection({
user: "root",
database: "db",
host: "localhost",
port: 3306
});
conn.connect(err => {
if (err) {
console.log("Error: " + err.message);
} else {
console.log("Connected successful");
conn.end();
}
});
Callback
QUICK START - INSERT
conn.query(
"CREATE TEMPORARY TABLE myTable " +
"(id int NOT NULL AUTO_INCREMENT, firstName varchar(256), lastName varchar(256), " +
" PRIMARY KEY (id))"
)
.then(() => {
return conn.query("INSERT INTO myTable(firstName, lastName) VALUES (?, ?)", [
"john",
"smith"
]);
})
.then(res => {
console.log(res); //{ affectedRows: 1, insertId: 1, warningStatus: 0 }
conn.end();
})
.catch(err => { });
QUICK START - SELECT
conn.query(
"SELECT ID,COLLATION_NAME FROM INFORMATION_SCHEMA.COLLATIONS " +
"WHERE CHARACTER_SET_NAME = ? LIMIT 2",
["utf8mb4"]
)
.then(res => {
console.log(res);
/* resultset is an array of rows, represented by JSON object
[
{ ID: 45, COLLATION_NAME: 'utf8mb4_general_ci' },
{ ID: 46, COLLATION_NAME: 'utf8mb4_bin' }
]
*/
conn.end();
})
.catch(err => { … });
CONNECTION ESSENTIAL API
● connection.query(sql[, values]) → Promise: Executes a query.
● connection.queryStream(sql[, values]) → Emitter: Executes a query, streaming results.
● connection.batch(sql, values) → Promise: fast batch processing.
● connection.beginTransaction() → Promise: Begins a transaction.
● connection.commit() → Promise: Commits the current transaction, if any.
● connection.rollback() → Promise: Rolls back the current transaction, if any.
● connection.ping() → Promise: Sends a 1 byte packet to the database to validate the connection.
● connection.end() → Promise: Gracefully close the connection.
SSL
SSL
One-Way SSL Authentication or Two-Way SSL Authentication
const fs = require("fs");
const mariadb = require('mariadb');
//reading certificates from file
const serverCert = [fs.readFileSync("server.pem", "utf8")];
//connecting
mariadb
.createConnection({
user: "myUser",
host: "myHost.com",
ssl: {
ca: serverCert
}
}).then(conn => {})
Pooling
POOLING
Basically a database connection cache implementation
Connections are expensive. On local DB:
● 2.4ms for a basic connection
● 0.05ms for a simple query
Problem : correctness and reliability
POOLING
Event implementation
- Pool handle new connection creation one by one
- New connection are added to idle connection queue
On connection failure:
- Pool revalidate all other connections
- Continue creating new connections creation one by one
Connection request are queued separately
Idle
Connections
POOLING
Connection request
Idle
ConnectionsConnection request
Connection request
Request
queue
POOLING
- Implementation to handle query pikes
Example with a pool that is configured to have a maximum of 50 connections. actual
connection number is 5.
With a basis of a connection creation taking 2.4ms, and query taking 0.05ms (example
on a local server).
Everything is quiet, and then ... Boom! ... 100 queries on the pool at once, wanting a
connection.
POOLING
POOLING
POOLING
Connection pools SIZING error
Example 10 000 user simultaneously, 20 000 transaction per second.
What value to connectionLimit (max connection number in pool) ?
100 ? 500 ? 1000 ?
POOLING - CONFIGURATION
acquireTimeout
t
acquireTimeout Timeout to get a new connection from pool.
Maximum number of connection in pool.
Delay to avoid connection validation
Disabling connection control
connectionLimit
minDelayValidation
noControlAfterUse
POOL API
● pool.getConnection() → Promise : Creates a new connection.
● pool.query(sql[, values]) → Promise: Executes a query.
● pool.batch(sql, values) → Promise: Executes a batch
Stats
● pool.activeConnections() → Number: Gets current active connection number.
● pool.totalConnections() → Number: Gets current total connection number.
● pool.idleConnections() → Number: Gets current idle connection number.
● pool.taskQueueSize() → Number: Gets current stacked request.
POOLING - CONFIGURATION
const pool = mariadb.createPool({ user: "root", database: "testn", host: "localhost", port: 3306,
sessionVariables: { wait_timeout: 31536000 },
acquireTimeout: 5000, connectionLimit: 8,
});
pool
.getConnection()
.then(conn => {
console.log("Connected successfully to server");
conn.release();
})
.catch(err => {
console.log("Error during connection: " + err.message);
});
Server expect connection to be used (@wait_timeout)
MULTI-SERVER
MULTI-HOST - ESSENTIAL API
“Cluster” offer handle multiple pools permitting load balancing and high availability
const mariadb = require("mariadb");
const cluster = mariadb.createPoolCluster();
cluster.add("master", { host: "mydb1.com", ... });
cluster.add("slave1", { host: "mydb2.com", ... });
cluster.add("slave2", { host: "mydb3.com", ... });
cluster
.getConnection("slave*", "RR") //RR: ROUND-ROBIN
.then(conn => { })
.catch(err => { });
MULTI-HOST - ESSENTIAL API
client
Master
Slave B
Slave A
Cluster.getConnection("slave*", "RR")
MULTI-HOST - ESSENTIAL API
client
Master
Slave B
Slave A
Cluster.getConnection("slave*", "RR")
MULTI-HOST - ESSENTIAL API
client
Master
Slave B
Slave A
Cluster.getConnection("slave*", "RR")
MULTI-HOST - ESSENTIAL API
client
Master
Slave B
Slave A
Cluster.getConnection("slave*", "RR")
MULTI-HOST - ESSENTIAL API
client
Master
Slave B
Slave A
Cluster.getConnection("slave*", "RR")
MULTI-HOST - ESSENTIAL API
client
Master
Slave B
Slave A
Cluster.getConnection("slave*", "RR")
MULTI-HOST
SELECTORS
● RR (round-robin)
● RANDOM
● ORDER
MULTI-HOST - ESSENTIAL API
● poolCluster.add(id, config) : add a pool to cluster.
● poolCluster.remove(pattern) : remove and end pool according to pattern.
● poolCluster.end() → Promise : end cluster.
● poolCluster.getConnection(pattern, selector) → Promise : return a connection from
cluster.
● poolCluster.of(pattern, selector) → FilteredPoolCluster : return a subset of cluster.
MULTI-HOST - ESSENTIAL API
poolCluster.of(pattern, selector) → FilteredPoolCluster : return a subset of cluster.
const cluster = mariadb.createPoolCluster();
cluster.add("master", { host: "mydb1.com", ... });
cluster.add("slave1", { host: "mydb2.com", ... });
cluster.add("slave2", { host: "mydb3.com", ... });
const slaves = cluster.of(/^slave?/, 'RANDOM');
slaves.getConnection().then( ... );
slaves.query(sql, values).then( ... );
slaves.batch(sql, values).then( ... );
New features
Pipelining
PIPELINING
Pipelining is a technique in which
multiple requests are sent on a single
TCP connection without waiting for the
corresponding responses.
This saves round trip time.
PIPELINING - without
const uuid = uuidv1(); //generate new UUID
conn
.beginTransaction()
.then(() => {
return conn.query("INSERT INTO basket(basketId) values (?)", uuid);
})
.then(() => {
return conn.query(
"INSERT INTO basket_item(basketId, itemId) VALUES (?, ?)",
[ uuid, 100 ]);
})
.then(() => {
return conn.query(
"INSERT INTO basket_item(basketId, itemId) VALUES (?, ?)",
[ uuid, 101 ]);
})
.then(() => { conn.commit(); })
.catch(err => { conn.rollback(); });
PIPELINING - with
const uuid = uuidv1(); //generate new UUID
conn
.beginTransaction()
.then(() => {
return Promise.all([
conn.query("INSERT INTO basket(basketId) values (?)", uuid),
conn.query(
"INSERT INTO basket_item(basketId, itemId) VALUES (?, ?)",
[uuid, 100]),
conn.query(
"INSERT INTO basket_item(basketId, itemId) VALUES (?, ?)",
[uuid, 101])
]);
})
.then(() => { conn.commit(); })
.catch(err => { conn.rollback(); });
PIPELINING
Local DB:
abuse : socket buffering
Streaming
Streaming
Goal : Avoid loading all in memory
● Streaming resultset -> avoiding loading large resultset totally into memory
○ By event
○ With pipe
● Streaming sent -> sending buffer by chunk
Streaming resultset
BY EVENT :
Limitations :
● Server net_write_timeout.
○ For a command: SET STATEMENT net_write_timeout=10000 FOR XXX
○ For a connection: sessionVariables: { net_write_timeout: 31536000 }
connection
.queryStream("SELECT * FROM mysql.user")
.on("error", err => {})
.on("fields", meta => {})
.on("data", row => {})
.on("end", () => {});
Streaming resultset
USING PIPE : const someWriterStream = fs.createWriteStream("./jsonUsers.txt");
const transformStream = new stream.Transform({
objectMode: true,
transform: function transformer(chunk, encoding, callback) {
callback(null, JSON.stringify(chunk));
}
});
const queryStream = connection.queryStream("SELECT * FROM mysql.user");
stream.pipeline(queryStream, transformStream, someWriterStream);
Streaming - sending
const https = require("https");
https.get(
"https://node.green/#ES2018-features-Promise-prototype-finally-basic-support", //3Mb page
readableStream => {
connection
.query("INSERT INTO StreamingContent (b) VALUE (?)", [readableStream])
.then(res => {})
.catch(err => {});
});
Limitations :
● Server net_read_timeout : SET STATEMENT net_read_timeout=10000 FOR XXX
○ For a connection: sessionVariables: { net_read_timeout: 10000 }
● max_allowed_packet
Batching
BATCH INSERT
conn.batch("INSERT INTO myTable(firstName, lastName) VALUES (?, ?)", [
["john", "smith"],
["jack", "brown"]
]);
})
.then(res => { })
.catch(err => { });
Benchmark : 100 * insert 100 characters on local DB
ORM - sequelize
ORM
$ npm install --save express body-parser sequelize@5.0.0-beta.16 mariadb
const Sequelize = require('sequelize');
const sequelize = new Sequelize('testn', 'root', null, {
host: 'localhost',
dialect: 'mariadb',
pool: {
max: 5,
min: 5,
acquire: 30000,
idle: 10000
}
});
ORM
const User = sequelize.define('myUser', {
id: { type: Sequelize.INTEGER, primaryKey: true, autoIncrement: true },
firstName: { type: Sequelize.STRING },
lastName: { type: Sequelize.STRING }
});
User.sync({ force: true })
.then(() => {
return User.create({ firstName: 'John', lastName: 'Hancock' });
});
ORM
const express = require('express');
const bodyParser = require('body-parser');
const app = express();
app.use(bodyParser.json());
const port = 3000;
app.listen(port, () => { console.log(`Running on http://localhost:${port}`) });
// get all users
app.get('/api/users', (req, res) => {
User.findAll().then(users => res.json(users))
});
tricks
DEBUGGING
Connection options ‘trace’ default to false, nice to have in development mode.
{ Error: (conn=149, no: 1146, SQLState: 42S02) Table 'testn.unknownTable' doesn't exist
sql: SELECT * FROM unknownTable - parameters:[]
at Object.module.exports.createError (/home/diego/IdeaProjects/test_node/node_modules/mariadb/lib/misc/errors.js:55:10)
at Packet.readError (/home/diego/IdeaProjects/test_node/node_modules/mariadb/lib/io/packet.js:506:19)
at Query.readResponsePacket (/home/diego/IdeaProjects/test_node/node_modules/mariadb/lib/cmd/resultset.js:47:28)
at PacketInputStream.receivePacket (/home/diego/IdeaProjects/test_node/node_modules/mariadb/lib/io/packet-input-stream.js:73:9)
at PacketInputStream.onData (/home/diego/IdeaProjects/test_node/node_modules/mariadb/lib/io/packet-input-stream.js:129:20)
at Socket.emit (events.js:197:13)
at addChunk (_stream_readable.js:288:12)
at readableAddChunk (_stream_readable.js:269:11)
at Socket.Readable.push (_stream_readable.js:224:10)
at TCP.onStreamRead [as onread] (internal/stream_base_commons.js:145:17)
fatal: false,
errno: 1146,
sqlState: '42S02',
code: 'ER_NO_SUCH_TABLE' }
DEBUGGING
With trace
{ Error: (conn=150, no: 1146, SQLState: 42S02) Table 'testn.unknownTable' doesn't exist
sql: SELECT * FROM unknownTable - parameters:[]
at Object.module.exports.createError (/home/diego/IdeaProjects/test_node/node_modules/mariadb/lib/misc/errors.js:55:10)
...
at TCP.onStreamRead [as onread] (internal/stream_base_commons.js:145:17)
From event:
at /home/diego/IdeaProjects/test_node/node_modules/mariadb/lib/connection.js:166:29
at new Promise (<anonymous>)
at Connection.query (/home/diego/IdeaProjects/test_node/node_modules/mariadb/lib/connection.js:164:12)
at mariadb.createConnection.then.conn (/home/diego/IdeaProjects/test_node/lib/promise/trace.js:13:8)
at processTicksAndRejections (internal/process/next_tick.js:81:5)
fatal: false,
errno: 1146,
sqlState: '42S02',
code: 'ER_NO_SUCH_TABLE' }
AVOID TCP-IP layer for local connection
Connection options ‘socketPath‘ for local server
- UNIX domain
- Windows named pipe
const mariadb = require('mariadb');
mariadb.createConnection({ socketPath: '/tmp/mysql.sock', user: 'root' })
.then(conn => { ... })
.catch(err => { ... });
METADATA
● Select query = row datas + metadata
Metadata = datatype, format, and lots of additional infos: schema, table name,
table alias, column name, column alias, … Not always needed
conn.query("select * from mysql.user u LIMIT 1")
.then(rows => {
console.log(rows);
// [
// { Host: 'localhost', User: 'root', … }
// ]
});
conn .query({
sql: "select * from mysql.user u LIMIT 1",
rowsAsArray: true
})
.then(rows => {
console.log(rows);
// [
// [ 'localhost', 'root', …]
// ]
});
What next ?
Authentication plugins (Kerberos, ed25519)
Performance improvement
Failover enhancement
Pools improvement
THANK YOU!

Weitere ähnliche Inhalte

Was ist angesagt?

AWS로 사용자 천만 명 서비스 만들기 (윤석찬)- 클라우드 태권 2015
AWS로 사용자 천만 명 서비스 만들기 (윤석찬)- 클라우드 태권 2015 AWS로 사용자 천만 명 서비스 만들기 (윤석찬)- 클라우드 태권 2015
AWS로 사용자 천만 명 서비스 만들기 (윤석찬)- 클라우드 태권 2015 Amazon Web Services Korea
 
Aws glue를 통한 손쉬운 데이터 전처리 작업하기
Aws glue를 통한 손쉬운 데이터 전처리 작업하기Aws glue를 통한 손쉬운 데이터 전처리 작업하기
Aws glue를 통한 손쉬운 데이터 전처리 작업하기Amazon Web Services Korea
 
AWS 기반의 마이크로 서비스 아키텍쳐 구현 방안 :: 김필중 :: AWS Summit Seoul 20
AWS 기반의 마이크로 서비스 아키텍쳐 구현 방안 :: 김필중 :: AWS Summit Seoul 20AWS 기반의 마이크로 서비스 아키텍쳐 구현 방안 :: 김필중 :: AWS Summit Seoul 20
AWS 기반의 마이크로 서비스 아키텍쳐 구현 방안 :: 김필중 :: AWS Summit Seoul 20Amazon Web Services Korea
 
AWS 고객이 주로 겪는 운영 이슈에 대한 해법-AWS Summit Seoul 2017
AWS 고객이 주로 겪는 운영 이슈에 대한 해법-AWS Summit Seoul 2017AWS 고객이 주로 겪는 운영 이슈에 대한 해법-AWS Summit Seoul 2017
AWS 고객이 주로 겪는 운영 이슈에 대한 해법-AWS Summit Seoul 2017Amazon Web Services Korea
 
[Spring Camp 2018] 11번가 Spring Cloud 기반 MSA로의 전환 : 지난 1년간의 이야기
[Spring Camp 2018] 11번가 Spring Cloud 기반 MSA로의 전환 : 지난 1년간의 이야기[Spring Camp 2018] 11번가 Spring Cloud 기반 MSA로의 전환 : 지난 1년간의 이야기
[Spring Camp 2018] 11번가 Spring Cloud 기반 MSA로의 전환 : 지난 1년간의 이야기YongSung Yoon
 
Amazon Aurora Deep Dive (김기완) - AWS DB Day
Amazon Aurora Deep Dive (김기완) - AWS DB DayAmazon Aurora Deep Dive (김기완) - AWS DB Day
Amazon Aurora Deep Dive (김기완) - AWS DB DayAmazon Web Services Korea
 
잘 키운 모노리스 하나 열 마이크로서비스 안 부럽다
잘 키운 모노리스 하나 열 마이크로서비스 안 부럽다잘 키운 모노리스 하나 열 마이크로서비스 안 부럽다
잘 키운 모노리스 하나 열 마이크로서비스 안 부럽다Arawn Park
 
Deep Dive on Accelerating Content, APIs, and Applications with Amazon CloudFr...
Deep Dive on Accelerating Content, APIs, and Applications with Amazon CloudFr...Deep Dive on Accelerating Content, APIs, and Applications with Amazon CloudFr...
Deep Dive on Accelerating Content, APIs, and Applications with Amazon CloudFr...Amazon Web Services
 
Sonatype nexus 로 docker registry 관리하기
Sonatype nexus 로 docker registry 관리하기Sonatype nexus 로 docker registry 관리하기
Sonatype nexus 로 docker registry 관리하기KwangSeob Jeong
 
[AWS Migration Workshop] 데이터베이스를 AWS로 손쉽게 마이그레이션 하기
[AWS Migration Workshop]  데이터베이스를 AWS로 손쉽게 마이그레이션 하기[AWS Migration Workshop]  데이터베이스를 AWS로 손쉽게 마이그레이션 하기
[AWS Migration Workshop] 데이터베이스를 AWS로 손쉽게 마이그레이션 하기Amazon Web Services Korea
 
Python for Linux System Administration
Python for Linux System AdministrationPython for Linux System Administration
Python for Linux System Administrationvceder
 
Introduction to Nginx
Introduction to NginxIntroduction to Nginx
Introduction to NginxKnoldus Inc.
 
엘라스틱서치, 로그스태시, 키바나
엘라스틱서치, 로그스태시, 키바나엘라스틱서치, 로그스태시, 키바나
엘라스틱서치, 로그스태시, 키바나종민 김
 
[236] 카카오의데이터파이프라인 윤도영
[236] 카카오의데이터파이프라인 윤도영[236] 카카오의데이터파이프라인 윤도영
[236] 카카오의데이터파이프라인 윤도영NAVER D2
 
높은 가용성과 성능 향상을 위한 ElastiCache 활용 팁 - 임근택, SendBird :: AWS Summit Seoul 2019
높은 가용성과 성능 향상을 위한 ElastiCache 활용 팁 - 임근택, SendBird :: AWS Summit Seoul 2019 높은 가용성과 성능 향상을 위한 ElastiCache 활용 팁 - 임근택, SendBird :: AWS Summit Seoul 2019
높은 가용성과 성능 향상을 위한 ElastiCache 활용 팁 - 임근택, SendBird :: AWS Summit Seoul 2019 Amazon Web Services Korea
 
Amazon RDS Proxy 집중 탐구 - 윤석찬 :: AWS Unboxing 온라인 세미나
Amazon RDS Proxy 집중 탐구 - 윤석찬 :: AWS Unboxing 온라인 세미나Amazon RDS Proxy 집중 탐구 - 윤석찬 :: AWS Unboxing 온라인 세미나
Amazon RDS Proxy 집중 탐구 - 윤석찬 :: AWS Unboxing 온라인 세미나Amazon Web Services Korea
 

Was ist angesagt? (20)

AWS로 사용자 천만 명 서비스 만들기 (윤석찬)- 클라우드 태권 2015
AWS로 사용자 천만 명 서비스 만들기 (윤석찬)- 클라우드 태권 2015 AWS로 사용자 천만 명 서비스 만들기 (윤석찬)- 클라우드 태권 2015
AWS로 사용자 천만 명 서비스 만들기 (윤석찬)- 클라우드 태권 2015
 
Aws glue를 통한 손쉬운 데이터 전처리 작업하기
Aws glue를 통한 손쉬운 데이터 전처리 작업하기Aws glue를 통한 손쉬운 데이터 전처리 작업하기
Aws glue를 통한 손쉬운 데이터 전처리 작업하기
 
AWS 기반의 마이크로 서비스 아키텍쳐 구현 방안 :: 김필중 :: AWS Summit Seoul 20
AWS 기반의 마이크로 서비스 아키텍쳐 구현 방안 :: 김필중 :: AWS Summit Seoul 20AWS 기반의 마이크로 서비스 아키텍쳐 구현 방안 :: 김필중 :: AWS Summit Seoul 20
AWS 기반의 마이크로 서비스 아키텍쳐 구현 방안 :: 김필중 :: AWS Summit Seoul 20
 
AWS 고객이 주로 겪는 운영 이슈에 대한 해법-AWS Summit Seoul 2017
AWS 고객이 주로 겪는 운영 이슈에 대한 해법-AWS Summit Seoul 2017AWS 고객이 주로 겪는 운영 이슈에 대한 해법-AWS Summit Seoul 2017
AWS 고객이 주로 겪는 운영 이슈에 대한 해법-AWS Summit Seoul 2017
 
[Spring Camp 2018] 11번가 Spring Cloud 기반 MSA로의 전환 : 지난 1년간의 이야기
[Spring Camp 2018] 11번가 Spring Cloud 기반 MSA로의 전환 : 지난 1년간의 이야기[Spring Camp 2018] 11번가 Spring Cloud 기반 MSA로의 전환 : 지난 1년간의 이야기
[Spring Camp 2018] 11번가 Spring Cloud 기반 MSA로의 전환 : 지난 1년간의 이야기
 
Amazon Aurora Deep Dive (김기완) - AWS DB Day
Amazon Aurora Deep Dive (김기완) - AWS DB DayAmazon Aurora Deep Dive (김기완) - AWS DB Day
Amazon Aurora Deep Dive (김기완) - AWS DB Day
 
잘 키운 모노리스 하나 열 마이크로서비스 안 부럽다
잘 키운 모노리스 하나 열 마이크로서비스 안 부럽다잘 키운 모노리스 하나 열 마이크로서비스 안 부럽다
잘 키운 모노리스 하나 열 마이크로서비스 안 부럽다
 
Deep Dive on Accelerating Content, APIs, and Applications with Amazon CloudFr...
Deep Dive on Accelerating Content, APIs, and Applications with Amazon CloudFr...Deep Dive on Accelerating Content, APIs, and Applications with Amazon CloudFr...
Deep Dive on Accelerating Content, APIs, and Applications with Amazon CloudFr...
 
Sonatype nexus 로 docker registry 관리하기
Sonatype nexus 로 docker registry 관리하기Sonatype nexus 로 docker registry 관리하기
Sonatype nexus 로 docker registry 관리하기
 
HAProxy
HAProxy HAProxy
HAProxy
 
[AWS Migration Workshop] 데이터베이스를 AWS로 손쉽게 마이그레이션 하기
[AWS Migration Workshop]  데이터베이스를 AWS로 손쉽게 마이그레이션 하기[AWS Migration Workshop]  데이터베이스를 AWS로 손쉽게 마이그레이션 하기
[AWS Migration Workshop] 데이터베이스를 AWS로 손쉽게 마이그레이션 하기
 
Python for Linux System Administration
Python for Linux System AdministrationPython for Linux System Administration
Python for Linux System Administration
 
Introduction to Nginx
Introduction to NginxIntroduction to Nginx
Introduction to Nginx
 
AWS Fargate on EKS 실전 사용하기
AWS Fargate on EKS 실전 사용하기AWS Fargate on EKS 실전 사용하기
AWS Fargate on EKS 실전 사용하기
 
엘라스틱서치, 로그스태시, 키바나
엘라스틱서치, 로그스태시, 키바나엘라스틱서치, 로그스태시, 키바나
엘라스틱서치, 로그스태시, 키바나
 
[236] 카카오의데이터파이프라인 윤도영
[236] 카카오의데이터파이프라인 윤도영[236] 카카오의데이터파이프라인 윤도영
[236] 카카오의데이터파이프라인 윤도영
 
Terraform
TerraformTerraform
Terraform
 
높은 가용성과 성능 향상을 위한 ElastiCache 활용 팁 - 임근택, SendBird :: AWS Summit Seoul 2019
높은 가용성과 성능 향상을 위한 ElastiCache 활용 팁 - 임근택, SendBird :: AWS Summit Seoul 2019 높은 가용성과 성능 향상을 위한 ElastiCache 활용 팁 - 임근택, SendBird :: AWS Summit Seoul 2019
높은 가용성과 성능 향상을 위한 ElastiCache 활용 팁 - 임근택, SendBird :: AWS Summit Seoul 2019
 
Amazon RDS Proxy 집중 탐구 - 윤석찬 :: AWS Unboxing 온라인 세미나
Amazon RDS Proxy 집중 탐구 - 윤석찬 :: AWS Unboxing 온라인 세미나Amazon RDS Proxy 집중 탐구 - 윤석찬 :: AWS Unboxing 온라인 세미나
Amazon RDS Proxy 집중 탐구 - 윤석찬 :: AWS Unboxing 온라인 세미나
 
Rest web services
Rest web servicesRest web services
Rest web services
 

Ähnlich wie Building better Node.js applications on MariaDB

Cutting through the fog of cloud
Cutting through the fog of cloudCutting through the fog of cloud
Cutting through the fog of cloudKyle Rames
 
Real World Lessons on the Pain Points of Node.JS Application
Real World Lessons on the Pain Points of Node.JS ApplicationReal World Lessons on the Pain Points of Node.JS Application
Real World Lessons on the Pain Points of Node.JS ApplicationBen Hall
 
Azure SQL Database - Connectivity Best Practices
Azure SQL Database - Connectivity Best PracticesAzure SQL Database - Connectivity Best Practices
Azure SQL Database - Connectivity Best PracticesJose Manuel Jurado Diaz
 
Introduce about Nodejs - duyetdev.com
Introduce about Nodejs - duyetdev.comIntroduce about Nodejs - duyetdev.com
Introduce about Nodejs - duyetdev.comVan-Duyet Le
 
Scaling asp.net websites to millions of users
Scaling asp.net websites to millions of usersScaling asp.net websites to millions of users
Scaling asp.net websites to millions of usersoazabir
 
Future Decoded - Node.js per sviluppatori .NET
Future Decoded - Node.js per sviluppatori .NETFuture Decoded - Node.js per sviluppatori .NET
Future Decoded - Node.js per sviluppatori .NETGianluca Carucci
 
RESTful API In Node Js using Express
RESTful API In Node Js using Express RESTful API In Node Js using Express
RESTful API In Node Js using Express Jeetendra singh
 
Apache MXNet Distributed Training Explained In Depth by Viacheslav Kovalevsky...
Apache MXNet Distributed Training Explained In Depth by Viacheslav Kovalevsky...Apache MXNet Distributed Training Explained In Depth by Viacheslav Kovalevsky...
Apache MXNet Distributed Training Explained In Depth by Viacheslav Kovalevsky...Big Data Spain
 
Hazelcast and MongoDB at Cloud CMS
Hazelcast and MongoDB at Cloud CMSHazelcast and MongoDB at Cloud CMS
Hazelcast and MongoDB at Cloud CMSuzquiano
 
Using advanced options in MariaDB Connector/J
Using advanced options in MariaDB Connector/JUsing advanced options in MariaDB Connector/J
Using advanced options in MariaDB Connector/JMariaDB plc
 
A Node.js Developer's Guide to Bluemix
A Node.js Developer's Guide to BluemixA Node.js Developer's Guide to Bluemix
A Node.js Developer's Guide to Bluemixibmwebspheresoftware
 
Writing robust Node.js applications
Writing robust Node.js applicationsWriting robust Node.js applications
Writing robust Node.js applicationsTom Croucher
 
Trivadis TechEvent 2016 Oracle Client Failover - Under the Hood by Robert Bialek
Trivadis TechEvent 2016 Oracle Client Failover - Under the Hood by Robert BialekTrivadis TechEvent 2016 Oracle Client Failover - Under the Hood by Robert Bialek
Trivadis TechEvent 2016 Oracle Client Failover - Under the Hood by Robert BialekTrivadis
 
Oracle Client Failover - Under The Hood
Oracle Client Failover - Under The HoodOracle Client Failover - Under The Hood
Oracle Client Failover - Under The HoodLudovico Caldara
 
10 Excellent Ways to Secure Spring Boot Applications - Okta Webinar 2020
10 Excellent Ways to Secure Spring Boot Applications - Okta Webinar 202010 Excellent Ways to Secure Spring Boot Applications - Okta Webinar 2020
10 Excellent Ways to Secure Spring Boot Applications - Okta Webinar 2020Matt Raible
 
Load Balancing MySQL with HAProxy - Slides
Load Balancing MySQL with HAProxy - SlidesLoad Balancing MySQL with HAProxy - Slides
Load Balancing MySQL with HAProxy - SlidesSeveralnines
 
Kubernetes internals (Kubernetes 해부하기)
Kubernetes internals (Kubernetes 해부하기)Kubernetes internals (Kubernetes 해부하기)
Kubernetes internals (Kubernetes 해부하기)DongHyeon Kim
 
20141011 mastering mysqlnd
20141011 mastering mysqlnd20141011 mastering mysqlnd
20141011 mastering mysqlnddo_aki
 

Ähnlich wie Building better Node.js applications on MariaDB (20)

Cutting through the fog of cloud
Cutting through the fog of cloudCutting through the fog of cloud
Cutting through the fog of cloud
 
Real World Lessons on the Pain Points of Node.JS Application
Real World Lessons on the Pain Points of Node.JS ApplicationReal World Lessons on the Pain Points of Node.JS Application
Real World Lessons on the Pain Points of Node.JS Application
 
Azure SQL Database - Connectivity Best Practices
Azure SQL Database - Connectivity Best PracticesAzure SQL Database - Connectivity Best Practices
Azure SQL Database - Connectivity Best Practices
 
Node.js with MySQL.pdf
Node.js with MySQL.pdfNode.js with MySQL.pdf
Node.js with MySQL.pdf
 
Introduce about Nodejs - duyetdev.com
Introduce about Nodejs - duyetdev.comIntroduce about Nodejs - duyetdev.com
Introduce about Nodejs - duyetdev.com
 
Scaling asp.net websites to millions of users
Scaling asp.net websites to millions of usersScaling asp.net websites to millions of users
Scaling asp.net websites to millions of users
 
Future Decoded - Node.js per sviluppatori .NET
Future Decoded - Node.js per sviluppatori .NETFuture Decoded - Node.js per sviluppatori .NET
Future Decoded - Node.js per sviluppatori .NET
 
RESTful API In Node Js using Express
RESTful API In Node Js using Express RESTful API In Node Js using Express
RESTful API In Node Js using Express
 
Apache MXNet Distributed Training Explained In Depth by Viacheslav Kovalevsky...
Apache MXNet Distributed Training Explained In Depth by Viacheslav Kovalevsky...Apache MXNet Distributed Training Explained In Depth by Viacheslav Kovalevsky...
Apache MXNet Distributed Training Explained In Depth by Viacheslav Kovalevsky...
 
Hazelcast and MongoDB at Cloud CMS
Hazelcast and MongoDB at Cloud CMSHazelcast and MongoDB at Cloud CMS
Hazelcast and MongoDB at Cloud CMS
 
Using advanced options in MariaDB Connector/J
Using advanced options in MariaDB Connector/JUsing advanced options in MariaDB Connector/J
Using advanced options in MariaDB Connector/J
 
A Node.js Developer's Guide to Bluemix
A Node.js Developer's Guide to BluemixA Node.js Developer's Guide to Bluemix
A Node.js Developer's Guide to Bluemix
 
NodeJS "Web en tiempo real"
NodeJS "Web en tiempo real"NodeJS "Web en tiempo real"
NodeJS "Web en tiempo real"
 
Writing robust Node.js applications
Writing robust Node.js applicationsWriting robust Node.js applications
Writing robust Node.js applications
 
Trivadis TechEvent 2016 Oracle Client Failover - Under the Hood by Robert Bialek
Trivadis TechEvent 2016 Oracle Client Failover - Under the Hood by Robert BialekTrivadis TechEvent 2016 Oracle Client Failover - Under the Hood by Robert Bialek
Trivadis TechEvent 2016 Oracle Client Failover - Under the Hood by Robert Bialek
 
Oracle Client Failover - Under The Hood
Oracle Client Failover - Under The HoodOracle Client Failover - Under The Hood
Oracle Client Failover - Under The Hood
 
10 Excellent Ways to Secure Spring Boot Applications - Okta Webinar 2020
10 Excellent Ways to Secure Spring Boot Applications - Okta Webinar 202010 Excellent Ways to Secure Spring Boot Applications - Okta Webinar 2020
10 Excellent Ways to Secure Spring Boot Applications - Okta Webinar 2020
 
Load Balancing MySQL with HAProxy - Slides
Load Balancing MySQL with HAProxy - SlidesLoad Balancing MySQL with HAProxy - Slides
Load Balancing MySQL with HAProxy - Slides
 
Kubernetes internals (Kubernetes 해부하기)
Kubernetes internals (Kubernetes 해부하기)Kubernetes internals (Kubernetes 해부하기)
Kubernetes internals (Kubernetes 해부하기)
 
20141011 mastering mysqlnd
20141011 mastering mysqlnd20141011 mastering mysqlnd
20141011 mastering mysqlnd
 

Mehr von MariaDB plc

MariaDB Paris Workshop 2023 - MaxScale 23.02.x
MariaDB Paris Workshop 2023 - MaxScale 23.02.xMariaDB Paris Workshop 2023 - MaxScale 23.02.x
MariaDB Paris Workshop 2023 - MaxScale 23.02.xMariaDB plc
 
MariaDB Paris Workshop 2023 - Newpharma
MariaDB Paris Workshop 2023 - NewpharmaMariaDB Paris Workshop 2023 - Newpharma
MariaDB Paris Workshop 2023 - NewpharmaMariaDB plc
 
MariaDB Paris Workshop 2023 - Cloud
MariaDB Paris Workshop 2023 - CloudMariaDB Paris Workshop 2023 - Cloud
MariaDB Paris Workshop 2023 - CloudMariaDB plc
 
MariaDB Paris Workshop 2023 - MariaDB Enterprise
MariaDB Paris Workshop 2023 - MariaDB EnterpriseMariaDB Paris Workshop 2023 - MariaDB Enterprise
MariaDB Paris Workshop 2023 - MariaDB EnterpriseMariaDB plc
 
MariaDB Paris Workshop 2023 - Performance Optimization
MariaDB Paris Workshop 2023 - Performance OptimizationMariaDB Paris Workshop 2023 - Performance Optimization
MariaDB Paris Workshop 2023 - Performance OptimizationMariaDB plc
 
MariaDB Paris Workshop 2023 - MaxScale
MariaDB Paris Workshop 2023 - MaxScale MariaDB Paris Workshop 2023 - MaxScale
MariaDB Paris Workshop 2023 - MaxScale MariaDB plc
 
MariaDB Paris Workshop 2023 - novadys presentation
MariaDB Paris Workshop 2023 - novadys presentationMariaDB Paris Workshop 2023 - novadys presentation
MariaDB Paris Workshop 2023 - novadys presentationMariaDB plc
 
MariaDB Paris Workshop 2023 - DARVA presentation
MariaDB Paris Workshop 2023 - DARVA presentationMariaDB Paris Workshop 2023 - DARVA presentation
MariaDB Paris Workshop 2023 - DARVA presentationMariaDB plc
 
MariaDB Tech und Business Update Hamburg 2023 - MariaDB Enterprise Server
MariaDB Tech und Business Update Hamburg 2023 - MariaDB Enterprise Server MariaDB Tech und Business Update Hamburg 2023 - MariaDB Enterprise Server
MariaDB Tech und Business Update Hamburg 2023 - MariaDB Enterprise Server MariaDB plc
 
MariaDB SkySQL Autonome Skalierung, Observability, Cloud-Backup
MariaDB SkySQL Autonome Skalierung, Observability, Cloud-BackupMariaDB SkySQL Autonome Skalierung, Observability, Cloud-Backup
MariaDB SkySQL Autonome Skalierung, Observability, Cloud-BackupMariaDB plc
 
Einführung : MariaDB Tech und Business Update Hamburg 2023
Einführung : MariaDB Tech und Business Update Hamburg 2023Einführung : MariaDB Tech und Business Update Hamburg 2023
Einführung : MariaDB Tech und Business Update Hamburg 2023MariaDB plc
 
Hochverfügbarkeitslösungen mit MariaDB
Hochverfügbarkeitslösungen mit MariaDBHochverfügbarkeitslösungen mit MariaDB
Hochverfügbarkeitslösungen mit MariaDBMariaDB plc
 
Die Neuheiten in MariaDB Enterprise Server
Die Neuheiten in MariaDB Enterprise ServerDie Neuheiten in MariaDB Enterprise Server
Die Neuheiten in MariaDB Enterprise ServerMariaDB plc
 
Global Data Replication with Galera for Ansell Guardian®
Global Data Replication with Galera for Ansell Guardian®Global Data Replication with Galera for Ansell Guardian®
Global Data Replication with Galera for Ansell Guardian®MariaDB plc
 
Introducing workload analysis
Introducing workload analysisIntroducing workload analysis
Introducing workload analysisMariaDB plc
 
Under the hood: SkySQL monitoring
Under the hood: SkySQL monitoringUnder the hood: SkySQL monitoring
Under the hood: SkySQL monitoringMariaDB plc
 
Introducing the R2DBC async Java connector
Introducing the R2DBC async Java connectorIntroducing the R2DBC async Java connector
Introducing the R2DBC async Java connectorMariaDB plc
 
MariaDB Enterprise Tools introduction
MariaDB Enterprise Tools introductionMariaDB Enterprise Tools introduction
MariaDB Enterprise Tools introductionMariaDB plc
 
Faster, better, stronger: The new InnoDB
Faster, better, stronger: The new InnoDBFaster, better, stronger: The new InnoDB
Faster, better, stronger: The new InnoDBMariaDB plc
 
The architecture of SkySQL
The architecture of SkySQLThe architecture of SkySQL
The architecture of SkySQLMariaDB plc
 

Mehr von MariaDB plc (20)

MariaDB Paris Workshop 2023 - MaxScale 23.02.x
MariaDB Paris Workshop 2023 - MaxScale 23.02.xMariaDB Paris Workshop 2023 - MaxScale 23.02.x
MariaDB Paris Workshop 2023 - MaxScale 23.02.x
 
MariaDB Paris Workshop 2023 - Newpharma
MariaDB Paris Workshop 2023 - NewpharmaMariaDB Paris Workshop 2023 - Newpharma
MariaDB Paris Workshop 2023 - Newpharma
 
MariaDB Paris Workshop 2023 - Cloud
MariaDB Paris Workshop 2023 - CloudMariaDB Paris Workshop 2023 - Cloud
MariaDB Paris Workshop 2023 - Cloud
 
MariaDB Paris Workshop 2023 - MariaDB Enterprise
MariaDB Paris Workshop 2023 - MariaDB EnterpriseMariaDB Paris Workshop 2023 - MariaDB Enterprise
MariaDB Paris Workshop 2023 - MariaDB Enterprise
 
MariaDB Paris Workshop 2023 - Performance Optimization
MariaDB Paris Workshop 2023 - Performance OptimizationMariaDB Paris Workshop 2023 - Performance Optimization
MariaDB Paris Workshop 2023 - Performance Optimization
 
MariaDB Paris Workshop 2023 - MaxScale
MariaDB Paris Workshop 2023 - MaxScale MariaDB Paris Workshop 2023 - MaxScale
MariaDB Paris Workshop 2023 - MaxScale
 
MariaDB Paris Workshop 2023 - novadys presentation
MariaDB Paris Workshop 2023 - novadys presentationMariaDB Paris Workshop 2023 - novadys presentation
MariaDB Paris Workshop 2023 - novadys presentation
 
MariaDB Paris Workshop 2023 - DARVA presentation
MariaDB Paris Workshop 2023 - DARVA presentationMariaDB Paris Workshop 2023 - DARVA presentation
MariaDB Paris Workshop 2023 - DARVA presentation
 
MariaDB Tech und Business Update Hamburg 2023 - MariaDB Enterprise Server
MariaDB Tech und Business Update Hamburg 2023 - MariaDB Enterprise Server MariaDB Tech und Business Update Hamburg 2023 - MariaDB Enterprise Server
MariaDB Tech und Business Update Hamburg 2023 - MariaDB Enterprise Server
 
MariaDB SkySQL Autonome Skalierung, Observability, Cloud-Backup
MariaDB SkySQL Autonome Skalierung, Observability, Cloud-BackupMariaDB SkySQL Autonome Skalierung, Observability, Cloud-Backup
MariaDB SkySQL Autonome Skalierung, Observability, Cloud-Backup
 
Einführung : MariaDB Tech und Business Update Hamburg 2023
Einführung : MariaDB Tech und Business Update Hamburg 2023Einführung : MariaDB Tech und Business Update Hamburg 2023
Einführung : MariaDB Tech und Business Update Hamburg 2023
 
Hochverfügbarkeitslösungen mit MariaDB
Hochverfügbarkeitslösungen mit MariaDBHochverfügbarkeitslösungen mit MariaDB
Hochverfügbarkeitslösungen mit MariaDB
 
Die Neuheiten in MariaDB Enterprise Server
Die Neuheiten in MariaDB Enterprise ServerDie Neuheiten in MariaDB Enterprise Server
Die Neuheiten in MariaDB Enterprise Server
 
Global Data Replication with Galera for Ansell Guardian®
Global Data Replication with Galera for Ansell Guardian®Global Data Replication with Galera for Ansell Guardian®
Global Data Replication with Galera for Ansell Guardian®
 
Introducing workload analysis
Introducing workload analysisIntroducing workload analysis
Introducing workload analysis
 
Under the hood: SkySQL monitoring
Under the hood: SkySQL monitoringUnder the hood: SkySQL monitoring
Under the hood: SkySQL monitoring
 
Introducing the R2DBC async Java connector
Introducing the R2DBC async Java connectorIntroducing the R2DBC async Java connector
Introducing the R2DBC async Java connector
 
MariaDB Enterprise Tools introduction
MariaDB Enterprise Tools introductionMariaDB Enterprise Tools introduction
MariaDB Enterprise Tools introduction
 
Faster, better, stronger: The new InnoDB
Faster, better, stronger: The new InnoDBFaster, better, stronger: The new InnoDB
Faster, better, stronger: The new InnoDB
 
The architecture of SkySQL
The architecture of SkySQLThe architecture of SkySQL
The architecture of SkySQL
 

Kürzlich hochgeladen

WSO2Con2024 - Enabling Transactional System's Exponential Growth With Simplicity
WSO2Con2024 - Enabling Transactional System's Exponential Growth With SimplicityWSO2Con2024 - Enabling Transactional System's Exponential Growth With Simplicity
WSO2Con2024 - Enabling Transactional System's Exponential Growth With SimplicityWSO2
 
WSO2CON 2024 - Navigating API Complexity: REST, GraphQL, gRPC, Websocket, Web...
WSO2CON 2024 - Navigating API Complexity: REST, GraphQL, gRPC, Websocket, Web...WSO2CON 2024 - Navigating API Complexity: REST, GraphQL, gRPC, Websocket, Web...
WSO2CON 2024 - Navigating API Complexity: REST, GraphQL, gRPC, Websocket, Web...WSO2
 
Devoxx UK 2024 - Going serverless with Quarkus, GraalVM native images and AWS...
Devoxx UK 2024 - Going serverless with Quarkus, GraalVM native images and AWS...Devoxx UK 2024 - Going serverless with Quarkus, GraalVM native images and AWS...
Devoxx UK 2024 - Going serverless with Quarkus, GraalVM native images and AWS...Bert Jan Schrijver
 
%+27788225528 love spells in Toronto Psychic Readings, Attraction spells,Brin...
%+27788225528 love spells in Toronto Psychic Readings, Attraction spells,Brin...%+27788225528 love spells in Toronto Psychic Readings, Attraction spells,Brin...
%+27788225528 love spells in Toronto Psychic Readings, Attraction spells,Brin...masabamasaba
 
%in Benoni+277-882-255-28 abortion pills for sale in Benoni
%in Benoni+277-882-255-28 abortion pills for sale in Benoni%in Benoni+277-882-255-28 abortion pills for sale in Benoni
%in Benoni+277-882-255-28 abortion pills for sale in Benonimasabamasaba
 
AI & Machine Learning Presentation Template
AI & Machine Learning Presentation TemplateAI & Machine Learning Presentation Template
AI & Machine Learning Presentation TemplatePresentation.STUDIO
 
Love witchcraft +27768521739 Binding love spell in Sandy Springs, GA |psychic...
Love witchcraft +27768521739 Binding love spell in Sandy Springs, GA |psychic...Love witchcraft +27768521739 Binding love spell in Sandy Springs, GA |psychic...
Love witchcraft +27768521739 Binding love spell in Sandy Springs, GA |psychic...chiefasafspells
 
WSO2CON 2024 - How to Run a Security Program
WSO2CON 2024 - How to Run a Security ProgramWSO2CON 2024 - How to Run a Security Program
WSO2CON 2024 - How to Run a Security ProgramWSO2
 
WSO2CON 2024 - Cloud Native Middleware: Domain-Driven Design, Cell-Based Arch...
WSO2CON 2024 - Cloud Native Middleware: Domain-Driven Design, Cell-Based Arch...WSO2CON 2024 - Cloud Native Middleware: Domain-Driven Design, Cell-Based Arch...
WSO2CON 2024 - Cloud Native Middleware: Domain-Driven Design, Cell-Based Arch...WSO2
 
tonesoftg
tonesoftgtonesoftg
tonesoftglanshi9
 
%in tembisa+277-882-255-28 abortion pills for sale in tembisa
%in tembisa+277-882-255-28 abortion pills for sale in tembisa%in tembisa+277-882-255-28 abortion pills for sale in tembisa
%in tembisa+277-882-255-28 abortion pills for sale in tembisamasabamasaba
 
MarTech Trend 2024 Book : Marketing Technology Trends (2024 Edition) How Data...
MarTech Trend 2024 Book : Marketing Technology Trends (2024 Edition) How Data...MarTech Trend 2024 Book : Marketing Technology Trends (2024 Edition) How Data...
MarTech Trend 2024 Book : Marketing Technology Trends (2024 Edition) How Data...Jittipong Loespradit
 
%in Midrand+277-882-255-28 abortion pills for sale in midrand
%in Midrand+277-882-255-28 abortion pills for sale in midrand%in Midrand+277-882-255-28 abortion pills for sale in midrand
%in Midrand+277-882-255-28 abortion pills for sale in midrandmasabamasaba
 
Crypto Cloud Review - How To Earn Up To $500 Per DAY Of Bitcoin 100% On AutoP...
Crypto Cloud Review - How To Earn Up To $500 Per DAY Of Bitcoin 100% On AutoP...Crypto Cloud Review - How To Earn Up To $500 Per DAY Of Bitcoin 100% On AutoP...
Crypto Cloud Review - How To Earn Up To $500 Per DAY Of Bitcoin 100% On AutoP...SelfMade bd
 
WSO2CON2024 - It's time to go Platformless
WSO2CON2024 - It's time to go PlatformlessWSO2CON2024 - It's time to go Platformless
WSO2CON2024 - It's time to go PlatformlessWSO2
 
Announcing Codolex 2.0 from GDK Software
Announcing Codolex 2.0 from GDK SoftwareAnnouncing Codolex 2.0 from GDK Software
Announcing Codolex 2.0 from GDK SoftwareJim McKeeth
 
%in kempton park+277-882-255-28 abortion pills for sale in kempton park
%in kempton park+277-882-255-28 abortion pills for sale in kempton park %in kempton park+277-882-255-28 abortion pills for sale in kempton park
%in kempton park+277-882-255-28 abortion pills for sale in kempton park masabamasaba
 
WSO2CON 2024 - Freedom First—Unleashing Developer Potential with Open Source
WSO2CON 2024 - Freedom First—Unleashing Developer Potential with Open SourceWSO2CON 2024 - Freedom First—Unleashing Developer Potential with Open Source
WSO2CON 2024 - Freedom First—Unleashing Developer Potential with Open SourceWSO2
 
%in Bahrain+277-882-255-28 abortion pills for sale in Bahrain
%in Bahrain+277-882-255-28 abortion pills for sale in Bahrain%in Bahrain+277-882-255-28 abortion pills for sale in Bahrain
%in Bahrain+277-882-255-28 abortion pills for sale in Bahrainmasabamasaba
 
%+27788225528 love spells in Huntington Beach Psychic Readings, Attraction sp...
%+27788225528 love spells in Huntington Beach Psychic Readings, Attraction sp...%+27788225528 love spells in Huntington Beach Psychic Readings, Attraction sp...
%+27788225528 love spells in Huntington Beach Psychic Readings, Attraction sp...masabamasaba
 

Kürzlich hochgeladen (20)

WSO2Con2024 - Enabling Transactional System's Exponential Growth With Simplicity
WSO2Con2024 - Enabling Transactional System's Exponential Growth With SimplicityWSO2Con2024 - Enabling Transactional System's Exponential Growth With Simplicity
WSO2Con2024 - Enabling Transactional System's Exponential Growth With Simplicity
 
WSO2CON 2024 - Navigating API Complexity: REST, GraphQL, gRPC, Websocket, Web...
WSO2CON 2024 - Navigating API Complexity: REST, GraphQL, gRPC, Websocket, Web...WSO2CON 2024 - Navigating API Complexity: REST, GraphQL, gRPC, Websocket, Web...
WSO2CON 2024 - Navigating API Complexity: REST, GraphQL, gRPC, Websocket, Web...
 
Devoxx UK 2024 - Going serverless with Quarkus, GraalVM native images and AWS...
Devoxx UK 2024 - Going serverless with Quarkus, GraalVM native images and AWS...Devoxx UK 2024 - Going serverless with Quarkus, GraalVM native images and AWS...
Devoxx UK 2024 - Going serverless with Quarkus, GraalVM native images and AWS...
 
%+27788225528 love spells in Toronto Psychic Readings, Attraction spells,Brin...
%+27788225528 love spells in Toronto Psychic Readings, Attraction spells,Brin...%+27788225528 love spells in Toronto Psychic Readings, Attraction spells,Brin...
%+27788225528 love spells in Toronto Psychic Readings, Attraction spells,Brin...
 
%in Benoni+277-882-255-28 abortion pills for sale in Benoni
%in Benoni+277-882-255-28 abortion pills for sale in Benoni%in Benoni+277-882-255-28 abortion pills for sale in Benoni
%in Benoni+277-882-255-28 abortion pills for sale in Benoni
 
AI & Machine Learning Presentation Template
AI & Machine Learning Presentation TemplateAI & Machine Learning Presentation Template
AI & Machine Learning Presentation Template
 
Love witchcraft +27768521739 Binding love spell in Sandy Springs, GA |psychic...
Love witchcraft +27768521739 Binding love spell in Sandy Springs, GA |psychic...Love witchcraft +27768521739 Binding love spell in Sandy Springs, GA |psychic...
Love witchcraft +27768521739 Binding love spell in Sandy Springs, GA |psychic...
 
WSO2CON 2024 - How to Run a Security Program
WSO2CON 2024 - How to Run a Security ProgramWSO2CON 2024 - How to Run a Security Program
WSO2CON 2024 - How to Run a Security Program
 
WSO2CON 2024 - Cloud Native Middleware: Domain-Driven Design, Cell-Based Arch...
WSO2CON 2024 - Cloud Native Middleware: Domain-Driven Design, Cell-Based Arch...WSO2CON 2024 - Cloud Native Middleware: Domain-Driven Design, Cell-Based Arch...
WSO2CON 2024 - Cloud Native Middleware: Domain-Driven Design, Cell-Based Arch...
 
tonesoftg
tonesoftgtonesoftg
tonesoftg
 
%in tembisa+277-882-255-28 abortion pills for sale in tembisa
%in tembisa+277-882-255-28 abortion pills for sale in tembisa%in tembisa+277-882-255-28 abortion pills for sale in tembisa
%in tembisa+277-882-255-28 abortion pills for sale in tembisa
 
MarTech Trend 2024 Book : Marketing Technology Trends (2024 Edition) How Data...
MarTech Trend 2024 Book : Marketing Technology Trends (2024 Edition) How Data...MarTech Trend 2024 Book : Marketing Technology Trends (2024 Edition) How Data...
MarTech Trend 2024 Book : Marketing Technology Trends (2024 Edition) How Data...
 
%in Midrand+277-882-255-28 abortion pills for sale in midrand
%in Midrand+277-882-255-28 abortion pills for sale in midrand%in Midrand+277-882-255-28 abortion pills for sale in midrand
%in Midrand+277-882-255-28 abortion pills for sale in midrand
 
Crypto Cloud Review - How To Earn Up To $500 Per DAY Of Bitcoin 100% On AutoP...
Crypto Cloud Review - How To Earn Up To $500 Per DAY Of Bitcoin 100% On AutoP...Crypto Cloud Review - How To Earn Up To $500 Per DAY Of Bitcoin 100% On AutoP...
Crypto Cloud Review - How To Earn Up To $500 Per DAY Of Bitcoin 100% On AutoP...
 
WSO2CON2024 - It's time to go Platformless
WSO2CON2024 - It's time to go PlatformlessWSO2CON2024 - It's time to go Platformless
WSO2CON2024 - It's time to go Platformless
 
Announcing Codolex 2.0 from GDK Software
Announcing Codolex 2.0 from GDK SoftwareAnnouncing Codolex 2.0 from GDK Software
Announcing Codolex 2.0 from GDK Software
 
%in kempton park+277-882-255-28 abortion pills for sale in kempton park
%in kempton park+277-882-255-28 abortion pills for sale in kempton park %in kempton park+277-882-255-28 abortion pills for sale in kempton park
%in kempton park+277-882-255-28 abortion pills for sale in kempton park
 
WSO2CON 2024 - Freedom First—Unleashing Developer Potential with Open Source
WSO2CON 2024 - Freedom First—Unleashing Developer Potential with Open SourceWSO2CON 2024 - Freedom First—Unleashing Developer Potential with Open Source
WSO2CON 2024 - Freedom First—Unleashing Developer Potential with Open Source
 
%in Bahrain+277-882-255-28 abortion pills for sale in Bahrain
%in Bahrain+277-882-255-28 abortion pills for sale in Bahrain%in Bahrain+277-882-255-28 abortion pills for sale in Bahrain
%in Bahrain+277-882-255-28 abortion pills for sale in Bahrain
 
%+27788225528 love spells in Huntington Beach Psychic Readings, Attraction sp...
%+27788225528 love spells in Huntington Beach Psychic Readings, Attraction sp...%+27788225528 love spells in Huntington Beach Psychic Readings, Attraction sp...
%+27788225528 love spells in Huntington Beach Psychic Readings, Attraction sp...
 

Building better Node.js applications on MariaDB

  • 1. Node.js Connector Diego DUPIN MariaDB Connector Engineer MariaDB Corporation
  • 2. PROGRAM - Getting started - Best practice - Advanced topic - ORM
  • 3. NODE.JS CONNECTORS Existing community connectors ● mysqljs/mysql (npm mysql) (+ Promise-mysql to have promise) ● sidorares/node-mysql2 (npm mysql2) ● mscdex/node-mariasql (npm mariasql) New connector ● MariaDB/mariadb-connector-nodejs (npm mariadb)
  • 4. WHY A NEW CONNECTOR ● New functionalities ● Better performance Benchmark : “SELECT * FROM mysql.user LIMIT 1” on local DB
  • 6. QUICK START - INSTALLATION through npm. $ npm install mariadb To use the Connector, you need to import the package into your application code. const mariadb = require('mariadb'); //promise implementation or const mariadb = require('mariadb/callback'); //callback implementation
  • 7. QUICK START - CONNECTION Promise const mariadb = require("mariadb"); mariadb.createConnection({ user: "root", database: "db", host: "localhost", port: 3306 }) .then(conn => { console.log("Connected successful"); conn.end(); }) .catch(err => { console.log("Error: " + err.message); }); const mariadb = require("mariadb/callback"); const conn = mariadb.createConnection({ user: "root", database: "db", host: "localhost", port: 3306 }); conn.connect(err => { if (err) { console.log("Error: " + err.message); } else { console.log("Connected successful"); conn.end(); } }); Callback
  • 8. QUICK START - INSERT conn.query( "CREATE TEMPORARY TABLE myTable " + "(id int NOT NULL AUTO_INCREMENT, firstName varchar(256), lastName varchar(256), " + " PRIMARY KEY (id))" ) .then(() => { return conn.query("INSERT INTO myTable(firstName, lastName) VALUES (?, ?)", [ "john", "smith" ]); }) .then(res => { console.log(res); //{ affectedRows: 1, insertId: 1, warningStatus: 0 } conn.end(); }) .catch(err => { });
  • 9. QUICK START - SELECT conn.query( "SELECT ID,COLLATION_NAME FROM INFORMATION_SCHEMA.COLLATIONS " + "WHERE CHARACTER_SET_NAME = ? LIMIT 2", ["utf8mb4"] ) .then(res => { console.log(res); /* resultset is an array of rows, represented by JSON object [ { ID: 45, COLLATION_NAME: 'utf8mb4_general_ci' }, { ID: 46, COLLATION_NAME: 'utf8mb4_bin' } ] */ conn.end(); }) .catch(err => { … });
  • 10. CONNECTION ESSENTIAL API ● connection.query(sql[, values]) → Promise: Executes a query. ● connection.queryStream(sql[, values]) → Emitter: Executes a query, streaming results. ● connection.batch(sql, values) → Promise: fast batch processing. ● connection.beginTransaction() → Promise: Begins a transaction. ● connection.commit() → Promise: Commits the current transaction, if any. ● connection.rollback() → Promise: Rolls back the current transaction, if any. ● connection.ping() → Promise: Sends a 1 byte packet to the database to validate the connection. ● connection.end() → Promise: Gracefully close the connection.
  • 11. SSL
  • 12. SSL One-Way SSL Authentication or Two-Way SSL Authentication const fs = require("fs"); const mariadb = require('mariadb'); //reading certificates from file const serverCert = [fs.readFileSync("server.pem", "utf8")]; //connecting mariadb .createConnection({ user: "myUser", host: "myHost.com", ssl: { ca: serverCert } }).then(conn => {})
  • 14. POOLING Basically a database connection cache implementation Connections are expensive. On local DB: ● 2.4ms for a basic connection ● 0.05ms for a simple query Problem : correctness and reliability
  • 15. POOLING Event implementation - Pool handle new connection creation one by one - New connection are added to idle connection queue On connection failure: - Pool revalidate all other connections - Continue creating new connections creation one by one Connection request are queued separately Idle Connections
  • 17. POOLING - Implementation to handle query pikes Example with a pool that is configured to have a maximum of 50 connections. actual connection number is 5. With a basis of a connection creation taking 2.4ms, and query taking 0.05ms (example on a local server). Everything is quiet, and then ... Boom! ... 100 queries on the pool at once, wanting a connection.
  • 20. POOLING Connection pools SIZING error Example 10 000 user simultaneously, 20 000 transaction per second. What value to connectionLimit (max connection number in pool) ? 100 ? 500 ? 1000 ?
  • 21. POOLING - CONFIGURATION acquireTimeout t acquireTimeout Timeout to get a new connection from pool. Maximum number of connection in pool. Delay to avoid connection validation Disabling connection control connectionLimit minDelayValidation noControlAfterUse
  • 22. POOL API ● pool.getConnection() → Promise : Creates a new connection. ● pool.query(sql[, values]) → Promise: Executes a query. ● pool.batch(sql, values) → Promise: Executes a batch Stats ● pool.activeConnections() → Number: Gets current active connection number. ● pool.totalConnections() → Number: Gets current total connection number. ● pool.idleConnections() → Number: Gets current idle connection number. ● pool.taskQueueSize() → Number: Gets current stacked request.
  • 23. POOLING - CONFIGURATION const pool = mariadb.createPool({ user: "root", database: "testn", host: "localhost", port: 3306, sessionVariables: { wait_timeout: 31536000 }, acquireTimeout: 5000, connectionLimit: 8, }); pool .getConnection() .then(conn => { console.log("Connected successfully to server"); conn.release(); }) .catch(err => { console.log("Error during connection: " + err.message); }); Server expect connection to be used (@wait_timeout)
  • 25. MULTI-HOST - ESSENTIAL API “Cluster” offer handle multiple pools permitting load balancing and high availability const mariadb = require("mariadb"); const cluster = mariadb.createPoolCluster(); cluster.add("master", { host: "mydb1.com", ... }); cluster.add("slave1", { host: "mydb2.com", ... }); cluster.add("slave2", { host: "mydb3.com", ... }); cluster .getConnection("slave*", "RR") //RR: ROUND-ROBIN .then(conn => { }) .catch(err => { });
  • 26. MULTI-HOST - ESSENTIAL API client Master Slave B Slave A Cluster.getConnection("slave*", "RR")
  • 27. MULTI-HOST - ESSENTIAL API client Master Slave B Slave A Cluster.getConnection("slave*", "RR")
  • 28. MULTI-HOST - ESSENTIAL API client Master Slave B Slave A Cluster.getConnection("slave*", "RR")
  • 29. MULTI-HOST - ESSENTIAL API client Master Slave B Slave A Cluster.getConnection("slave*", "RR")
  • 30. MULTI-HOST - ESSENTIAL API client Master Slave B Slave A Cluster.getConnection("slave*", "RR")
  • 31. MULTI-HOST - ESSENTIAL API client Master Slave B Slave A Cluster.getConnection("slave*", "RR")
  • 33. MULTI-HOST - ESSENTIAL API ● poolCluster.add(id, config) : add a pool to cluster. ● poolCluster.remove(pattern) : remove and end pool according to pattern. ● poolCluster.end() → Promise : end cluster. ● poolCluster.getConnection(pattern, selector) → Promise : return a connection from cluster. ● poolCluster.of(pattern, selector) → FilteredPoolCluster : return a subset of cluster.
  • 34. MULTI-HOST - ESSENTIAL API poolCluster.of(pattern, selector) → FilteredPoolCluster : return a subset of cluster. const cluster = mariadb.createPoolCluster(); cluster.add("master", { host: "mydb1.com", ... }); cluster.add("slave1", { host: "mydb2.com", ... }); cluster.add("slave2", { host: "mydb3.com", ... }); const slaves = cluster.of(/^slave?/, 'RANDOM'); slaves.getConnection().then( ... ); slaves.query(sql, values).then( ... ); slaves.batch(sql, values).then( ... );
  • 37. PIPELINING Pipelining is a technique in which multiple requests are sent on a single TCP connection without waiting for the corresponding responses. This saves round trip time.
  • 38. PIPELINING - without const uuid = uuidv1(); //generate new UUID conn .beginTransaction() .then(() => { return conn.query("INSERT INTO basket(basketId) values (?)", uuid); }) .then(() => { return conn.query( "INSERT INTO basket_item(basketId, itemId) VALUES (?, ?)", [ uuid, 100 ]); }) .then(() => { return conn.query( "INSERT INTO basket_item(basketId, itemId) VALUES (?, ?)", [ uuid, 101 ]); }) .then(() => { conn.commit(); }) .catch(err => { conn.rollback(); });
  • 39. PIPELINING - with const uuid = uuidv1(); //generate new UUID conn .beginTransaction() .then(() => { return Promise.all([ conn.query("INSERT INTO basket(basketId) values (?)", uuid), conn.query( "INSERT INTO basket_item(basketId, itemId) VALUES (?, ?)", [uuid, 100]), conn.query( "INSERT INTO basket_item(basketId, itemId) VALUES (?, ?)", [uuid, 101]) ]); }) .then(() => { conn.commit(); }) .catch(err => { conn.rollback(); });
  • 40. PIPELINING Local DB: abuse : socket buffering
  • 42. Streaming Goal : Avoid loading all in memory ● Streaming resultset -> avoiding loading large resultset totally into memory ○ By event ○ With pipe ● Streaming sent -> sending buffer by chunk
  • 43. Streaming resultset BY EVENT : Limitations : ● Server net_write_timeout. ○ For a command: SET STATEMENT net_write_timeout=10000 FOR XXX ○ For a connection: sessionVariables: { net_write_timeout: 31536000 } connection .queryStream("SELECT * FROM mysql.user") .on("error", err => {}) .on("fields", meta => {}) .on("data", row => {}) .on("end", () => {});
  • 44. Streaming resultset USING PIPE : const someWriterStream = fs.createWriteStream("./jsonUsers.txt"); const transformStream = new stream.Transform({ objectMode: true, transform: function transformer(chunk, encoding, callback) { callback(null, JSON.stringify(chunk)); } }); const queryStream = connection.queryStream("SELECT * FROM mysql.user"); stream.pipeline(queryStream, transformStream, someWriterStream);
  • 45. Streaming - sending const https = require("https"); https.get( "https://node.green/#ES2018-features-Promise-prototype-finally-basic-support", //3Mb page readableStream => { connection .query("INSERT INTO StreamingContent (b) VALUE (?)", [readableStream]) .then(res => {}) .catch(err => {}); }); Limitations : ● Server net_read_timeout : SET STATEMENT net_read_timeout=10000 FOR XXX ○ For a connection: sessionVariables: { net_read_timeout: 10000 } ● max_allowed_packet
  • 47. BATCH INSERT conn.batch("INSERT INTO myTable(firstName, lastName) VALUES (?, ?)", [ ["john", "smith"], ["jack", "brown"] ]); }) .then(res => { }) .catch(err => { }); Benchmark : 100 * insert 100 characters on local DB
  • 49. ORM $ npm install --save express body-parser sequelize@5.0.0-beta.16 mariadb const Sequelize = require('sequelize'); const sequelize = new Sequelize('testn', 'root', null, { host: 'localhost', dialect: 'mariadb', pool: { max: 5, min: 5, acquire: 30000, idle: 10000 } });
  • 50. ORM const User = sequelize.define('myUser', { id: { type: Sequelize.INTEGER, primaryKey: true, autoIncrement: true }, firstName: { type: Sequelize.STRING }, lastName: { type: Sequelize.STRING } }); User.sync({ force: true }) .then(() => { return User.create({ firstName: 'John', lastName: 'Hancock' }); });
  • 51. ORM const express = require('express'); const bodyParser = require('body-parser'); const app = express(); app.use(bodyParser.json()); const port = 3000; app.listen(port, () => { console.log(`Running on http://localhost:${port}`) }); // get all users app.get('/api/users', (req, res) => { User.findAll().then(users => res.json(users)) });
  • 53. DEBUGGING Connection options ‘trace’ default to false, nice to have in development mode. { Error: (conn=149, no: 1146, SQLState: 42S02) Table 'testn.unknownTable' doesn't exist sql: SELECT * FROM unknownTable - parameters:[] at Object.module.exports.createError (/home/diego/IdeaProjects/test_node/node_modules/mariadb/lib/misc/errors.js:55:10) at Packet.readError (/home/diego/IdeaProjects/test_node/node_modules/mariadb/lib/io/packet.js:506:19) at Query.readResponsePacket (/home/diego/IdeaProjects/test_node/node_modules/mariadb/lib/cmd/resultset.js:47:28) at PacketInputStream.receivePacket (/home/diego/IdeaProjects/test_node/node_modules/mariadb/lib/io/packet-input-stream.js:73:9) at PacketInputStream.onData (/home/diego/IdeaProjects/test_node/node_modules/mariadb/lib/io/packet-input-stream.js:129:20) at Socket.emit (events.js:197:13) at addChunk (_stream_readable.js:288:12) at readableAddChunk (_stream_readable.js:269:11) at Socket.Readable.push (_stream_readable.js:224:10) at TCP.onStreamRead [as onread] (internal/stream_base_commons.js:145:17) fatal: false, errno: 1146, sqlState: '42S02', code: 'ER_NO_SUCH_TABLE' }
  • 54. DEBUGGING With trace { Error: (conn=150, no: 1146, SQLState: 42S02) Table 'testn.unknownTable' doesn't exist sql: SELECT * FROM unknownTable - parameters:[] at Object.module.exports.createError (/home/diego/IdeaProjects/test_node/node_modules/mariadb/lib/misc/errors.js:55:10) ... at TCP.onStreamRead [as onread] (internal/stream_base_commons.js:145:17) From event: at /home/diego/IdeaProjects/test_node/node_modules/mariadb/lib/connection.js:166:29 at new Promise (<anonymous>) at Connection.query (/home/diego/IdeaProjects/test_node/node_modules/mariadb/lib/connection.js:164:12) at mariadb.createConnection.then.conn (/home/diego/IdeaProjects/test_node/lib/promise/trace.js:13:8) at processTicksAndRejections (internal/process/next_tick.js:81:5) fatal: false, errno: 1146, sqlState: '42S02', code: 'ER_NO_SUCH_TABLE' }
  • 55. AVOID TCP-IP layer for local connection Connection options ‘socketPath‘ for local server - UNIX domain - Windows named pipe const mariadb = require('mariadb'); mariadb.createConnection({ socketPath: '/tmp/mysql.sock', user: 'root' }) .then(conn => { ... }) .catch(err => { ... });
  • 56. METADATA ● Select query = row datas + metadata Metadata = datatype, format, and lots of additional infos: schema, table name, table alias, column name, column alias, … Not always needed conn.query("select * from mysql.user u LIMIT 1") .then(rows => { console.log(rows); // [ // { Host: 'localhost', User: 'root', … } // ] }); conn .query({ sql: "select * from mysql.user u LIMIT 1", rowsAsArray: true }) .then(rows => { console.log(rows); // [ // [ 'localhost', 'root', …] // ] });
  • 57. What next ? Authentication plugins (Kerberos, ed25519) Performance improvement Failover enhancement Pools improvement