SlideShare une entreprise Scribd logo
1  sur  64
Télécharger pour lire hors ligne
Créer un serveur noSQL
en une heure
Bases noSQL
Bibliothèques utilisées
Présentation AngstromDB
Étude de code
Benchmark & évolutions
Créer un serveur noSQL
Base noSQL
Aller plus loin
Scalabilité horizontale
Haute disponibilité
Big Data
S'affranchir
Modèle relationnel
Transactions ACID
Principe général
Types de bases noSQL
Clé-valeur Document Colonne Graph
Dynamo
Riak
Redis
Voldemort
Tokyo Tyrant
MemcacheDB
FoundationDB
MongoDB
CouchDB
CouchBase
HyperDex
RethinkDB
Cassandra
Hadoop / Hbase
Accumulo
Neo4J
Allegro
Virtuoso
InfoGrid
Bibliothèques
de programmation
Le successeur de ZeroMQ
Bibliothèque réseau avec des
super-pouvoirs
Nanomsg
Gestion de files de messages
Protocole spécifique
14 langages supportés
Redéfinition des concepts réseau
Nanomsg
Méthodes de transport
Inter-threads inproc
Inter-processus ipc
Inter-machines tcp
Découplage du sens de connexion
ServeurClient
Découplage du sens de connexion
ServeurClient
Socket multi-connexion
ServeurClient
Client
Client
port A
port B
Connexion REQ/REP
ServeurClient
REQ
Connexion REQ/REP
ServeurClient
REP
Connexion PUSH/PULL
ServeurClient
PUSH
Connexion PUSH/PULL
ServeurClient
PULL
Connexion PUB/SUB
Client
PUB
Serveur
Client
Client
Connexion PUB/SUB
ClientServeur
Client
Client
SUB
SUB
SUB
Load-balancing
ClientServeur
Client
Client
PULL
PUSH
Load-balancing
ClientServeur
Client
Client
PULLPUSH
Load-balancing
ClientServeur
Client
Client
PULL
PUSH
Bus
Client
Client
Client
Client
Bus
Client Client
Client
Client
Stockage paires clé-valeur multivaluées
Persistance sur disque, mapping RAM
Transactionnel (1 thread d'écriture)
Au cœur de OpenLDAP
LMDB (LightningDB)
Débit
Latence
ops / sec.
microsec.
HyperDex : LMDB vs LevelDB
Présentation
AngstromDB
Serveur paires clé-valeur
Codé en C
Basé sur des bibliothèques reconnues
Protocole binaire
Aucun contrôle d'erreur
Implémentation naïve
API très simple
PUT
Ajout ou mise-à-jour de clé
GET
Retourne une valeur
DELETE
Efface une clé
Protocole : DELETE
2
cmd taille
clé
clé
1 1 1 à 255 octets
Requête
Réponse 1
statut
1
Protocole : GET
3
cmd taille
clé
clé
1 1 1 à 255 octets
Requête
Réponse 1
statut taille
données
données
1 4 0 à 4 GO
Protocole : PUT
1
cmd taille clé clé
1 1 1 à 255 octets
Requête
Réponse 1
statut
taille données données
1
4 0 à 4 GO
Multi-threadé
Thread principal
Attend les nouvelles connexions
Threads de communication
Un thread par client connecté
Thread d'écriture
Pas d'écriture concurrente
Thread principal
Threads de communication
LMDB
Thread
d'écriture
Étude de code
github.com/Amaury/AngstromDB ↩
↪ /tree/master/src
Démarrage
/*
* db Pointer to the database environment.
* socket Socket descriptor for incoming connections.
* threads_socket Nanomsg socket for threads communication.
* writer_tid ID of the writer thread.
* comm_threads Array of communication threads.
*/
typedef struct angstrom_s {
MDB_env *db;
int socket;
int threads_socket;
pthread_t writer_tid;
struct comm_thread_s *comm_threads;
} angstrom_t;
/*
* tid Thread's identifier.
* angstrom Pointer to the server's structure.
* client_sock Socket used to communicate with the client.
* writer_sock Nanomsg socket to send data to the writer. */
typedef struct comm_thread_s {
pthread_t tid;
angstrom_t *angstrom;
int client_sock;
int writer_sock;
} comm_thread_t;
angstrom.h
Démarrage
int main() {
angstrom_t *angstrom;
int i;
// server init
angstrom = calloc(1, sizeof(angstrom_t));
angstrom->socket = angstrom->threads_socket = -1;
angstrom->comm_threads = calloc(NBR_THREADS,
sizeof(comm_thread_t));
// open the database
angstrom->db = database_open(DEFAULT_DB_PATH,
DEFAULT_MAPSIZE, NBR_THREADS);
// create the nanomsg socket for threads communication
angstrom->threads_socket = nn_socket(AF_SP, NN_PUSH);
nn_bind(angstrom->threads_socket, ENDPOINT_THREADS_SOCKET);
// create the writer thread
pthread_create(&angstrom->writer_tid, NULL,
thread_writer_loop, angstrom);
main.c
Démarrage
int main() {
angstrom_t *angstrom;
int i;
// server init
angstrom = calloc(1, sizeof(angstrom_t));
angstrom->socket = angstrom->threads_socket = -1;
angstrom->comm_threads = calloc(NBR_THREADS,
sizeof(comm_thread_t));
// open the database
angstrom->db = database_open(DEFAULT_DB_PATH,
DEFAULT_MAPSIZE, NBR_THREADS);
// create the nanomsg socket for threads communication
angstrom->threads_socket = nn_socket(AF_SP, NN_PUSH);
nn_bind(angstrom->threads_socket, ENDPOINT_THREADS_SOCKET);
// create the writer thread
pthread_create(&angstrom->writer_tid, NULL,
thread_writer_loop, angstrom);
main.c
"inproc://threads_socket"
Démarrage
// create communication threads
for (i = 0; i < NBR_THREADS; i++) {
comm_thread_t *thread = &(angstrom->comm_threads[i]);
thread->client_sock = -1;
thread->angstrom = angstrom;
pthread_create(&thread->tid, 0, thread_comm_loop,
thread);
pthread_detach(thread->tid);
}
// create listening socket
angstrom->socket = _create_listening_socket(DEFAULT_PORT);
// server loop
_main_thread_loop(angstrom);
return (0);
}
main.c
Démarrage
MDB_env *database_open(const char *path, size_t mapsize,
unsigned int nbr_threads) {
MDB_env *env = NULL;
mdb_env_create(&env);
mdb_env_set_mapsize(env, mapsize);
mdb_env_set_maxreaders(env, nbr_threads);
mdb_env_open(env, path, 0, 0664);
return (env);
}
database.c
Démarrage
static int _create_listening_socket(unsigned short port) {
int sock;
struct sockaddr_in addr;
unsigned int addr_size;
const int on = 1;
// create the socket
sock = socket(AF_INET, SOCK_STREAM, 0);
// some options
setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (void*)&on,
sizeof(on));
setsockopt(sock, SOL_SOCKET, SO_KEEPALIVE, (void*)&on,
sizeof(on));
// binding to any interface
addr_size = sizeof(addr);
bzero(&addr, addr_size);
addr.sin_addr.s_addr = htonl(INADDR_ANY);
addr.sin_family = AF_INET;
addr.sin_port = htons(port);
bind(sock, (struct sockaddr*)&addr, addr_size);
listen(sock, SOMAXCONN);
return (sock);
}
main.c
Nouvelle connexion
static void _main_thread_loop(angstrom_t *angstrom) {
int fd;
struct sockaddr_in addr;
unsigned int addr_size;
const int on = 1;
addr_size = sizeof(addr);
for (; ; ) {
bzero(&addr, addr_size);
// accept a new connection
if ((fd = accept(angstrom->socket,
(struct sockaddr*)&addr,
&addr_size)) < 0) {
continue ;
}
setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, (void*)&on,
sizeof(on));
// send the file descriptor number to comm threads
nn_send(angstrom->threads_socket, &fd, sizeof(fd), 0);
}
}
main.c
Nouvelle connexion
void *thread_comm_loop(void *param) {
comm_thread_t *thread = param;
int in_sock;
// opening a connection to the writer thread
thread->writer_sock = nn_socket(AF_SP, NN_PUSH);
nn_connect(thread->writer_sock, ENDPOINT_WRITER_SOCKET);
// opening a connection to the main thread
in_sock = nn_socket(AF_SP, NN_PULL);
nn_connect(in_sock, ENDPOINT_THREADS_SOCKET);
// loop to process new connections
for (; ; ) {
// waiting for a new connection to handle
nn_recv(in_sock, &thread->client_sock, sizeof(int), 0);
// process connection
_process_connection(thread);
}
return (NULL);
}
thread_com
munication.c
Nouvelle connexion
void *thread_comm_loop(void *param) {
comm_thread_t *thread = param;
int in_sock;
// opening a connection to the writer thread
thread->writer_sock = nn_socket(AF_SP, NN_PUSH);
nn_connect(thread->writer_sock, ENDPOINT_WRITER_SOCKET);
// opening a connection to the main thread
in_sock = nn_socket(AF_SP, NN_PULL);
nn_connect(in_sock, ENDPOINT_THREADS_SOCKET);
// loop to process new connections
for (; ; ) {
// waiting for a new connection to handle
nn_recv(in_sock, &thread->client_sock, sizeof(int), 0);
// process connection
_process_connection(thread);
}
return (NULL);
}
thread_com
munication.c
"inproc://writer_socket"
"inproc://threads_socket"
Nouvelle connexion
static void _process_connection(comm_thread_t *thread) {
uint8_t cmd;
// loop on incoming requests
for (; ; ) {
// read command byte
if (read(thread->client_sock, &cmd, sizeof(cmd)) <= 0) {
close(thread->client_sock);
break;
}
// interpret command
switch (cmd) {
case PROTO_PUT:
command_put(thread);
break;
case PROTO_DELETE:
command_del(thread);
break;
case PROTO_GET:
command_get(thread);
break;
}
}
}
thread_com
munication.c
Lecture de données
void command_get(comm_thread_t *thread) {
uint8_t key_size, response = PROTO_OK;
uint32_t value_size;
MDB_val key, value;
// read key length
read(thread->client_sock, &key_size, sizeof(key_size));
// read key data
key.mv_data = malloc(key_size);
read(thread->client_sock, key.mv_data, key_size);
// get data
key.mv_size = (size_t)key_size;
database_get(thread->angstrom->db, &key, &value);
// send response to the client
write(thread->client_sock, &response, sizeof(response));
value_size = htonl((uint32_t)value.mv_size);
write(thread->client_sock, &value_size, sizeof(value_size));
if (value_size)
write(thread->client_sock, value.mv_data, value.mv_size);
}
command_
get.c
Lecture de données
void database_get(MDB_env *db, MDB_val *key, MDB_val *value) {
MDB_dbi dbi;
MDB_txn *txn;
// transaction init
mdb_txn_begin(db, NULL, MDB_RDONLY, &txn);
// open database in read-write mode
mdb_dbi_open(txn, NULL, 0, &dbi);
// get data
if (mdb_get(txn, dbi, key, value))
bzero(value, sizeof(*value));
// end of transaction
mdb_txn_abort(txn);
// close database
mdb_dbi_close(db, dbi);
}
database.c
Thread d'écriture
/*
* type Type of action (WRITE_PUT, WRITE_DEL).
* key Size and content of the key.
* value Size and content of the value.
*/
typedef struct writer_msg_s {
enum {
WRITE_PUT,
WRITE_DEL
} type;
MDB_val key;
MDB_val value;
} writer_msg_t;
angstrom.h
Thread d'écriture
void *thread_writer_loop(void *param) {
angstrom_t *angstrom = param;
int socket;
// create the nanomsg socket for threads communication
socket = nn_socket(AF_SP, NN_PULL);
nn_bind(socket, ENDPOINT_WRITER_SOCKET);
// loop to process new connections
for (; ; ) {
writer_msg_t *msg;
// waiting for a new connection to handle
if (nn_recv(socket, &msg, sizeof(writer_msg_t*), 0) < 0)
continue;
// processing
switch (msg->type) {
case WRITE_PUT:
database_put(angstrom->db, &msg->key, &msg->value);
break;
case WRITE_DEL:
database_del(angstrom->db, &msg->key);
break;
}
thread_
writer.c
Thread d'écriture
void *thread_writer_loop(void *param) {
angstrom_t *angstrom = param;
int socket;
// create the nanomsg socket for threads communication
socket = nn_socket(AF_SP, NN_PULL);
nn_bind(socket, ENDPOINT_WRITER_SOCKET);
// loop to process new connections
for (; ; ) {
writer_msg_t *msg;
// waiting for a new connection to handle
if (nn_recv(socket, &msg, sizeof(writer_msg_t*), 0) < 0)
continue;
// processing
switch (msg->type) {
case WRITE_PUT:
database_put(angstrom->db, &msg->key, &msg->value);
break;
case WRITE_DEL:
database_del(angstrom->db, &msg->key);
break;
}
thread_
writer.c
"inproc://writer_socket"
Thread d'écriture
// free data
if (msg->key.mv_data)
free(msg->key.mv_data);
if (msg->value.mv_data)
free(msg->value.mv_data);
free(msg);
}
return (NULL);
}
thread_
writer.c
Effacement de clé
void command_delete(comm_thread_t *thread) {
uint8_t key_size, response = PROTO_OK;
void *key;
writer_msg_t *msg;
// read key length
read(thread->client_sock, &key_size, sizeof(key_size));
// read key data
key = malloc(key_size);
read(thread->client_sock, key, key_size);
// create message
msg = calloc(1, sizeof(writer_msg_t));
msg->type = WRITE_DEL;
msg->key.mv_size = (size_t)key_size;
msg->key.mv_data = key;
// send the message to the writer thread
nn_send(thread->writer_sock, &msg, sizeof(msg), 0);
// send response to the client
write(thread->client_sock, &response, sizeof(response));
}
command_
delete.c
Effacement de clé
void database_del(MDB_env *db, MDB_val *key) {
MDB_dbi dbi;
MDB_txn *txn;
// transaction init
mdb_txn_begin(db, NULL, 0, &txn);
// open database in read-write mode
mdb_dbi_open(txn, NULL, 0, &dbi);
// delete key
mdb_del(txn, dbi, key, NULL);
// close database
mdb_dbi_close(db, dbi);
// transaction commit
mdb_txn_commit(txn);
}
database.c
Ajout / mise-à-jour de clé
void command_put(comm_thread_t *thread) {
uint8_t key_size, response = PROTO_OK;
void *key, *value = NULL;
uint32_t value_size;
writer_msg_t *msg;
// read key length
read(thread->client_sock, &key_size, sizeof(key_size));
// read key data
key = malloc(key_size);
read(thread->client_sock, key, key_size);
// read value length
read(thread->client_sock, &value_size, sizeof(value_size));
value_size = ntohl(value_size);
if (value_size > 0) {
// read value data
value = malloc(value_size);
read(thread->client_sock, value, value_size);
}
command_
put.c
Ajout / mise-à-jour de clé
// create message
msg = malloc(sizeof(writer_msg_t));
msg->type = WRITE_PUT;
msg->key.mv_size = (size_t)key_size;
msg->key.mv_data = key;
msg->value.mv_size = (size_t)value_size;
msg->value.mv_data = value;
// send the message to the writer thread
nn_send(thread->writer_sock, &msg, sizeof(msg), 0);
// send response to the client
write(thread->client_sock, &response, sizeof(response));
}
command_
put.c
Ajout / mise-à-jour de clé
void database_put(MDB_env *db, MDB_val *key, MDB_val *value) {
MDB_dbi dbi;
MDB_txn *txn;
// transaction init
mdb_txn_begin(db, NULL, 0, &txn);
// open database in read-write mode
mdb_dbi_open(txn, NULL, 0, &dbi);
// put data
mdb_put(txn, dbi, key, value, 0);
// close database
mdb_dbi_close(db, dbi);
// transaction commit
mdb_txn_commit(txn);
}
database.c
cloc
Language files comment code
-------------------------------------------------
C 7 132 212
C Header 1 111 55
make 1 13 27
-------------------------------------------------
SUM: 9 256 294
sloccount
Schedule Estimate, Years (Months) = 0.17 (2.06)
Total Estimated Cost to Develop = $ 6,753
Benchmark
Base Écritures Lectures
AngstromDB 22 ms 55 ms
Couchbase 25 ms 22 ms
Redis 29 ms 30 ms
MongoDB 39 ms 27 ms
45 écritures / lectures séquentielles de données représentatives
Améliorations
possibles
Réduire les appels systèmes !
Bufferiser les lectures réseau
Regrouper les écritures réseau
Facile à tester (sendmsg vs write)
Pour commencer
Benchmark
Base Écritures Lectures
AngstromDB 22 ms 55 ms
AngstromDB 22 ms 26 ms
Couchbase 25 ms 22 ms
Redis 29 ms 30 ms
MongoDB 39 ms 27 ms
Compression à la volée (Zippy)
Sérialisation de données (MsgPack)
Transactions en lecture
… Mono-processus asynchrone ?
Pour aller plus loin
geek-directeur-technique.com
github.com/Amaury/AngstromDB
amaury@amaury.net
@geekcto

Contenu connexe

Tendances

PHP Backdoor: The rise of the vuln
PHP Backdoor: The rise of the vulnPHP Backdoor: The rise of the vuln
PHP Backdoor: The rise of the vulnSandro Zaccarini
 
Debugging: Rules & Tools
Debugging: Rules & ToolsDebugging: Rules & Tools
Debugging: Rules & ToolsIan Barber
 
On UnQLite
On UnQLiteOn UnQLite
On UnQLitecharsbar
 
Asynchronous I/O in PHP
Asynchronous I/O in PHPAsynchronous I/O in PHP
Asynchronous I/O in PHPThomas Weinert
 
React PHP: the NodeJS challenger
React PHP: the NodeJS challengerReact PHP: the NodeJS challenger
React PHP: the NodeJS challengervanphp
 
Php web backdoor obfuscation
Php web backdoor obfuscationPhp web backdoor obfuscation
Php web backdoor obfuscationSandro Zaccarini
 
Modern Getopt for Command Line Processing in Perl
Modern Getopt for Command Line Processing in PerlModern Getopt for Command Line Processing in Perl
Modern Getopt for Command Line Processing in PerlNova Patch
 
Webrtc mojo
Webrtc mojoWebrtc mojo
Webrtc mojobpmedley
 
Smolder @Silex
Smolder @SilexSmolder @Silex
Smolder @SilexJeen Lee
 
PHP in 2018 - Q4 - AFUP Limoges
PHP in 2018 - Q4 - AFUP LimogesPHP in 2018 - Q4 - AFUP Limoges
PHP in 2018 - Q4 - AFUP Limoges✅ William Pinaud
 
Introduction to CloudForecast / YAPC::Asia 2010 Tokyo
Introduction to CloudForecast / YAPC::Asia 2010 TokyoIntroduction to CloudForecast / YAPC::Asia 2010 Tokyo
Introduction to CloudForecast / YAPC::Asia 2010 TokyoMasahiro Nagano
 
Any event intro
Any event introAny event intro
Any event introqiang
 
Introducing PHP Latest Updates
Introducing PHP Latest UpdatesIntroducing PHP Latest Updates
Introducing PHP Latest UpdatesIftekhar Eather
 
Meet up symfony 16 juin 2017 - Les PSR
Meet up symfony 16 juin 2017 -  Les PSRMeet up symfony 16 juin 2017 -  Les PSR
Meet up symfony 16 juin 2017 - Les PSRJulien Vinber
 

Tendances (20)

PHP Backdoor: The rise of the vuln
PHP Backdoor: The rise of the vulnPHP Backdoor: The rise of the vuln
PHP Backdoor: The rise of the vuln
 
Debugging: Rules & Tools
Debugging: Rules & ToolsDebugging: Rules & Tools
Debugging: Rules & Tools
 
On UnQLite
On UnQLiteOn UnQLite
On UnQLite
 
C99.php
C99.phpC99.php
C99.php
 
Asynchronous I/O in PHP
Asynchronous I/O in PHPAsynchronous I/O in PHP
Asynchronous I/O in PHP
 
React PHP: the NodeJS challenger
React PHP: the NodeJS challengerReact PHP: the NodeJS challenger
React PHP: the NodeJS challenger
 
Php web backdoor obfuscation
Php web backdoor obfuscationPhp web backdoor obfuscation
Php web backdoor obfuscation
 
C99
C99C99
C99
 
Modern Getopt for Command Line Processing in Perl
Modern Getopt for Command Line Processing in PerlModern Getopt for Command Line Processing in Perl
Modern Getopt for Command Line Processing in Perl
 
Webrtc mojo
Webrtc mojoWebrtc mojo
Webrtc mojo
 
Yg byev2e
Yg byev2eYg byev2e
Yg byev2e
 
Smolder @Silex
Smolder @SilexSmolder @Silex
Smolder @Silex
 
How-to Integração Postfi
How-to Integração PostfiHow-to Integração Postfi
How-to Integração Postfi
 
PHP in 2018 - Q4 - AFUP Limoges
PHP in 2018 - Q4 - AFUP LimogesPHP in 2018 - Q4 - AFUP Limoges
PHP in 2018 - Q4 - AFUP Limoges
 
TRunner
TRunnerTRunner
TRunner
 
dotCloud and go
dotCloud and godotCloud and go
dotCloud and go
 
Introduction to CloudForecast / YAPC::Asia 2010 Tokyo
Introduction to CloudForecast / YAPC::Asia 2010 TokyoIntroduction to CloudForecast / YAPC::Asia 2010 Tokyo
Introduction to CloudForecast / YAPC::Asia 2010 Tokyo
 
Any event intro
Any event introAny event intro
Any event intro
 
Introducing PHP Latest Updates
Introducing PHP Latest UpdatesIntroducing PHP Latest Updates
Introducing PHP Latest Updates
 
Meet up symfony 16 juin 2017 - Les PSR
Meet up symfony 16 juin 2017 -  Les PSRMeet up symfony 16 juin 2017 -  Les PSR
Meet up symfony 16 juin 2017 - Les PSR
 

En vedette

De 0 à 10 millions de visiteurs uniques avec les moyens d'une startup
De 0 à 10 millions de visiteurs uniques avec les moyens d'une startupDe 0 à 10 millions de visiteurs uniques avec les moyens d'une startup
De 0 à 10 millions de visiteurs uniques avec les moyens d'une startupAmaury Bouchard
 
PyCon 2015 Belarus Andrii Soldatenko
PyCon 2015 Belarus Andrii SoldatenkoPyCon 2015 Belarus Andrii Soldatenko
PyCon 2015 Belarus Andrii SoldatenkoAndrii Soldatenko
 
SeleniumCamp 2015 Andrii Soldatenko
SeleniumCamp 2015 Andrii SoldatenkoSeleniumCamp 2015 Andrii Soldatenko
SeleniumCamp 2015 Andrii SoldatenkoAndrii Soldatenko
 
PyCon Russian 2015 - Dive into full text search with python.
PyCon Russian 2015 - Dive into full text search with python.PyCon Russian 2015 - Dive into full text search with python.
PyCon Russian 2015 - Dive into full text search with python.Andrii Soldatenko
 
Practical continuous quality gates for development process
Practical continuous quality gates for development processPractical continuous quality gates for development process
Practical continuous quality gates for development processAndrii Soldatenko
 
Building social network with Neo4j and Python
Building social network with Neo4j and PythonBuilding social network with Neo4j and Python
Building social network with Neo4j and PythonAndrii Soldatenko
 

En vedette (7)

De 0 à 10 millions de visiteurs uniques avec les moyens d'une startup
De 0 à 10 millions de visiteurs uniques avec les moyens d'une startupDe 0 à 10 millions de visiteurs uniques avec les moyens d'une startup
De 0 à 10 millions de visiteurs uniques avec les moyens d'une startup
 
PyCon 2015 Belarus Andrii Soldatenko
PyCon 2015 Belarus Andrii SoldatenkoPyCon 2015 Belarus Andrii Soldatenko
PyCon 2015 Belarus Andrii Soldatenko
 
SeleniumCamp 2015 Andrii Soldatenko
SeleniumCamp 2015 Andrii SoldatenkoSeleniumCamp 2015 Andrii Soldatenko
SeleniumCamp 2015 Andrii Soldatenko
 
PyCon Ukraine 2014
PyCon Ukraine 2014PyCon Ukraine 2014
PyCon Ukraine 2014
 
PyCon Russian 2015 - Dive into full text search with python.
PyCon Russian 2015 - Dive into full text search with python.PyCon Russian 2015 - Dive into full text search with python.
PyCon Russian 2015 - Dive into full text search with python.
 
Practical continuous quality gates for development process
Practical continuous quality gates for development processPractical continuous quality gates for development process
Practical continuous quality gates for development process
 
Building social network with Neo4j and Python
Building social network with Neo4j and PythonBuilding social network with Neo4j and Python
Building social network with Neo4j and Python
 

Similaire à Créer une base NoSQL en 1 heure

Server side JavaScript: going all the way
Server side JavaScript: going all the wayServer side JavaScript: going all the way
Server side JavaScript: going all the wayOleg Podsechin
 
CODE FOR echo_client.c A simple echo client using TCP #inc.pdf
CODE FOR echo_client.c A simple echo client using TCP  #inc.pdfCODE FOR echo_client.c A simple echo client using TCP  #inc.pdf
CODE FOR echo_client.c A simple echo client using TCP #inc.pdfsecunderbadtirumalgi
 
Extending functionality in nginx, with modules!
Extending functionality in nginx, with modules!Extending functionality in nginx, with modules!
Extending functionality in nginx, with modules!Trygve Vea
 
Remote Procedure Call
Remote Procedure CallRemote Procedure Call
Remote Procedure CallNadia Nahar
 
How to Leverage Go for Your Networking Needs
How to Leverage Go for Your Networking NeedsHow to Leverage Go for Your Networking Needs
How to Leverage Go for Your Networking NeedsDigitalOcean
 
Nachos3 - Theoretical Part
Nachos3 - Theoretical PartNachos3 - Theoretical Part
Nachos3 - Theoretical PartEduardo Triana
 
Anchoring Trust: Rewriting DNS for the Semantic Network with Ruby and Rails
Anchoring Trust: Rewriting DNS for the Semantic Network with Ruby and RailsAnchoring Trust: Rewriting DNS for the Semantic Network with Ruby and Rails
Anchoring Trust: Rewriting DNS for the Semantic Network with Ruby and RailsEleanor McHugh
 
sbt-ethereum: a terminal for the world computer
sbt-ethereum: a terminal for the world computersbt-ethereum: a terminal for the world computer
sbt-ethereum: a terminal for the world computerSteve Waldman
 
Nodejs 프로그래밍 ch.3
Nodejs 프로그래밍 ch.3Nodejs 프로그래밍 ch.3
Nodejs 프로그래밍 ch.3HyeonSeok Choi
 
Session Server - Maintaing State between several Servers
Session Server - Maintaing State between several ServersSession Server - Maintaing State between several Servers
Session Server - Maintaing State between several ServersStephan Schmidt
 
Chatting dengan beberapa pc laptop
Chatting dengan beberapa pc laptopChatting dengan beberapa pc laptop
Chatting dengan beberapa pc laptopyayaria
 
Use perl creating web services with xml rpc
Use perl creating web services with xml rpcUse perl creating web services with xml rpc
Use perl creating web services with xml rpcJohnny Pork
 
Socket programming
Socket programmingSocket programming
Socket programmingAnurag Tomar
 
NodeJSnodesforfreeinmyworldgipsnndnnd.pdf
NodeJSnodesforfreeinmyworldgipsnndnnd.pdfNodeJSnodesforfreeinmyworldgipsnndnnd.pdf
NodeJSnodesforfreeinmyworldgipsnndnnd.pdfVivekSonawane45
 
OpenSSL Basic Function Call Flow
OpenSSL Basic Function Call FlowOpenSSL Basic Function Call Flow
OpenSSL Basic Function Call FlowWilliam Lee
 
forwarder.java.txt java forwarder class waits for an in.docx
forwarder.java.txt java forwarder class waits for an in.docxforwarder.java.txt java forwarder class waits for an in.docx
forwarder.java.txt java forwarder class waits for an in.docxbudbarber38650
 

Similaire à Créer une base NoSQL en 1 heure (20)

Server side JavaScript: going all the way
Server side JavaScript: going all the wayServer side JavaScript: going all the way
Server side JavaScript: going all the way
 
CODE FOR echo_client.c A simple echo client using TCP #inc.pdf
CODE FOR echo_client.c A simple echo client using TCP  #inc.pdfCODE FOR echo_client.c A simple echo client using TCP  #inc.pdf
CODE FOR echo_client.c A simple echo client using TCP #inc.pdf
 
Extending functionality in nginx, with modules!
Extending functionality in nginx, with modules!Extending functionality in nginx, with modules!
Extending functionality in nginx, with modules!
 
Remote Procedure Call
Remote Procedure CallRemote Procedure Call
Remote Procedure Call
 
Python networking
Python networkingPython networking
Python networking
 
Socket programming
Socket programming Socket programming
Socket programming
 
How to Leverage Go for Your Networking Needs
How to Leverage Go for Your Networking NeedsHow to Leverage Go for Your Networking Needs
How to Leverage Go for Your Networking Needs
 
Nachos3 - Theoretical Part
Nachos3 - Theoretical PartNachos3 - Theoretical Part
Nachos3 - Theoretical Part
 
Anchoring Trust: Rewriting DNS for the Semantic Network with Ruby and Rails
Anchoring Trust: Rewriting DNS for the Semantic Network with Ruby and RailsAnchoring Trust: Rewriting DNS for the Semantic Network with Ruby and Rails
Anchoring Trust: Rewriting DNS for the Semantic Network with Ruby and Rails
 
sbt-ethereum: a terminal for the world computer
sbt-ethereum: a terminal for the world computersbt-ethereum: a terminal for the world computer
sbt-ethereum: a terminal for the world computer
 
Nodejs 프로그래밍 ch.3
Nodejs 프로그래밍 ch.3Nodejs 프로그래밍 ch.3
Nodejs 프로그래밍 ch.3
 
Session Server - Maintaing State between several Servers
Session Server - Maintaing State between several ServersSession Server - Maintaing State between several Servers
Session Server - Maintaing State between several Servers
 
Chatting dengan beberapa pc laptop
Chatting dengan beberapa pc laptopChatting dengan beberapa pc laptop
Chatting dengan beberapa pc laptop
 
Use perl creating web services with xml rpc
Use perl creating web services with xml rpcUse perl creating web services with xml rpc
Use perl creating web services with xml rpc
 
Node js lecture
Node js lectureNode js lecture
Node js lecture
 
Socket programming
Socket programmingSocket programming
Socket programming
 
NodeJSnodesforfreeinmyworldgipsnndnnd.pdf
NodeJSnodesforfreeinmyworldgipsnndnnd.pdfNodeJSnodesforfreeinmyworldgipsnndnnd.pdf
NodeJSnodesforfreeinmyworldgipsnndnnd.pdf
 
03 sockets
03 sockets03 sockets
03 sockets
 
OpenSSL Basic Function Call Flow
OpenSSL Basic Function Call FlowOpenSSL Basic Function Call Flow
OpenSSL Basic Function Call Flow
 
forwarder.java.txt java forwarder class waits for an in.docx
forwarder.java.txt java forwarder class waits for an in.docxforwarder.java.txt java forwarder class waits for an in.docx
forwarder.java.txt java forwarder class waits for an in.docx
 

Plus de Amaury Bouchard

Organisation personnelle : GTD et matrice d'Eisenhower (Lightning Talk)
Organisation personnelle : GTD et matrice d'Eisenhower (Lightning Talk)Organisation personnelle : GTD et matrice d'Eisenhower (Lightning Talk)
Organisation personnelle : GTD et matrice d'Eisenhower (Lightning Talk)Amaury Bouchard
 
Démons en PHP, de inetd à ZeroMQ
Démons en PHP, de inetd à ZeroMQDémons en PHP, de inetd à ZeroMQ
Démons en PHP, de inetd à ZeroMQAmaury Bouchard
 
Architectures réparties en environnement web
Architectures réparties en environnement webArchitectures réparties en environnement web
Architectures réparties en environnement webAmaury Bouchard
 
De geek à directeur technique - Conférence SupInfo 2010
De geek à directeur technique - Conférence SupInfo 2010De geek à directeur technique - Conférence SupInfo 2010
De geek à directeur technique - Conférence SupInfo 2010Amaury Bouchard
 
De geek à directeur technique - Conférence Université de Montréal 2010
De geek à directeur technique - Conférence Université de Montréal 2010De geek à directeur technique - Conférence Université de Montréal 2010
De geek à directeur technique - Conférence Université de Montréal 2010Amaury Bouchard
 
De geek à directeur technique - Conférence UQÀM 2010
De geek à directeur technique - Conférence UQÀM 2010De geek à directeur technique - Conférence UQÀM 2010
De geek à directeur technique - Conférence UQÀM 2010Amaury Bouchard
 
De geek à directeur technique - Conférence Epitech 2010
De geek à directeur technique - Conférence Epitech 2010De geek à directeur technique - Conférence Epitech 2010
De geek à directeur technique - Conférence Epitech 2010Amaury Bouchard
 

Plus de Amaury Bouchard (7)

Organisation personnelle : GTD et matrice d'Eisenhower (Lightning Talk)
Organisation personnelle : GTD et matrice d'Eisenhower (Lightning Talk)Organisation personnelle : GTD et matrice d'Eisenhower (Lightning Talk)
Organisation personnelle : GTD et matrice d'Eisenhower (Lightning Talk)
 
Démons en PHP, de inetd à ZeroMQ
Démons en PHP, de inetd à ZeroMQDémons en PHP, de inetd à ZeroMQ
Démons en PHP, de inetd à ZeroMQ
 
Architectures réparties en environnement web
Architectures réparties en environnement webArchitectures réparties en environnement web
Architectures réparties en environnement web
 
De geek à directeur technique - Conférence SupInfo 2010
De geek à directeur technique - Conférence SupInfo 2010De geek à directeur technique - Conférence SupInfo 2010
De geek à directeur technique - Conférence SupInfo 2010
 
De geek à directeur technique - Conférence Université de Montréal 2010
De geek à directeur technique - Conférence Université de Montréal 2010De geek à directeur technique - Conférence Université de Montréal 2010
De geek à directeur technique - Conférence Université de Montréal 2010
 
De geek à directeur technique - Conférence UQÀM 2010
De geek à directeur technique - Conférence UQÀM 2010De geek à directeur technique - Conférence UQÀM 2010
De geek à directeur technique - Conférence UQÀM 2010
 
De geek à directeur technique - Conférence Epitech 2010
De geek à directeur technique - Conférence Epitech 2010De geek à directeur technique - Conférence Epitech 2010
De geek à directeur technique - Conférence Epitech 2010
 

Dernier

Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)Mark Simos
 
Nell’iperspazio con Rocket: il Framework Web di Rust!
Nell’iperspazio con Rocket: il Framework Web di Rust!Nell’iperspazio con Rocket: il Framework Web di Rust!
Nell’iperspazio con Rocket: il Framework Web di Rust!Commit University
 
"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr Bagan"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr BaganFwdays
 
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek SchlawackFwdays
 
Gen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdfGen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdfAddepto
 
Powerpoint exploring the locations used in television show Time Clash
Powerpoint exploring the locations used in television show Time ClashPowerpoint exploring the locations used in television show Time Clash
Powerpoint exploring the locations used in television show Time Clashcharlottematthew16
 
From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .Alan Dix
 
H2O.ai CEO/Founder: Sri Ambati Keynote at Wells Fargo Day
H2O.ai CEO/Founder: Sri Ambati Keynote at Wells Fargo DayH2O.ai CEO/Founder: Sri Ambati Keynote at Wells Fargo Day
H2O.ai CEO/Founder: Sri Ambati Keynote at Wells Fargo DaySri Ambati
 
Anypoint Exchange: It’s Not Just a Repo!
Anypoint Exchange: It’s Not Just a Repo!Anypoint Exchange: It’s Not Just a Repo!
Anypoint Exchange: It’s Not Just a Repo!Manik S Magar
 
DevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platformsDevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platformsSergiu Bodiu
 
TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024Lonnie McRorey
 
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptxMerck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptxLoriGlavin3
 
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024BookNet Canada
 
Commit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easyCommit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easyAlfredo García Lavilla
 
SAP Build Work Zone - Overview L2-L3.pptx
SAP Build Work Zone - Overview L2-L3.pptxSAP Build Work Zone - Overview L2-L3.pptx
SAP Build Work Zone - Overview L2-L3.pptxNavinnSomaal
 
Connect Wave/ connectwave Pitch Deck Presentation
Connect Wave/ connectwave Pitch Deck PresentationConnect Wave/ connectwave Pitch Deck Presentation
Connect Wave/ connectwave Pitch Deck PresentationSlibray Presentation
 
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024BookNet Canada
 
TrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data PrivacyTrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data PrivacyTrustArc
 
Hyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdf
Hyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdfHyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdf
Hyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdfPrecisely
 
Human Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR SystemsHuman Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR SystemsMark Billinghurst
 

Dernier (20)

Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
 
Nell’iperspazio con Rocket: il Framework Web di Rust!
Nell’iperspazio con Rocket: il Framework Web di Rust!Nell’iperspazio con Rocket: il Framework Web di Rust!
Nell’iperspazio con Rocket: il Framework Web di Rust!
 
"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr Bagan"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr Bagan
 
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
 
Gen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdfGen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdf
 
Powerpoint exploring the locations used in television show Time Clash
Powerpoint exploring the locations used in television show Time ClashPowerpoint exploring the locations used in television show Time Clash
Powerpoint exploring the locations used in television show Time Clash
 
From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .
 
H2O.ai CEO/Founder: Sri Ambati Keynote at Wells Fargo Day
H2O.ai CEO/Founder: Sri Ambati Keynote at Wells Fargo DayH2O.ai CEO/Founder: Sri Ambati Keynote at Wells Fargo Day
H2O.ai CEO/Founder: Sri Ambati Keynote at Wells Fargo Day
 
Anypoint Exchange: It’s Not Just a Repo!
Anypoint Exchange: It’s Not Just a Repo!Anypoint Exchange: It’s Not Just a Repo!
Anypoint Exchange: It’s Not Just a Repo!
 
DevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platformsDevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platforms
 
TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024
 
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptxMerck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptx
 
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
 
Commit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easyCommit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easy
 
SAP Build Work Zone - Overview L2-L3.pptx
SAP Build Work Zone - Overview L2-L3.pptxSAP Build Work Zone - Overview L2-L3.pptx
SAP Build Work Zone - Overview L2-L3.pptx
 
Connect Wave/ connectwave Pitch Deck Presentation
Connect Wave/ connectwave Pitch Deck PresentationConnect Wave/ connectwave Pitch Deck Presentation
Connect Wave/ connectwave Pitch Deck Presentation
 
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
 
TrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data PrivacyTrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data Privacy
 
Hyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdf
Hyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdfHyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdf
Hyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdf
 
Human Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR SystemsHuman Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR Systems
 

Créer une base NoSQL en 1 heure

  • 1. Créer un serveur noSQL en une heure
  • 2. Bases noSQL Bibliothèques utilisées Présentation AngstromDB Étude de code Benchmark & évolutions Créer un serveur noSQL
  • 4. Aller plus loin Scalabilité horizontale Haute disponibilité Big Data S'affranchir Modèle relationnel Transactions ACID Principe général
  • 5. Types de bases noSQL Clé-valeur Document Colonne Graph Dynamo Riak Redis Voldemort Tokyo Tyrant MemcacheDB FoundationDB MongoDB CouchDB CouchBase HyperDex RethinkDB Cassandra Hadoop / Hbase Accumulo Neo4J Allegro Virtuoso InfoGrid
  • 7. Le successeur de ZeroMQ Bibliothèque réseau avec des super-pouvoirs Nanomsg
  • 8. Gestion de files de messages Protocole spécifique 14 langages supportés Redéfinition des concepts réseau Nanomsg
  • 9. Méthodes de transport Inter-threads inproc Inter-processus ipc Inter-machines tcp
  • 10. Découplage du sens de connexion ServeurClient
  • 11. Découplage du sens de connexion ServeurClient
  • 24. Stockage paires clé-valeur multivaluées Persistance sur disque, mapping RAM Transactionnel (1 thread d'écriture) Au cœur de OpenLDAP LMDB (LightningDB)
  • 27. Serveur paires clé-valeur Codé en C Basé sur des bibliothèques reconnues Protocole binaire Aucun contrôle d'erreur Implémentation naïve
  • 28. API très simple PUT Ajout ou mise-à-jour de clé GET Retourne une valeur DELETE Efface une clé
  • 29. Protocole : DELETE 2 cmd taille clé clé 1 1 1 à 255 octets Requête Réponse 1 statut 1
  • 30. Protocole : GET 3 cmd taille clé clé 1 1 1 à 255 octets Requête Réponse 1 statut taille données données 1 4 0 à 4 GO
  • 31. Protocole : PUT 1 cmd taille clé clé 1 1 1 à 255 octets Requête Réponse 1 statut taille données données 1 4 0 à 4 GO
  • 32. Multi-threadé Thread principal Attend les nouvelles connexions Threads de communication Un thread par client connecté Thread d'écriture Pas d'écriture concurrente
  • 33. Thread principal Threads de communication LMDB Thread d'écriture
  • 36. Démarrage /* * db Pointer to the database environment. * socket Socket descriptor for incoming connections. * threads_socket Nanomsg socket for threads communication. * writer_tid ID of the writer thread. * comm_threads Array of communication threads. */ typedef struct angstrom_s { MDB_env *db; int socket; int threads_socket; pthread_t writer_tid; struct comm_thread_s *comm_threads; } angstrom_t; /* * tid Thread's identifier. * angstrom Pointer to the server's structure. * client_sock Socket used to communicate with the client. * writer_sock Nanomsg socket to send data to the writer. */ typedef struct comm_thread_s { pthread_t tid; angstrom_t *angstrom; int client_sock; int writer_sock; } comm_thread_t; angstrom.h
  • 37. Démarrage int main() { angstrom_t *angstrom; int i; // server init angstrom = calloc(1, sizeof(angstrom_t)); angstrom->socket = angstrom->threads_socket = -1; angstrom->comm_threads = calloc(NBR_THREADS, sizeof(comm_thread_t)); // open the database angstrom->db = database_open(DEFAULT_DB_PATH, DEFAULT_MAPSIZE, NBR_THREADS); // create the nanomsg socket for threads communication angstrom->threads_socket = nn_socket(AF_SP, NN_PUSH); nn_bind(angstrom->threads_socket, ENDPOINT_THREADS_SOCKET); // create the writer thread pthread_create(&angstrom->writer_tid, NULL, thread_writer_loop, angstrom); main.c
  • 38. Démarrage int main() { angstrom_t *angstrom; int i; // server init angstrom = calloc(1, sizeof(angstrom_t)); angstrom->socket = angstrom->threads_socket = -1; angstrom->comm_threads = calloc(NBR_THREADS, sizeof(comm_thread_t)); // open the database angstrom->db = database_open(DEFAULT_DB_PATH, DEFAULT_MAPSIZE, NBR_THREADS); // create the nanomsg socket for threads communication angstrom->threads_socket = nn_socket(AF_SP, NN_PUSH); nn_bind(angstrom->threads_socket, ENDPOINT_THREADS_SOCKET); // create the writer thread pthread_create(&angstrom->writer_tid, NULL, thread_writer_loop, angstrom); main.c "inproc://threads_socket"
  • 39. Démarrage // create communication threads for (i = 0; i < NBR_THREADS; i++) { comm_thread_t *thread = &(angstrom->comm_threads[i]); thread->client_sock = -1; thread->angstrom = angstrom; pthread_create(&thread->tid, 0, thread_comm_loop, thread); pthread_detach(thread->tid); } // create listening socket angstrom->socket = _create_listening_socket(DEFAULT_PORT); // server loop _main_thread_loop(angstrom); return (0); } main.c
  • 40. Démarrage MDB_env *database_open(const char *path, size_t mapsize, unsigned int nbr_threads) { MDB_env *env = NULL; mdb_env_create(&env); mdb_env_set_mapsize(env, mapsize); mdb_env_set_maxreaders(env, nbr_threads); mdb_env_open(env, path, 0, 0664); return (env); } database.c
  • 41. Démarrage static int _create_listening_socket(unsigned short port) { int sock; struct sockaddr_in addr; unsigned int addr_size; const int on = 1; // create the socket sock = socket(AF_INET, SOCK_STREAM, 0); // some options setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (void*)&on, sizeof(on)); setsockopt(sock, SOL_SOCKET, SO_KEEPALIVE, (void*)&on, sizeof(on)); // binding to any interface addr_size = sizeof(addr); bzero(&addr, addr_size); addr.sin_addr.s_addr = htonl(INADDR_ANY); addr.sin_family = AF_INET; addr.sin_port = htons(port); bind(sock, (struct sockaddr*)&addr, addr_size); listen(sock, SOMAXCONN); return (sock); } main.c
  • 42. Nouvelle connexion static void _main_thread_loop(angstrom_t *angstrom) { int fd; struct sockaddr_in addr; unsigned int addr_size; const int on = 1; addr_size = sizeof(addr); for (; ; ) { bzero(&addr, addr_size); // accept a new connection if ((fd = accept(angstrom->socket, (struct sockaddr*)&addr, &addr_size)) < 0) { continue ; } setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, (void*)&on, sizeof(on)); // send the file descriptor number to comm threads nn_send(angstrom->threads_socket, &fd, sizeof(fd), 0); } } main.c
  • 43. Nouvelle connexion void *thread_comm_loop(void *param) { comm_thread_t *thread = param; int in_sock; // opening a connection to the writer thread thread->writer_sock = nn_socket(AF_SP, NN_PUSH); nn_connect(thread->writer_sock, ENDPOINT_WRITER_SOCKET); // opening a connection to the main thread in_sock = nn_socket(AF_SP, NN_PULL); nn_connect(in_sock, ENDPOINT_THREADS_SOCKET); // loop to process new connections for (; ; ) { // waiting for a new connection to handle nn_recv(in_sock, &thread->client_sock, sizeof(int), 0); // process connection _process_connection(thread); } return (NULL); } thread_com munication.c
  • 44. Nouvelle connexion void *thread_comm_loop(void *param) { comm_thread_t *thread = param; int in_sock; // opening a connection to the writer thread thread->writer_sock = nn_socket(AF_SP, NN_PUSH); nn_connect(thread->writer_sock, ENDPOINT_WRITER_SOCKET); // opening a connection to the main thread in_sock = nn_socket(AF_SP, NN_PULL); nn_connect(in_sock, ENDPOINT_THREADS_SOCKET); // loop to process new connections for (; ; ) { // waiting for a new connection to handle nn_recv(in_sock, &thread->client_sock, sizeof(int), 0); // process connection _process_connection(thread); } return (NULL); } thread_com munication.c "inproc://writer_socket" "inproc://threads_socket"
  • 45. Nouvelle connexion static void _process_connection(comm_thread_t *thread) { uint8_t cmd; // loop on incoming requests for (; ; ) { // read command byte if (read(thread->client_sock, &cmd, sizeof(cmd)) <= 0) { close(thread->client_sock); break; } // interpret command switch (cmd) { case PROTO_PUT: command_put(thread); break; case PROTO_DELETE: command_del(thread); break; case PROTO_GET: command_get(thread); break; } } } thread_com munication.c
  • 46. Lecture de données void command_get(comm_thread_t *thread) { uint8_t key_size, response = PROTO_OK; uint32_t value_size; MDB_val key, value; // read key length read(thread->client_sock, &key_size, sizeof(key_size)); // read key data key.mv_data = malloc(key_size); read(thread->client_sock, key.mv_data, key_size); // get data key.mv_size = (size_t)key_size; database_get(thread->angstrom->db, &key, &value); // send response to the client write(thread->client_sock, &response, sizeof(response)); value_size = htonl((uint32_t)value.mv_size); write(thread->client_sock, &value_size, sizeof(value_size)); if (value_size) write(thread->client_sock, value.mv_data, value.mv_size); } command_ get.c
  • 47. Lecture de données void database_get(MDB_env *db, MDB_val *key, MDB_val *value) { MDB_dbi dbi; MDB_txn *txn; // transaction init mdb_txn_begin(db, NULL, MDB_RDONLY, &txn); // open database in read-write mode mdb_dbi_open(txn, NULL, 0, &dbi); // get data if (mdb_get(txn, dbi, key, value)) bzero(value, sizeof(*value)); // end of transaction mdb_txn_abort(txn); // close database mdb_dbi_close(db, dbi); } database.c
  • 48. Thread d'écriture /* * type Type of action (WRITE_PUT, WRITE_DEL). * key Size and content of the key. * value Size and content of the value. */ typedef struct writer_msg_s { enum { WRITE_PUT, WRITE_DEL } type; MDB_val key; MDB_val value; } writer_msg_t; angstrom.h
  • 49. Thread d'écriture void *thread_writer_loop(void *param) { angstrom_t *angstrom = param; int socket; // create the nanomsg socket for threads communication socket = nn_socket(AF_SP, NN_PULL); nn_bind(socket, ENDPOINT_WRITER_SOCKET); // loop to process new connections for (; ; ) { writer_msg_t *msg; // waiting for a new connection to handle if (nn_recv(socket, &msg, sizeof(writer_msg_t*), 0) < 0) continue; // processing switch (msg->type) { case WRITE_PUT: database_put(angstrom->db, &msg->key, &msg->value); break; case WRITE_DEL: database_del(angstrom->db, &msg->key); break; } thread_ writer.c
  • 50. Thread d'écriture void *thread_writer_loop(void *param) { angstrom_t *angstrom = param; int socket; // create the nanomsg socket for threads communication socket = nn_socket(AF_SP, NN_PULL); nn_bind(socket, ENDPOINT_WRITER_SOCKET); // loop to process new connections for (; ; ) { writer_msg_t *msg; // waiting for a new connection to handle if (nn_recv(socket, &msg, sizeof(writer_msg_t*), 0) < 0) continue; // processing switch (msg->type) { case WRITE_PUT: database_put(angstrom->db, &msg->key, &msg->value); break; case WRITE_DEL: database_del(angstrom->db, &msg->key); break; } thread_ writer.c "inproc://writer_socket"
  • 51. Thread d'écriture // free data if (msg->key.mv_data) free(msg->key.mv_data); if (msg->value.mv_data) free(msg->value.mv_data); free(msg); } return (NULL); } thread_ writer.c
  • 52. Effacement de clé void command_delete(comm_thread_t *thread) { uint8_t key_size, response = PROTO_OK; void *key; writer_msg_t *msg; // read key length read(thread->client_sock, &key_size, sizeof(key_size)); // read key data key = malloc(key_size); read(thread->client_sock, key, key_size); // create message msg = calloc(1, sizeof(writer_msg_t)); msg->type = WRITE_DEL; msg->key.mv_size = (size_t)key_size; msg->key.mv_data = key; // send the message to the writer thread nn_send(thread->writer_sock, &msg, sizeof(msg), 0); // send response to the client write(thread->client_sock, &response, sizeof(response)); } command_ delete.c
  • 53. Effacement de clé void database_del(MDB_env *db, MDB_val *key) { MDB_dbi dbi; MDB_txn *txn; // transaction init mdb_txn_begin(db, NULL, 0, &txn); // open database in read-write mode mdb_dbi_open(txn, NULL, 0, &dbi); // delete key mdb_del(txn, dbi, key, NULL); // close database mdb_dbi_close(db, dbi); // transaction commit mdb_txn_commit(txn); } database.c
  • 54. Ajout / mise-à-jour de clé void command_put(comm_thread_t *thread) { uint8_t key_size, response = PROTO_OK; void *key, *value = NULL; uint32_t value_size; writer_msg_t *msg; // read key length read(thread->client_sock, &key_size, sizeof(key_size)); // read key data key = malloc(key_size); read(thread->client_sock, key, key_size); // read value length read(thread->client_sock, &value_size, sizeof(value_size)); value_size = ntohl(value_size); if (value_size > 0) { // read value data value = malloc(value_size); read(thread->client_sock, value, value_size); } command_ put.c
  • 55. Ajout / mise-à-jour de clé // create message msg = malloc(sizeof(writer_msg_t)); msg->type = WRITE_PUT; msg->key.mv_size = (size_t)key_size; msg->key.mv_data = key; msg->value.mv_size = (size_t)value_size; msg->value.mv_data = value; // send the message to the writer thread nn_send(thread->writer_sock, &msg, sizeof(msg), 0); // send response to the client write(thread->client_sock, &response, sizeof(response)); } command_ put.c
  • 56. Ajout / mise-à-jour de clé void database_put(MDB_env *db, MDB_val *key, MDB_val *value) { MDB_dbi dbi; MDB_txn *txn; // transaction init mdb_txn_begin(db, NULL, 0, &txn); // open database in read-write mode mdb_dbi_open(txn, NULL, 0, &dbi); // put data mdb_put(txn, dbi, key, value, 0); // close database mdb_dbi_close(db, dbi); // transaction commit mdb_txn_commit(txn); } database.c
  • 57.
  • 58. cloc Language files comment code ------------------------------------------------- C 7 132 212 C Header 1 111 55 make 1 13 27 ------------------------------------------------- SUM: 9 256 294 sloccount Schedule Estimate, Years (Months) = 0.17 (2.06) Total Estimated Cost to Develop = $ 6,753
  • 59. Benchmark Base Écritures Lectures AngstromDB 22 ms 55 ms Couchbase 25 ms 22 ms Redis 29 ms 30 ms MongoDB 39 ms 27 ms 45 écritures / lectures séquentielles de données représentatives
  • 61. Réduire les appels systèmes ! Bufferiser les lectures réseau Regrouper les écritures réseau Facile à tester (sendmsg vs write) Pour commencer
  • 62. Benchmark Base Écritures Lectures AngstromDB 22 ms 55 ms AngstromDB 22 ms 26 ms Couchbase 25 ms 22 ms Redis 29 ms 30 ms MongoDB 39 ms 27 ms
  • 63. Compression à la volée (Zippy) Sérialisation de données (MsgPack) Transactions en lecture … Mono-processus asynchrone ? Pour aller plus loin