{"id":862,"date":"2017-03-01T08:00:32","date_gmt":"2017-03-01T08:00:32","guid":{"rendered":"http:\/\/blog.tiran.info\/?p=862"},"modified":"2017-12-05T14:24:41","modified_gmt":"2017-12-05T13:24:41","slug":"oracle-r-enterprise-1","status":"publish","type":"post","link":"https:\/\/blog.tiran.stream\/?p=862","title":{"rendered":"Oracle R Enterprise (#1)"},"content":{"rendered":"<p style=\"text-align: justify;\">Lorsque je teste une fonctionnalit\u00e9, j&rsquo;aime bien utiliser plusieurs approches afin de voir les forces et faiblesses de chacune. Dans le cadre d&rsquo;analyses statistiques avec Oracle, cela revient g\u00e9n\u00e9ralement \u00e0 comparer une impl\u00e9mentation bas\u00e9e sur SQL\/ODM avec son homologue bas\u00e9e sur R.<\/p>\n<p style=\"text-align: justify;\">Ici, dans la <a href=\"http:\/\/blog.tiran.info\/fonctions-approximatives-oracle-12-2-2\">continuit\u00e9 des billets pr\u00e9c\u00e9dents<\/a>, je me suis demand\u00e9 s&rsquo;il existait des packages R permettant de r\u00e9aliser un COUNT(DISTINCT) avec l&rsquo;algorithme d&rsquo;HyperLogLog. Je n&rsquo;en ai pas trouv\u00e9.<\/p>\n<p style=\"text-align: justify;\">N\u00e9anmoins, lors de mes investigations, j&rsquo;ai rencontr\u00e9 un probl\u00e8me beaucoup plus \u00e9pineux&#8230;<\/p>\n<p style=\"text-align: justify;\">Pour r\u00e9aliser le <a href=\"http:\/\/blog.tiran.info\/fonctions-approximatives-oracle-12-2-2\" target=\"_blank\" rel=\"noopener\">COUNT(DISTINCT) des donn\u00e9es de la table LOG_CONTRIBS<\/a>, j&rsquo;ai essay\u00e9 au pr\u00e9alable de la charger dans une session R via ROracle:<\/p>\n<pre class=\"brush: sql; ruler: true;\">&gt; library(ROracle)\r\nLoading required package: DBI\r\n&gt; ora = Oracle()\r\n&gt; cnx = dbConnect(ora, username=&quot;c##raf&quot;, password=&quot;Password1#&quot;, dbname=&quot;\/\/clorai2-scan:1521\/pdb_iotst04&quot;)\r\n&gt; wiki_contribs &lt;- dbGetQuery(cnx, &quot;select * from LOG_CONTRIBS&quot;)\r\n...\r\n<\/pre>\n<p style=\"text-align: justify;\">&#8230; et j&rsquo;ai attendu, attendu, attendu&#8230;<\/p>\n<p style=\"text-align: justify;\">En effet, par d\u00e9faut, R fonctionne de mani\u00e8re autonome en traitant les donn\u00e9es en m\u00e9moire. Donc, ici la fonction dbGetQuery r\u00e9alise le rapatriement vers le client de l&rsquo;ensemble des donn\u00e9es de la table LOG_CONTRIBS pour peupler le dataframe wiki_contribs.<br \/>\nMalheureusement, cette table est relativement volumineuse:<\/p>\n<pre class=\"brush: sql; ruler: true;\">SQL&gt; SELECT bytes \/ POWER (1024, 3) GB\r\n  2    FROM user_segments\r\n  3   WHERE segment_name = &#039;LOG_CONTRIBS&#039;;\r\n\r\n        GB\r\n----------\r\n    3.8125\r\n\r\nSQL&gt;\r\n<\/pre>\n<p style=\"text-align: justify;\">Cette approche est tout \u00e0 fait valide lorsqu&rsquo;on manipule de petits jeux de donn\u00e9es mais elle devient inop\u00e9rante \u00e0 mesure que les volumes augmentent.<\/p>\n<p style=\"text-align: justify;\">Par curiosit\u00e9, j&rsquo;ai tach\u00e9 de suivre sur ma machine l&rsquo;allocation de la m\u00e9moire virtuelle du\u00a0processus rsession au fur et \u00e0 mesure du chargement de la table. Pour cela, j&rsquo;ai utilis\u00e9 une collecte perfmon dont le param\u00e9trage appara\u00eet dans les deux copies d&rsquo;\u00e9cran ci-dessous:<\/p>\n<p style=\"text-align: justify;\"><a href=\"https:\/\/blog.tiran.stream\/wp-content\/uploads\/2017\/02\/CollecteVMRsession.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter wp-image-868 size-medium\" src=\"https:\/\/blog.tiran.stream\/wp-content\/uploads\/2017\/02\/CollecteVMRsession.png\" width=\"300\" height=\"232\" \/><\/a><\/p>\n<p style=\"text-align: justify;\"><a href=\"https:\/\/blog.tiran.stream\/wp-content\/uploads\/2017\/02\/CollecteVMRsession.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter wp-image-867 size-medium\" src=\"https:\/\/blog.tiran.stream\/wp-content\/uploads\/2017\/02\/CollecteVMRsession2.png\" width=\"269\" height=\"300\" \/><br \/>\n<\/a><\/p>\n<p style=\"text-align: justify;\">Le r\u00e9sultat est un fichier csv:\u00a0<a href=\"https:\/\/blog.tiran.stream\/wp-content\/uploads\/2017\/02\/DataCollector01.zip\">DataCollector01<\/a>\u00a0dont les donn\u00e9es ont \u00e9t\u00e9 repr\u00e9sent\u00e9es&#8230; avec R \ud83d\ude09<\/p>\n<pre class=\"brush: sql; ruler: true;\">&gt; Rsession &lt;- read.csv2(&quot;C:\/PerfLogs\/Admin\/Suivi VM R\/S1401037_20170222-000001\/DataCollector01.csv&quot;, encoding=&quot;UTF-8&quot;, sep=&quot;,&quot;)\r\n&gt; names(Rsession) &lt;- c(&quot;Dt&quot;,&quot;VMSize&quot;)\r\n&gt; \r\n&gt; Rsession$Dt &lt;- strptime(Rsession$Dt, &quot;%m\/%d\/%Y %H:%M:%OS&quot;)\r\n&gt; Rsession$VMSize &lt;- Rsession$VMSize\/(1024^3)\r\n&gt; \r\n&gt; summary(Rsession)\r\n       Dt                          VMSize       \r\n Min.   :2017-02-22 10:37:58   Min.   : 0.3463  \r\n 1st Qu.:2017-02-22 10:48:07   1st Qu.: 2.4995  \r\n Median :2017-02-22 10:58:16   Median : 4.6035  \r\n Mean   :2017-02-22 10:58:24   Mean   : 4.7239  \r\n 3rd Qu.:2017-02-22 11:08:25   3rd Qu.: 6.7383  \r\n Max.   :2017-02-22 11:22:28   Max.   :11.2029  \r\n&gt; \r\n&gt; library(ggplot2)\r\n&gt; \r\n&gt; ggplot(data=Rsession, aes(x=Dt, y=VMSize)) +\r\n+   geom_line(color=&quot;blue&quot;) + \r\n+   xlab(&quot;Heure&quot;) + \r\n+   ylab(&quot;Taille en GB&quot;) + \r\n+   theme_classic()+\r\n+   ggtitle(&quot;Evolution de la m\u00e9moire virtuelle du processus rsession&quot;) +\r\n+   theme(plot.title = element_text(hjust = 0.5)) +\r\n+   theme(panel.grid.major = element_line(linetype = &quot;dotted&quot;)) + \r\n+   scale_y_continuous(breaks = seq(0, 12),limits = c(0,11.5))\r\n&gt; \r\n<\/pre>\n<p style=\"text-align: justify;\"><a href=\"https:\/\/blog.tiran.stream\/wp-content\/uploads\/2017\/02\/Evol_VM_Rsession.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter wp-image-877 size-full\" src=\"https:\/\/blog.tiran.stream\/wp-content\/uploads\/2017\/02\/Evol_VM_Rsession.png\" width=\"660\" height=\"553\" \/><\/a><\/p>\n<p style=\"text-align: justify;\">On voit donc que la taille de la m\u00e9moire virtuelle du processus a augment\u00e9e jusqu&rsquo;\u00e0 atteindre 11.2GB:<\/p>\n<p style=\"text-align: justify;\"><a href=\"https:\/\/blog.tiran.stream\/wp-content\/uploads\/2017\/02\/CollecteVMRsession3.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter wp-image-866 size-full\" src=\"https:\/\/blog.tiran.stream\/wp-content\/uploads\/2017\/02\/CollecteVMRsession3.png\" width=\"1072\" height=\"53\" \/><\/a><\/p>\n<p style=\"text-align: justify;\">Ma machine disposant de 8GB de RAM, cela signifie qu&rsquo;une partie de l&rsquo;allocation provenait de l&rsquo;espace de swap.<\/p>\n<p style=\"text-align: justify;\">Il a fallu environ 40 minutes pour que le dataframe wiki_contribs soit peupl\u00e9. Cela-dit \u00e0 ce stade, l&rsquo;interface RStudio \u00e9tait compl\u00e8tement gel\u00e9e et il m&rsquo;\u00e9tait impossible de travailler sur ce dataframe&#8230;<\/p>\n<p style=\"text-align: justify;\">Pas d&rsquo;autre choix que d&rsquo;interrompre le processus:<\/p>\n<p style=\"text-align: justify;\"><a href=\"https:\/\/blog.tiran.stream\/wp-content\/uploads\/2017\/02\/R-Abort.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-medium wp-image-865\" src=\"https:\/\/blog.tiran.stream\/wp-content\/uploads\/2017\/02\/R-Abort-300x203.png\" alt=\"\" width=\"300\" height=\"203\" \/><\/a><\/p>\n<p style=\"text-align: justify;\">On comprend d\u00e8s lors la grande limitation de la version communautaire de R. Les donn\u00e9es de travail sont r\u00e9cup\u00e9r\u00e9es localement ce qui s&rsquo;av\u00e8re non scalable. Dans la m\u00eame veine, R travaille de mani\u00e8re s\u00e9rielle et ne propose pas, par d\u00e9faut, de parall\u00e9lisation des algorithmes.<\/p>\n<p style=\"text-align: justify;\">C&rsquo;est la raison d&rsquo;\u00eatre de l&rsquo;<a href=\"http:\/\/www.oracle.com\/technetwork\/database\/database-technologies\/r\/r-enterprise\/overview\/index.html\" target=\"_blank\" rel=\"noopener\">offre Oracle R Entreprise<\/a> qui permet de s&rsquo;affranchir de ces probl\u00e8mes. En effet, les donn\u00e9es restent au sein de la base Oracle (pas de rapatriement au niveau du client) et des moteurs R sont instanci\u00e9s directement sur le serveur de base de donn\u00e9es. Une couche d&rsquo;abstraction entre le client R et la base permet de transformer le code R en SQL de mani\u00e8re transparente.<\/p>\n<p style=\"text-align: justify;\">Ce sera l&rsquo;objet des prochains articles!<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Lorsque je teste une fonctionnalit\u00e9, j&rsquo;aime bien utiliser plusieurs approches afin de voir les forces et faiblesses de chacune. Dans<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"colormag_page_container_layout":"default_layout","colormag_page_sidebar_layout":"default_layout","footnotes":""},"categories":[9],"tags":[],"class_list":["post-862","post","type-post","status-publish","format-standard","hentry","category-oracle-r-enterprise"],"_links":{"self":[{"href":"https:\/\/blog.tiran.stream\/index.php?rest_route=\/wp\/v2\/posts\/862","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/blog.tiran.stream\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blog.tiran.stream\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blog.tiran.stream\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.tiran.stream\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=862"}],"version-history":[{"count":1,"href":"https:\/\/blog.tiran.stream\/index.php?rest_route=\/wp\/v2\/posts\/862\/revisions"}],"predecessor-version":[{"id":1166,"href":"https:\/\/blog.tiran.stream\/index.php?rest_route=\/wp\/v2\/posts\/862\/revisions\/1166"}],"wp:attachment":[{"href":"https:\/\/blog.tiran.stream\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=862"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.tiran.stream\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=862"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.tiran.stream\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=862"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}