ZEP-11 : Interface de statistiques sur les tutoriels

Des chiffres, des graphes, du kikimeter !

a marqué ce sujet comme résolu.

Je trouve ça très étrange quand même qu'on arrive à 1Go pour à peine 50K entrées par jour. Sur un mois d'extraction de données assez complètes sur des volumes de 300 000 et 550 000 entrées par jour, avec trois tables de réplications (précalculs, réorganisation) et des index fulltext sur deux champs, je n'ai que 2Go de pris sur 1 mois entier. On est très loin d'un besoin de 400Go.

(Nota : j'utilise MySQL, les logs à partir desquels sont générés la BDD font en moyenne 50Mo à 65Mo)

@firm1 : je reste persuadé qu'estimer la taille a partir d'un seul document est probablement pas pertinent. Fait au moins un test avec quelques centaines de documents, ce sera plus proche de la réalité.

Kje

Suite cette remarque de Kje, j'ai relancé le chargement du même document 100 fois dans ma base MongoDB, j'arrive à un espace de stockage de 5384 Ko ce qui équivaut à ~5.2 Mo ce qui est effectivement loin de 25 Mo estimé. Mais je ne peux pas objectivement me baser sur ce chiffre car j'ai importé la même collection, et étant donné que MongoDB est intelligent, il ne duplique pas un document. Mais dans la réalité, les documents seront certainement différent.

Du coup, je dirais que les 1Go/jour seraient dans le pire des cas.

@firm1 : même si nos données viennent de nos logs et pas de Google Analytics, explique-moi comment tu peux avoir besoin de 14 fois plus de place que ce que je propose ?

Dominus Carnufex

C'est très certainement parce que dans ton calcul tu oublie aussi la taille des index (et en il faudra beaucoup). Les index ont eux aussi leur poids non négligeable dans l'affaire.

My 2 cents inutiles: la taille des urls va être mécaniquement réduite de quelques octets avec la ZEP-12, disparation du pk oblige (oui, ça marche).

pierre_24

C'est possible, mais même en réduisant de 10 ou 20 Ko l'unité de stockage, les chiffres restent tout de même délirants.

Je trouve ça très étrange quand même qu'on arrive à 1Go pour à peine 50K entrées par jour. Sur un mois d'extraction de données assez complètes sur des volumes de 300 000 et 550 000 entrées par jour, avec trois tables de réplications (précalculs, réorganisation) et des index fulltext sur deux champs, je n'ai que 2Go de pris sur 1 mois entier. On est très loin d'un besoin de 400Go.

(Nota : j'utilise MySQL, les logs à partir desquels sont générés la BDD font en moyenne 50Mo à 65Mo)

artragis

Je suis intéressé par le détails de cette analyse. Tu stocke des données brutes ou des données déjà calculées ?

principalement des données brutes. Puis je recrée des tables avec des précalculs.

Certaines tables contiennent donc des données assez lourdes.

Notons aussi que pour un soucis de taille il est tout à fait possible de stocker les dates sous forme d'entier plutôt que de chaînes de caractères.

principalement des données brutes. Puis je recrée des tables avec des précalculs.

artragis

Donc on est d'accord que si tu veux tracer une courbe du nombre de visite sur une page entre le 01 janvier et le 01 février par exemple, tu dois aller taper dans tes données brutes qui constituent ton historique ?

Notre problème c'est que les donnée brutes, on ne les a pas avec l'API de Google Analytics.

Voici mon modèle :

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
-- MySQL dump 10.13  Distrib 5.6.19, for debian-linux-gnu (x86_64)
--
-- Host: localhost    Database: rd_fbl_something
-- ------------------------------------------------------
-- Server version 5.6.19-0ubuntu0.14.04.1

/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
/*!40101 SET NAMES utf8 */;
/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */;
/*!40103 SET TIME_ZONE='+00:00' */;
/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;

--
-- Table structure for table `BANNED_IP`
--

DROP TABLE IF EXISTS `BANNED_IP`;
/*!40101 SET @saved_cs_client     = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `BANNED_IP` (
  `IP` char(16) NOT NULL DEFAULT '127.0.0.1',
  UNIQUE KEY `uniq_ip` (`IP`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
/*!40101 SET character_set_client = @saved_cs_client */;

--
-- Table structure for table `COMPLAINTS`
--

DROP TABLE IF EXISTS `COMPLAINTS`;
/*!40101 SET @saved_cs_client     = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `COMPLAINTS` (
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `FBL` char(7) NOT NULL DEFAULT 'something',
  `RECEPTION_DATE` bigint(20) NOT NULL DEFAULT '0',
  `COMPLAINT_DATE` bigint(20) NOT NULL DEFAULT '0',
  `SUBJECT_HEADER` char(255) NOT NULL DEFAULT '',
  `FROM_HEADER` char(255) NOT NULL DEFAULT '',
  `IP` char(16) NOT NULL DEFAULT '127.0.0.1',
  PRIMARY KEY (`id`)
) ENGINE=MyISAM AUTO_INCREMENT=7729749 DEFAULT CHARSET=latin1;
/*!40101 SET character_set_client = @saved_cs_client */;

--
-- Table structure for table `stat_something_per_day`
--

DROP TABLE IF EXISTS `stat_something_per_day`;
/*!40101 SET @saved_cs_client     = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `stat_something_per_day` (
  `jour` int(2) DEFAULT NULL,
  `nb_mail` bigint(21) NOT NULL DEFAULT '0',
  `temps_moy` decimal(24,4) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
/*!40101 SET character_set_client = @saved_cs_client */;

--
-- Table structure for table `stat_per_day`
--

DROP TABLE IF EXISTS `stat_per_day`;
/*!40101 SET @saved_cs_client     = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `stat_per_day` (
  `mois` int(2) DEFAULT NULL,
  `jour` int(2) DEFAULT NULL,
  `nb_mail` bigint(21) NOT NULL DEFAULT '0',
  `temps_moy` decimal(24,4) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
/*!40101 SET character_set_client = @saved_cs_client */;

--
-- Table structure for table `stat_sfr_per_day`
--

DROP TABLE IF EXISTS `stat_sfr_per_day`;
/*!40101 SET @saved_cs_client     = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `stat_sfr_per_day` (
  `jour` int(2) DEFAULT NULL,
  `nb_mail` bigint(21) NOT NULL DEFAULT '0',
  `temps_moy` decimal(24,4) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
/*!40101 SET character_set_client = @saved_cs_client */;

--
-- Table structure for table `vague_elements`
--

DROP TABLE IF EXISTS `vague_elements`;
/*!40101 SET @saved_cs_client     = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `vague_elements` (
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `int_5_min` int(11) NOT NULL,
  `int_5_min_rec` int(11) NOT NULL,
  `reception_date` int(11) NOT NULL,
  `complaint_date` int(11) NOT NULL,
  `jour` int(2) NOT NULL,
  `heure` int(2) NOT NULL,
  `subject` char(255) NOT NULL,
  `ip` char(15) NOT NULL,
  `from_header` char(128) NOT NULL,
  PRIMARY KEY (`id`),
  KEY `vague_header` (`from_header`(50)),
  KEY `vague_ip` (`ip`),
  KEY `vague_subject` (`subject`(20))
) ENGINE=MyISAM AUTO_INCREMENT=5268756 DEFAULT CHARSET=latin1;
/*!40101 SET character_set_client = @saved_cs_client */;

--
-- Table structure for table `vague_elements_something`
--

DROP TABLE IF EXISTS `vague_elements_something`;
/*!40101 SET @saved_cs_client     = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `vague_elements_something` (
  `id` int(10) unsigned NOT NULL DEFAULT '0',
  `int_5_min` decimal(16,0) DEFAULT NULL,
  `int_5_min_rec` decimal(16,0) DEFAULT NULL,
  `reception_date` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  `complaint_date` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
  `jour` int(2) DEFAULT NULL,
  `heure` int(2) DEFAULT NULL,
  `subject` varchar(255) DEFAULT NULL,
  `ip` char(40) DEFAULT NULL,
  `from_header` varchar(255) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
/*!40101 SET character_set_client = @saved_cs_client */;

--
-- Table structure for table `vague_per_subject`
--

DROP TABLE IF EXISTS `vague_per_subject`;
/*!40101 SET @saved_cs_client     = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `vague_per_subject` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `subject` char(255) NOT NULL,
  `volume_vague` int(11) NOT NULL,
  `min_rec_time` bigint(20) NOT NULL,
  `max_rec_time` bigint(20) NOT NULL,
  `min_comp_time` bigint(20) NOT NULL,
  `max_comp_time` bigint(20) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=MyISAM AUTO_INCREMENT=971 DEFAULT CHARSET=latin1;
/*!40101 SET character_set_client = @saved_cs_client */;

--
-- Temporary view structure for view `week_stats`
--

DROP TABLE IF EXISTS `week_stats`;
/*!50001 DROP VIEW IF EXISTS `week_stats`*/;
SET @saved_cs_client     = @@character_set_client;
SET character_set_client = utf8;
/*!50001 CREATE VIEW `week_stats` AS SELECT 
 1 AS `id`,
 1 AS `difference`,
 1 AS `heure`,
 1 AS `jour`,
 1 AS `complain_date`*/;
SET character_set_client = @saved_cs_client;

--
-- Final view structure for view `week_stats`
--

/*!50001 DROP VIEW IF EXISTS `week_stats`*/;
/*!50001 SET @saved_cs_client          = @@character_set_client */;
/*!50001 SET @saved_cs_results         = @@character_set_results */;
/*!50001 SET @saved_col_connection     = @@collation_connection */;
/*!50001 SET character_set_client      = utf8 */;
/*!50001 SET character_set_results     = utf8 */;
/*!50001 SET collation_connection      = utf8_general_ci */;
/*!50001 CREATE ALGORITHM=UNDEFINED */
/*!50013 DEFINER=`root`@`localhost` SQL SECURITY DEFINER */
/*!50001 VIEW `week_stats` AS select `COMPLAINTS`.`id` AS `id`,abs((`COMPLAINTS`.`RECEPTION_DATE` - `COMPLAINTS`.`COMPLAINT_DATE`)) AS `difference`,hour(from_unixtime(`COMPLAINTS`.`COMPLAINT_DATE`)) AS `heure`,dayofmonth(from_unixtime(`COMPLAINTS`.`COMPLAINT_DATE`)) AS `jour`,from_unixtime(`COMPLAINTS`.`COMPLAINT_DATE`) AS `complain_date` from `COMPLAINTS` where ((not(`COMPLAINTS`.`IP` in (select `BANNED_IP`.`IP` from `BANNED_IP`))) and (`COMPLAINTS`.`COMPLAINT_DATE` >= '2015-03-10') and (`COMPLAINTS`.`COMPLAINT_DATE` >= `COMPLAINTS`.`RECEPTION_DATE`)) */;
/*!50001 SET character_set_client      = @saved_cs_client */;
/*!50001 SET character_set_results     = @saved_cs_results */;
/*!50001 SET collation_connection      = @saved_col_connection */;
/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;

/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;
/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;

-- Dump completed on 2015-04-23 14:57:06

Si on regarde les fichiers de données mysql sur cette bdd là (5 800 000 entrées dans COMPLAINTS) :

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
-rw-rw---- 1 mysql mysql       8556 avril 21 09:55 BANNED_IP.frm
-rw-rw---- 1 mysql mysql      98304 avril 21 09:55 BANNED_IP.ibd
-rw-rw---- 1 mysql mysql       8804 avril  9 11:44 COMPLAINTS.frm
-rw-rw---- 1 mysql mysql 2924578742 avril 21 09:54 COMPLAINTS.MYD
-rw-rw---- 1 mysql mysql   54177792 avril 21 17:36 COMPLAINTS.MYI
-rw-rw---- 1 mysql mysql         65 mars  26 14:44 db.opt
-rw-rw---- 1 mysql mysql       8666 avril 21 10:10 stat_per_day.frm
-rw-rw---- 1 mysql mysql      98304 avril 21 10:10 stat_per_day.ibd
-rw-rw---- 1 mysql mysql       8912 avril 21 10:04 vague_elements.frm
-rw-rw---- 1 mysql mysql 2249758385 avril 21 10:07 vague_elements.MYD
-rw-rw---- 1 mysql mysql  187602944 avril 21 10:10 vague_elements.MYI
-rw-rw---- 1 mysql mysql       8912 mars  26 15:35 vague_elements_something.frm
-rw-rw---- 1 mysql mysql  146800640 mars  26 15:36 vague_elements_something.ibd
-rw-rw---- 1 mysql mysql       8826 avril 21 10:10 vague_per_subject.frm
-rw-rw---- 1 mysql mysql     287120 avril 21 10:17 vague_per_subject.MYD
-rw-rw---- 1 mysql mysql      12288 avril 21 17:36 vague_per_subject.MYI
-rw-rw---- 1 mysql mysql       2175 avril 21 09:54 week_stats.frm

@artragis : C'est bien ce que je pensais. Dans ton modèle de données, tu as des informations brutes que l'on a pas avec Google Analytics.

Pour te donner une idée, si on devait se contenter d'analyser ce que l'on a dans nos logs, voici ce qu'on devrait stocker en gros :

id IP timestamp temps de réponse serveur url demandée url source user agent
1 127.0.0.1 200 /tutoriel/blabla /twitter.com/firm1/

ça ne couterait pas grand chose en stockage. C'est a peu de chose près le même modèle que le tiens, et donc on en revient au problème de base. Google Analytics ne ne permet pas d'avoir des informations aussi fines.

Pour essayer de faire avancer les choses, étant donné que notre problème de volumétrie provient des données multidimensionnelles fournies par Google Analytics. Est-ce que ça ne serait pas possible de changer de provider en se contentant de stocker (après filtrage) le contenu des logs ?

Néanmoins il faut être conscient que cette piste, nous privera des métriques suivantes (parmi les 10 énoncées dans le premier post) :

Proposition Description Total "Oui" Total "Non" Total "Pourquoi pas"
2 Le temps moyen passé sur le tuto. 14 3 0
8 Le type d'audience (fourchette d'age, sexe) que mon tutoriel attire 10 3 3
10 Les mots clés qui permettent d'arriver sur mon tutoriel depuis un moteur de recherche 14 2 1

Notons qu'étant donné qu'on fait des stats sur le contenu, on ne va pas stocker toutes les logs mais uniquement celles de type contenu (article, tutoriel, chapitres, etc.).

Du coup, est-ce que ça vaut le coup que je fasse un chiffrage avec cette piste ?

Il existe pas des outils tout fait pour mesurer et stocker ce genre de chose ?

Kje

Si tu parles de gérer les 3 métriques restantes (mentionnées dans mon post), alors la réponse est celle de Coyote, on ne peut le faire qu'avec des Tracker en JS et le stockage des données doit être sur nos serveurs.

Si tu parles de stocker tout ce qu'on veut stocker depuis le début, il existe 2 types de systèmes :

  • Les analyseurs de logs
  • Les trackers JS

Dans les 2 catégories des outils existent, mais il faut de toute façon les intégrer à ZdS (API, parsing d'url, etc.)

Du coup, tu pourrais préciser la question ?

Ma question était si il existait pas un outils qui s'occupe de tout ça pour nous et où on aurait qu'à présenter les données sur ZDS et laisser le soin à cet outils de gérer le stockage et la collecte des données.

Kje

Un outil qui fait tout ça gratuitement ? Non ça n'existe pas :)

Mais de toute façon l'approche pas l'outil n'est jamais une bonne chose. Il faut d'abord savoir ce que l'on veut avant d'aller chercher l'outil qu'il nous faut et pas l'inverse.

Il faut d'abord savoir ce que l'on veut avant d'aller chercher l'outil qu'il nous faut et pas l'inverse.

Bah justement, on vient de passer 10 pages pour savoir ce que l'on veut. C'est pour ça que maintenant définit, je demande si il y a pas un outils qui fait ça. Ça me semble un besoin tellement classique que je m’étonne que ça n'existe pas. Je suis rarement un grand fan de devoir manager un outils séparé mais si ça peut nous éviter de devoir parser des logs ou gérer une base de 200Go, je préfèrerai

Un truc tout fait qui corresponde à ce que l'on veut n'existe malheureusement pas (en tout ce n'est pas gratuit). On ne pourra pas échapper au stockage des informations.

D’où la proposition d'analyse de log (sachant qu'il existent des outils qui font le parsing très bien ) vraiment pas couteuse en espace de stockage (on serait dans les 5Go par an).

ça vaut quand même le coup d'avoir les 7 autres métriques, que de ne rien avoir non ?

Je ne sais pas si j'ai bien compris, mais pourquoi ne pas faire un mix log/GA où on prendrait stockerai dans une BDD seulement les 3 métriques qu'on ne peux pas avoir avec les logs ?

Bat'

On pourrait envisager ce cas là, mais ça commence a devenir techniquement complexe de gérer et synchroniser 2 provider en entrée dont la forme des données est différente (l'un fournit des données brutes, l'autre fournit des données calculées).

Je serais d'avis dans une première version de la ZEP de partir sur un fournisseur de donnée au départ, et de rajouter éventuellement un second dans une deuxième phase.

Connectez-vous pour pouvoir poster un message.
Connexion

Pas encore membre ?

Créez un compte en une minute pour profiter pleinement de toutes les fonctionnalités de Zeste de Savoir. Ici, tout est gratuit et sans publicité.
Créer un compte