MongoDB : la base NoSQL qui réinvente la gestion de données

7843bb075c05be6886a97b77e36758ff?s=47 David
November 27, 2013

MongoDB : la base NoSQL qui réinvente la gestion de données

Foursquare utilise MongoDB, Criteo utilise MongoDB…
Quelles sont les caractéristiques de cette base ? les uses cases ? Quels sont les avantages et les défauts de MongoDB ?
Pour cela, nous verrons le fonctionnement de cette base de données, la description des documents, les notions de replicat-set, sharding, mais aussi des cas d’utilisation possible en environnement BigData et NoBigData !
Et pourquoi ne pas finir en créant une petite application se basant sur MongoDB ?

7843bb075c05be6886a97b77e36758ff?s=128

David

November 27, 2013
Tweet

Transcript

  1. MongoDB Big Database @DWURSTEISEN

  2. http://fr.slideshare.net/soatexpert

  3. None
  4. WARNING

  5. None
  6. Il n’y a pas si longtemps que cela, un site

    internet faisait sensation…
  7. None
  8. None
  9. 20:00:00

  10. Ce site déboite

  11. Oups ! Database Error

  12. no more space disk available

  13. None
  14. None
  15. None
  16. None
  17. None
  18. None
  19. BIG DATA

  20. Animation Soat Devoxx France 2013

  21. Caractéristiques (sous le capot)

  22. Orienté document

  23. None
  24. {! "_id": "enigme1", ! "titre": "Enigme du vendredi", ! "activation":

    true! }
  25. {! "_id": "enigme1", ! "titre": "Enigme du vendredi", ! "activation":

    true! } {! "_id": "enigme1", ! "activation": true, ! "joueurs": [! { "email": "john@doe.com", "score": 20 }! ], ! "indices": [! {! "contenu": "je suis ton père",! "flashcode": "111-111-1111", ! "joueurs": [ { "email": "john@doe.com" } ]! } ]! }!
  26. Sans schéma

  27. CREATE TABLE example_default_now ( id INT NOT NULL PRIMARY KEY

    AUTO_INCREMENT, data VARCHAR(100), created TIMESTAMP DEFAULT NOW() );
  28. CREATE TABLE example_default_now ( id INT NOT NULL PRIMARY KEY

    AUTO_INCREMENT, data VARCHAR(100), created TIMESTAMP DEFAULT NOW() );
  29. Sans transaction

  30. Transaction

  31. Transaction

  32. Transaction

  33. Transaction

  34. Transaction

  35. Transaction

  36. Sans transaction

  37. Sans transaction

  38. Sans transaction

  39. Sans transaction

  40. Update atomique

  41. Sans jointure

  42. {! "_id": "enigme1", ! "activation": true, ! "joueurs": [! {

    "email": "john@doe.com", "score": 20 }! ], ! "indices": [! {! "contenu": "je suis ton père",! "flashcode": "111-111-1111", ! "joueurs": [ { "email": "john@doe.com" } ]! } ]! }!
  43. {! "_id": "enigme1", ! "activation": true, ! "joueurs": [! {

    "email": "john@doe.com", "score": 20 }! ], ! "indices": [! {! "contenu": "je suis ton père",! "flashcode": "111-111-1111", ! "joueurs": [ { "email": "john@doe.com" } ]! } ]! }! jointure ?
  44. Distribué

  45. Document = 16Mb Hard Limit

  46. Design  des structures  des données

  47. Type Exemple Int / Double / … { a: 1

    } Boolean { b: true } String { c: ‘hello’ } Array { d: [1, 2, 3] } Date {e: ISODate("2012-12-19T06:01:17.171Z") ObjectId {f: ObjectId(‘123456’)} Object {g: {a: 1, b: true}} … http://docs.mongodb.org/manual/reference/bson-types/
  48. Organiser les données selon leurs Utilisations

  49. None
  50. ci gît la 
 4ème forme 
 normale

  51. Structure de donnée pour l’affichage d’un message ? Question :

  52. 2

  53. 2 Auteur

  54. 2 Auteur Contenu

  55. 2 Auteur Contenu Recouicoui

  56. { _id: ObjectId(11),

  57. { _id: ObjectId(11), user: {mail: « user1 », avatar: «

    http://…. »,
  58. { _id: ObjectId(11), user: {mail: « user1 », avatar: «

    http://…. », content: « blabla »,
  59. { _id: ObjectId(11), user: {mail: « user1 », avatar: «

    http://…. », content: « blabla », …
  60. { _id: ObjectId(11), user: {mail: « user1 », avatar: «

    http://…. », content: « blabla », … recouicoui: [ObjectId(22), ObjectId(33)]
  61. { _id: ObjectId(11), user: {mail: « user1 », avatar: «

    http://…. », content: « blabla », … ! recouicoui: 2, // compteur
  62. { _id: ObjectId(11), user: {mail: « user1 », avatar: «

    http://…. », content: « blabla », … ! recouicoui: [{user: {…}, {user: {…}]
  63. None
  64. None
  65. None
  66. None
  67. { _id: ObjectId(11), user: {mail: « user1 », avatar: «

    http://…. », content: « blabla », … ! recouicoui: [{user: {…}, {user: {…}]
  68. { _id: ObjectId(11), user: {mail: « user1 », avatar: «

    http://…. », content: « blabla », … ! recouicoui: [{user: {…} * 789013]
  69. { _id: ObjectId(11), user: {mail: « user1 », avatar: «

    http://…. », content: « blabla », … ! recouicoui: [{user: {…} * 789013] > 16Mb
  70. 2

  71. 2 Information partielle

  72. { _id: ObjectId(11), user: {mail: « user1 », avatar: «

    http://…. », content: « blabla », … recouicoui: { users: [{user: {…} * 5], compteur: 789013 }
  73. bonne complexe structure de donnée est Le design d’une

  74. Parlez-vous Français ? Query language select * from table

  75. Le shell : mongo

  76. Lecture

  77. Sélection d’un document db.collection.findOne(…)

  78. Sélection d’un document db.collection.findOne(…) Query

  79. Sélection de documents db.collection.find(…)

  80. Sélection et mise à jour de document db.collection.findAndModify(…)

  81. Champ unique {_id: ‘azerty’}

  82. Champ unique {_id: ‘azerty’} {! "_id": "azerty", ! "titre": "Enigme

    du vendredi", ! "activation": true! } ✓
  83. Champ unique {_id: ‘azerty’} {! "_id": "azerty", ! "titre": "Enigme

    du vendredi", ! "activation": true! } ✓ {! "_id": "azerty", ! "activation": true,! "titre": "Enigme du vendredi"! } ✓
  84. {! "_id": "azerty12345", ! "activation": true,! "titre": "Enigme du vendredi"!

    } ✗ Champ unique {_id: ‘azerty’} {! "_id": "azerty", ! "titre": "Enigme du vendredi", ! "activation": true! } ✓ {! "_id": "azerty", ! "activation": true,! "titre": "Enigme du vendredi"! } ✓
  85. Sous document spécifique {auteur: {nom: ‘Wursteisen’}}

  86. Sous document spécifique {auteur: {nom: ‘Wursteisen’}} {! "_id": "azerty", !

    "auteur": {"nom":"Wursteisen"}! } ✓
  87. Sous document spécifique {auteur: {nom: ‘Wursteisen’}} {! "_id": "azerty", !

    "auteur": {"nom":"Wursteisen"}! } ✓ {! "_id": "azerty", ! "auteur": {"nom":"Wursteisen", "prénom":"David"}! } ✗
  88. Sous document spécifique {auteur: {prénom: ‘David’, nom: ‘Wursteisen’}}

  89. Sous document spécifique {auteur: {prénom: ‘David’, nom: ‘Wursteisen’}} {! "_id":

    "azerty", ! "auteur": {"prénom":"David", "nom":"Wursteisen"}! } ✓
  90. Sous document spécifique {auteur: {prénom: ‘David’, nom: ‘Wursteisen’}} {! "_id":

    "azerty", ! "auteur": {"prénom":"David", "nom":"Wursteisen"}! } ✓ {! "_id": "azerty", ! "auteur": {"nom":"Wursteisen", "prénom":"David"}! } ✗
  91. Sous champ {‘auteur.nom’: ‘Wursteisen’}

  92. Sous champ {‘auteur.nom’: ‘Wursteisen’} {! "_id": "azerty", ! "auteur": {"nom":"Wursteisen"}!

    } ✓
  93. Sous champ {‘auteur.nom’: ‘Wursteisen’} {! "_id": "azerty", ! "auteur": {"nom":"Wursteisen"}!

    } ✓ {! "_id": "azerty", ! "auteur": {"nom":"Wursteisen", "prénom":"David"}! } ✓
  94. Sous champ {‘auteur.nom’: ‘Wursteisen’} {! "_id": "azerty", ! "auteur": {"nom":"Wursteisen"}!

    } ✓ {! "_id": "azerty", ! "auteur": {"nom":"Wursteisen", "prénom":"David"}! } ✓ {! "_id": "azerty", ! "auteur": {"nom":"Bob", "prénom":"David"}! } ✗
  95. Champ unique {recouicoui: {$gt: 20}}

  96. Champ unique {recouicoui: {$gt: 20}} {! "_id": "azerty", ! "titre":

    "Enigme du vendredi", ! "recouicoui": 50! } ✓
  97. Champ unique {recouicoui: {$gt: 20}} {! "_id": "azerty", ! "titre":

    "Enigme du vendredi", ! "recouicoui": 50! } ✓ {! "_id": "azerty", ! "titre": "Enigme du vendredi", ! "recouicoui": 10! } ✗
  98. Champ unique {recouicoui: {$gt: 20}} {! "_id": "azerty", ! "titre":

    "Enigme du vendredi", ! "recouicoui": 50! } ✓ {! "_id": "azerty", ! "titre": "Enigme du vendredi", ! "recouicoui": 10! } ✗ {! "_id": "azerty", ! "titre": "Enigme du vendredi", ! ! } ✗
  99. Écriture

  100. Insertion d’un document db.collection.insert(…)

  101. Insertion d’un document db.collection.insert(…) Document

  102. Update d’un document db.collection.update(<query>, <update>)

  103. Update d’un document db.collection.update(<query>, <update>) modifier

  104. Update de documents db.collection.update(…, …, {multi: true})

  105. Écrire un document db.collection.update(…, {prénom:’David’})

  106. Écrire un document db.collection.update(…, {prénom:’David’}) {! "_id": "azerty", ! "nom":

    "wursteisen", ! "prénom": "bob"! }
  107. Écrire un document db.collection.update(…, {prénom:’David’}) {! "_id": "azerty", ! "nom":

    "wursteisen", ! "prénom": "bob"! } {! "_id": "azerty", ! "prénom": "David"! }
  108. Modifier un champ db.collection.update(…, {$set: {prénom:’David’}})

  109. Modifier un champ db.collection.update(…, {$set: {prénom:’David’}}) {! "_id": "azerty", !

    "nom": "wursteisen", ! "prénom": "bob"! }
  110. Modifier un champ db.collection.update(…, {$set: {prénom:’David’}}) {! "_id": "azerty", !

    "nom": "wursteisen", ! "prénom": "bob"! } {! "_id": "azerty", ! "nom": "wursteisen", ! "prénom": "David"! }
  111. Incrémentation db.collection.update(…, {$inc: {recouicoui: 2 }})

  112. Incrémentation db.collection.update(…, {$inc: {recouicoui: 2 }}) {! "_id": "azerty", !

    "nom": "wursteisen", ! "recouicoui": 5! }
  113. Incrémentation db.collection.update(…, {$inc: {recouicoui: 2 }}) {! "_id": "azerty", !

    "nom": "wursteisen", ! "recouicoui": 5! } {! "_id": "azerty", ! "nom": "wursteisen", ! "recouicoui": 7! }
  114. Ajout dans un tableau db.collection.update(…, {$push: {contact: ‘Robert’ }})

  115. Ajout dans un tableau db.collection.update(…, {$push: {contact: ‘Robert’ }}) {!

    "_id": "azerty", ! "contact": ["John", "Bob"] ! }
  116. Ajout dans un tableau db.collection.update(…, {$push: {contact: ‘Robert’ }}) {!

    "_id": "azerty", ! "contact": ["John", "Bob"] ! } {! "_id": "azerty", ! "contact": ["John", "Bob", "Robert"] ! }
  117. Index

  118. db.couicoui.ensureIndex({ name:1 }) Index simple

  119. db.couicoui.ensureIndex({ name:1, date:-1 }) Index composé

  120. db.couicoui.ensureIndex({ geo: ‘2d‘ }) Géo index

  121. None
  122. db.couicoui.ensureIndex({ name:1 }, {expireAfterSeconds: 3600}) Index avec Time To Live

  123. db.find({…}).explain()

  124. { "cursor" : "<Cursor Type and Index>", "n" : <num>,

    "nscanned" : <num>, "scanAndOrder" : <boolean>, … }
  125. Replica Set

  126. Driver Primary Secondary Secondary

  127. Driver Primary Secondary Secondary Écriture

  128. Driver Primary Secondary Secondary Écriture Réplication

  129. Driver Primary Secondary Secondary Écriture Réplication Réplication

  130. Driver Primary Secondary Secondary Écriture Réplication Réplication Lecture

  131. Driver Primary Secondary Secondary Écriture Réplication Réplication Lecture Lecture

  132. Primary Secondary Secondary

  133. Primary Secondary Secondary Heartbeats

  134. Primary Secondary Secondary Heartbeats

  135. Primary Secondary Secondary

  136. Primary Secondary Secondary Primary ?

  137. Primary Primary Secondary Primary ?

  138. Primary Primary Secondary Primary ? Réplication

  139. Primary Primary Secondary Primary ? Réplication

  140. Primary Primary Secondary Primary ? Réplication Heartbeats

  141. Primary Primary Secondary Primary ? Réplication Heartbeats

  142. Secondary Primary Secondary Primary ? Réplication Heartbeats

  143. Secondary Primary Secondary Primary ? Réplication Heartbeats

  144. None
  145. None
  146. None
  147. None
  148. None
  149. None
  150. None
  151. Write Concern notification d’écriture

  152. collection.insert(…, WriteConcern.ACKNOWLEDGED); ! db.getLastError(); (dépendant du driver)

  153. collection.insert(…, WriteConcern.ACKNOWLEDGED); ! db.getLastError(); (dépendant du driver) w=1

  154. collection.insert(…, WriteConcern.ACKNOWLEDGED); ! db.getLastError(); (dépendant du driver) w=1 bloquant

  155. disable acknowledgment w=0

  156. Driver Mongod

  157. write Driver Mongod

  158. write Driver Mongod getLastError
 w=0

  159. write Driver Mongod getLastError response getLastError
 w=0

  160. acknowledgment w=1

  161. Driver Mongod

  162. write Driver Mongod

  163. write Driver Mongod getLastError
 w=1

  164. write Driver Mongod getLastError
 w=1 apply

  165. write Driver Mongod getLastError response getLastError
 w=1 apply

  166. write Driver Mongod getLastError response getLastError
 w=1 apply bloquant

  167. journal j=1

  168. Driver Mongod

  169. write Driver Mongod

  170. write Driver Mongod getLastError
 w=1,j=1

  171. write Driver Mongod getLastError
 w=1,j=1 apply

  172. write Driver Mongod getLastError
 w=1,j=1 apply write to journal

  173. write Driver Mongod getLastError response getLastError
 w=1,j=1 apply write to

    journal
  174. write Driver Mongod getLastError response getLastError
 w=1,j=1 apply write to

    journal bloquant
  175. replica acknowledgment w=2

  176. Driver Primary Secondary Secondary

  177. write Driver Primary Secondary Secondary

  178. write Driver Primary getLastError
 w=2 Secondary Secondary

  179. write Driver Primary getLastError
 w=2 apply Secondary Secondary

  180. write Driver Primary getLastError
 w=2 apply Secondary Secondary replicate

  181. write Driver Primary getLastError
 w=2 apply Secondary Secondary replicate

  182. write Driver Primary getLastError response getLastError
 w=2 apply Secondary Secondary

    replicate
  183. write Driver Primary getLastError response getLastError
 w=2 apply Secondary Secondary

    replicate bloquant
  184. write Driver Primary getLastError response getLastError
 w=2 apply Secondary Secondary

    replicate replicate bloquant
  185. Sharding Répartition

  186. collection

  187. Shard2 Shard3 Shard1 collection

  188. Shard2 Shard3 Shard1 collection {x: min} {x: max} {x: -11}

    {x: 50}
  189. Avec une clé de sharding

  190. Mongos db.collect.find({key: …})

  191. Mongos db.collect.find({key: …})

  192. Mongos db.collect.find({key: …})

  193. Mongos db.collect.find({key: …})

  194. Mongos db.collect.find({key: …})

  195. Avec une clé non shardé

  196. Mongos db.collect.find({other: …})

  197. Mongos db.collect.find({other: …})

  198. Mongos db.collect.find({other: …})

  199. Clé de sharding pour gérer 
 les messages d’un utilisateur

    ? Question :
  200. Cardinalité Répartition en écriture Isolation Fiabilité _id

  201. ObjectId(« 507f1f77bcf86cd799439011 ») http://www.mongodb.com/presentations/advanced-sharding-features-mongodb-24

  202. ObjectId(« 507f1f77bcf86cd799439011 ») http://www.mongodb.com/presentations/advanced-sharding-features-mongodb-24 Timestamp

  203. ObjectId(« 507f1f77bcf86cd799439011 ») http://www.mongodb.com/presentations/advanced-sharding-features-mongodb-24 Timestamp Host

  204. ObjectId(« 507f1f77bcf86cd799439011 ») http://www.mongodb.com/presentations/advanced-sharding-features-mongodb-24 Timestamp Host PID

  205. ObjectId(« 507f1f77bcf86cd799439011 ») http://www.mongodb.com/presentations/advanced-sharding-features-mongodb-24 Timestamp Host Compteur PID

  206. ObjectId(« 507f1f77bcf86cd799439011 ») http://www.mongodb.com/presentations/advanced-sharding-features-mongodb-24 Timestamp

  207. Cardinalité Répartition en écriture Isolation Fiabilité _id ✓ ✗ ✗

  208. Mongos db.collect.insert({…})

  209. Mongos db.collect.insert({…})

  210. Mongos db.collect.find({…})

  211. Mongos db.collect.find({…})

  212. Mongos db.collect.find({…})

  213. Cardinalité Répartition en écriture Isolation Fiabilité _id ✓ ✗ ✗

    ✗ hash(_id) ✓ ✓ ✗ ✗
  214. Mongos db.collect.insert({…})

  215. Mongos db.collect.insert({…})

  216. Mongos db.collect.insert({…})

  217. Mongos db.collect.insert({…})

  218. Mongos db.collect.find({…})

  219. Mongos db.collect.find({…})

  220. Mongos db.collect.find({…})

  221. Cardinalité Répartition en écriture Isolation Fiabilité _id ✓ ✗ ✗

    ✗ hash(_id) ✓ ✓ ✗ ✗ user ✗ ✓ ✓ ✓
  222. Mongos db.collect.insert({…})

  223. Mongos db.collect.insert({…})

  224. Mongos db.collect.insert({…})

  225. Mongos db.collect.insert({…})

  226. Mongos db.collect.find({…})

  227. Mongos db.collect.find({…})

  228. Mongos db.collect.find({…})

  229. Cardinalité Répartition en écriture Isolation Fiabilité _id ✓ ✗ ✗

    ✗ hash(_id) ✓ ✓ ✗ ✗ user ✗ ✓ ✓ ✓ user, time ✓ ✓ ✓ ✓
  230. Mongos db.collect.insert({…})

  231. Mongos db.collect.insert({…})

  232. Mongos db.collect.insert({…})

  233. Mongos db.collect.insert({…})

  234. Mongos db.collect.find({…})

  235. Mongos db.collect.find({…})

  236. Mongos db.collect.find({…})

  237. Aller plus loin…

  238. https://education.mongodb.com

  239. http://www.meetup.com/Paris-MongoDB-User-Group/

  240. Demo

  241. https://github.com/dwursteisen/atelier-mongodb

  242. Questions ? @dwursteisen

  243. Crédits photos

  244. http://bit.ly/HNvkfZ http://bit.ly/HGb1BO http://bit.ly/1d5OVTr http://bit.ly/1awf0XL http://bit.ly/MMaRr8 http://bit.ly/1hTARzS http://bit.ly/1hrvZ7z http://bit.ly/17SGXwC http://bit.ly/HNvRP4

  245. http://bit.ly/HGf2Gh http://bit.ly/1967kv2 http://bit.ly/1c6uCUA